llvm.org GIT mirror llvm / 36ecb2e
Re-commit r208025, reverted in r208030, with a fix for a conformance issue which GCC detects and Clang does not! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208033 91177308-0d34-0410-b5e6-96231b3b80d8 Richard Smith 6 years ago
9 changed file(s) with 228 addition(s) and 47 deletion(s). Raw diff Collapse all Expand all
107107 * Lambdas: N2927_
108108
109109 * But *not* ``std::function``, until Clang implements `MSVC-compatible RTTI`_.
110 In many cases, you may be able to use ``llvm::function_ref`` instead, and it
111 is a superior choice in those cases.
110112 * And *not* lambdas with default arguments.
111113
112114 * ``decltype``: N2343_
261261 almost never be stored or mentioned directly. They are intended solely for use
262262 when defining a function which should be able to efficiently accept concatenated
263263 strings.
264
265 .. _function_apis:
266
267 Passing functions and other callable objects
268 --------------------------------------------
269
270 Sometimes you may want a function to be passed a callback object. In order to
271 support lambda expressions and other function objects, you should not use the
272 traditional C approach of taking a function pointer and an opaque cookie:
273
274 .. code-block:: c++
275
276 void takeCallback(bool (*Callback)(Function *, void *), void *Cookie);
277
278 Instead, use one of the following approaches:
279
280 Function template
281 ^^^^^^^^^^^^^^^^^
282
283 If you don't mind putting the definition of your function into a header file,
284 make it a function template that is templated on the callable type.
285
286 .. code-block:: c++
287
288 template
289 void takeCallback(Callable Callback) {
290 Callback(1, 2, 3);
291 }
292
293 The ``function_ref`` class template
294 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
295
296 The ``function_ref``
297 (`doxygen `__) class
298 template represents a reference to a callable object, templated over the type
299 of the callable. This is a good choice for passing a callback to a function,
300 if you don't need to hold onto the callback after the function returns.
301
302 ``function_ref`` can be implicitly constructed from
303 any callable object that can be called with arguments of type ``Param1``,
304 ``Param2``, ..., and returns a value that can be converted to type ``Ret``.
305 For example:
306
307 .. code-block:: c++
308
309 void visitBasicBlocks(Function *F, function_ref Callback) {
310 for (BasicBlock &BB : *F)
311 if (Callback(&BB))
312 return;
313 }
314
315 can be called using:
316
317 .. code-block:: c++
318
319 visitBasicBlocks(F, [&](BasicBlock *BB) {
320 if (process(BB))
321 return isEmpty(BB);
322 return false;
323 });
324
325 Note that a ``function_ref`` object contains pointers to external memory, so
326 it is not generally safe to store an instance of the class (unless you know
327 that the external storage will not be freed).
328 ``function_ref`` is small enough that it should always be passed by value.
329
330 ``std::function``
331 ^^^^^^^^^^^^^^^^^
332
333 You cannot use ``std::function`` within LLVM code, because it is not supported
334 by all our target toolchains.
335
264336
265337 .. _DEBUG:
266338
5353 return *right < *left;
5454 }
5555 };
56
57 /// An efficient, type-erasing, non-owning reference to a callable. This is
58 /// intended for use as the type of a function parameter that is not used
59 /// after the function in question returns.
60 ///
61 /// This class does not own the callable, so it is not in general safe to store
62 /// a function_ref.
63 template class function_ref;
64
65 #if LLVM_HAS_VARIADIC_TEMPLATES
66
67 template
68 class function_ref {
69 Ret (*callback)(void *callable, Params ...params);
70 void *callable;
71
72 template
73 static Ret callback_fn(void *callable, Params ...params) {
74 return (*reinterpret_cast(callable))(
75 std::forward(params)...);
76 }
77
78 public:
79 template
80 function_ref(Callable &&callable)
81 : callback(callback_fn::type>),
82 callable(reinterpret_cast(&callable)) {}
83 Ret operator()(Params ...params) const {
84 return callback(callable, std::forward(params)...);
85 }
86 };
87
88 #else
89
90 template
91 class function_ref {
92 Ret (*callback)(void *callable);
93 void *callable;
94
95 template
96 static Ret callback_fn(void *callable) {
97 return (*reinterpret_cast(callable))();
98 }
99
100 public:
101 template
102 function_ref(Callable &&callable)
103 : callback(callback_fn::type>),
104 callable(reinterpret_cast(&callable)) {}
105 Ret operator()() const { return callback(callable); }
106 };
107
108 template
109 class function_ref {
110 Ret (*callback)(void *callable, Param1 param1);
111 void *callable;
112
113 template
114 static Ret callback_fn(void *callable, Param1 param1) {
115 return (*reinterpret_cast(callable))(
116 std::forward(param1));
117 }
118
119 public:
120 template
121 function_ref(Callable &&callable)
122 : callback(callback_fn::type>),
123 callable(reinterpret_cast(&callable)) {}
124 Ret operator()(Param1 param1) {
125 return callback(callable, std::forward(param1));
126 }
127 };
128
129 template
130 class function_ref {
131 Ret (*callback)(void *callable, Param1 param1, Param2 param2);
132 void *callable;
133
134 template
135 static Ret callback_fn(void *callable, Param1 param1, Param2 param2) {
136 return (*reinterpret_cast(callable))(
137 std::forward(param1),
138 std::forward(param2));
139 }
140
141 public:
142 template
143 function_ref(Callable &&callable)
144 : callback(callback_fn::type>),
145 callable(reinterpret_cast(&callable)) {}
146 Ret operator()(Param1 param1, Param2 param2) {
147 return callback(callable,
148 std::forward(param1),
149 std::forward(param2));
150 }
151 };
152
153 template
154 class function_ref {
155 Ret (*callback)(void *callable, Param1 param1, Param2 param2, Param3 param3);
156 void *callable;
157
158 template
159 static Ret callback_fn(void *callable, Param1 param1, Param2 param2,
160 Param3 param3) {
161 return (*reinterpret_cast(callable))(
162 std::forward(param1),
163 std::forward(param2),
164 std::forward(param3));
165 }
166
167 public:
168 template
169 function_ref(Callable &&callable)
170 : callback(callback_fn::type>),
171 callable(reinterpret_cast(&callable)) {}
172 Ret operator()(Param1 param1, Param2 param2, Param3 param3) {
173 return callback(callable,
174 std::forward(param1),
175 std::forward(param2),
176 std::forward(param3));
177 }
178 };
179
180 #endif
56181
57182 // deleter - Very very very simple method that is used to invoke operator
58183 // delete on something. It is used like this:
1111
1212 #include
1313
14 #include "llvm/ADT/STLExtras.h"
15
1416 namespace llvm {
1517 class StringRef;
1618
1719 class CrashRecoveryContextCleanup;
18
20
1921 /// \brief Crash recovery helper object.
2022 ///
2123 /// This class implements support for running operations in a safe context so
4547 void *Impl;
4648 CrashRecoveryContextCleanup *head;
4749
48 /// An adaptor to convert an arbitrary functor into a void(void*), void* pair.
49 template struct FunctorAdaptor {
50 T Fn;
51 static void invoke(void *Data) {
52 return static_cast*>(Data)->Fn();
53 }
54 typedef void Callback(void*);
55 Callback *fn() { return &invoke; }
56 void *arg() { return this; }
57 };
58
5950 public:
6051 CrashRecoveryContext() : Impl(nullptr), head(nullptr) {}
6152 ~CrashRecoveryContext();
62
53
6354 void registerCleanup(CrashRecoveryContextCleanup *cleanup);
6455 void unregisterCleanup(CrashRecoveryContextCleanup *cleanup);
6556
8576 /// make as little assumptions as possible about the program state when
8677 /// RunSafely has returned false. Clients can use getBacktrace() to retrieve
8778 /// the backtrace of the crash on failures.
88 bool RunSafely(void (*Fn)(void*), void *UserData);
89 template
90 bool RunSafely(Functor Fn) {
91 FunctorAdaptor Adaptor = { Fn };
92 return RunSafely(Adaptor.fn(), Adaptor.arg());
79 bool RunSafely(function_ref Fn);
80 bool RunSafely(void (*Fn)(void*), void *UserData) {
81 return RunSafely([&]() { Fn(UserData); });
9382 }
9483
9584 /// \brief Execute the provide callback function (with the given arguments) in
9786 /// requested stack size).
9887 ///
9988 /// See RunSafely() and llvm_execute_on_thread().
89 bool RunSafelyOnThread(function_ref, unsigned RequestedStackSize = 0);
10090 bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
101 unsigned RequestedStackSize = 0);
102 template
103 bool RunSafelyOnThread(Functor Fn, unsigned RequestedStackSize = 0) {
104 FunctorAdaptor Adaptor = { Fn };
105 return RunSafelyOnThread(Adaptor.fn(), Adaptor.arg(), RequestedStackSize);
91 unsigned RequestedStackSize = 0) {
92 return RunSafelyOnThread([&]() { Fn(UserData); }, RequestedStackSize);
10693 }
10794
10895 /// \brief Explicitly trigger a crash recovery in the current process, and
1313 #ifndef LLVM_TRANSFORMS_UTILS_CTOR_UTILS_H
1414 #define LLVM_TRANSFORMS_UTILS_CTOR_UTILS_H
1515
16 #include
17 #include
16 #include "llvm/ADT/STLExtras.h"
1817
1918 namespace llvm {
2019
2221 class Function;
2322 class Module;
2423
25 typedef bool (*ShouldRemoveCtor)(void *, Function *);
26
2724 /// Call "ShouldRemove" for every entry in M's global_ctor list and remove the
2825 /// entries for which it returns true. Return true if anything changed.
29 bool optimizeGlobalCtorsList(Module &M, ShouldRemoveCtor ShouldRemove,
30 void *Context);
26 bool optimizeGlobalCtorsList(Module &M,
27 function_ref ShouldRemove);
3128
3229 } // End llvm namespace
3330
300300
301301 #endif
302302
303 bool CrashRecoveryContext::RunSafely(void (*Fn)(void*), void *UserData) {
303 bool CrashRecoveryContext::RunSafely(function_ref Fn) {
304304 // If crash recovery is disabled, do nothing.
305305 if (gCrashRecoveryEnabled) {
306306 assert(!Impl && "Crash recovery context already initialized!");
312312 }
313313 }
314314
315 Fn(UserData);
315 Fn();
316316 return true;
317317 }
318318
333333
334334 namespace {
335335 struct RunSafelyOnThreadInfo {
336 void (*Fn)(void*);
337 void *Data;
336 function_ref Fn;
338337 CrashRecoveryContext *CRC;
339338 bool Result;
340339 };
343342 static void RunSafelyOnThread_Dispatch(void *UserData) {
344343 RunSafelyOnThreadInfo *Info =
345344 reinterpret_cast(UserData);
346 Info->Result = Info->CRC->RunSafely(Info->Fn, Info->Data);
347 }
348 bool CrashRecoveryContext::RunSafelyOnThread(void (*Fn)(void*), void *UserData,
345 Info->Result = Info->CRC->RunSafely(Info->Fn);
346 }
347 bool CrashRecoveryContext::RunSafelyOnThread(function_ref Fn,
349348 unsigned RequestedStackSize) {
350 RunSafelyOnThreadInfo Info = { Fn, UserData, this, false };
349 RunSafelyOnThreadInfo Info = { Fn, this, false };
351350 llvm_execute_on_thread(RunSafelyOnThread_Dispatch, &Info, RequestedStackSize);
352351 if (CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *)Impl)
353352 CRC->setSwitchedThread();
5353
5454 bool RemoveUnusedGlobalValue(GlobalValue &GV);
5555 };
56 }
5657
5758 /// Returns true if F contains only a single "ret" instruction.
58 bool isEmptyFunction(void *Context, Function *F) {
59 static bool isEmptyFunction(Function *F) {
5960 BasicBlock &Entry = F->getEntryBlock();
6061 if (Entry.size() != 1 || !isa(Entry.front()))
6162 return false;
6263 ReturnInst &RI = cast(Entry.front());
6364 return RI.getReturnValue() == NULL;
6465 }
65 }
6666
6767 char GlobalDCE::ID = 0;
6868 INITIALIZE_PASS(GlobalDCE, "globaldce",
7474 bool Changed = false;
7575
7676 // Remove empty functions from the global ctors list.
77 Changed |= optimizeGlobalCtorsList(M, isEmptyFunction, nullptr);
77 Changed |= optimizeGlobalCtorsList(M, isEmptyFunction);
7878
7979 // Loop over the module, adding globals which are obviously necessary.
8080 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
30213021 LocalChange |= OptimizeFunctions(M);
30223022
30233023 // Optimize global_ctors list.
3024 LocalChange |= optimizeGlobalCtorsList(M, [](void *C, Function *F) -> bool {
3025 GlobalOpt *self = static_cast(C);
3026 return EvaluateStaticConstructor(F, self->DL, self->TLI);
3027 }, this);
3024 LocalChange |= optimizeGlobalCtorsList(M, [&](Function *F) {
3025 return EvaluateStaticConstructor(F, DL, TLI);
3026 });
30283027
30293028 // Optimize non-address-taken globals.
30303029 LocalChange |= OptimizeGlobalVars(M);
131131
132132 /// Call "ShouldRemove" for every entry in M's global_ctor list and remove the
133133 /// entries for which it returns true. Return true if anything changed.
134 bool optimizeGlobalCtorsList(Module &M, ShouldRemoveCtor ShouldRemove,
135 void *Context) {
134 bool optimizeGlobalCtorsList(Module &M,
135 function_ref ShouldRemove) {
136136 GlobalVariable *GlobalCtors = findGlobalCtors(M);
137137 if (!GlobalCtors)
138138 return false;
162162 continue;
163163
164164 // If we can evaluate the ctor at compile time, do.
165 if (ShouldRemove(Context, F)) {
165 if (ShouldRemove(F)) {
166166 Ctors.erase(Ctors.begin() + i);
167167 MadeChange = true;
168168 --i;