[llvm] r208025 - Add llvm::function_ref (and a couple of uses of it), representing a type-erased reference to a callable object.
Richard Smith
richard at metafoo.co.uk
Mon May 5 18:50:55 PDT 2014
On Mon, May 5, 2014 at 6:37 PM, Kevin Qin <kevinqindev at gmail.com> wrote:
> This commit make trunk broken. Please have a look.
>
This was already reverted. =)
> In file included from
> /home/kevin/llvm_trunk/llvm/include/llvm/Support/CrashRecoveryContext.h:15:0,
> from
> /home/kevin/llvm_trunk/llvm/lib/Support/CrashRecoveryContext.cpp:10:
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h: In instantiation
> of ‘static Ret llvm::function_ref<Ret()>::callback_fn(void*) [with Callable
> = llvm::CrashRecoveryContext::RunSafely(void (*)(void*), void*)::__lambda0;
> Ret = void]’:
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h:105:53:
> required from ‘llvm::function_ref<Ret()>::function_ref(Callable&&) [with
> Callable = llvm::CrashRecoveryContext::RunSafely(void (*)(void*),
> void*)::__lambda0; Ret = void]’
> /home/kevin/llvm_trunk/llvm/include/llvm/Support/CrashRecoveryContext.h:82:45:
> required from here
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h:98:51: error:
> ‘void*’ is not a pointer-to-object type
> return reinterpret_cast<Callable&>(*callable)();
> ^
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h:98:51: error:
> return-statement with a value, in function returning 'void' [-fpermissive]
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h: In instantiation
> of ‘static Ret llvm::function_ref<Ret()>::callback_fn(void*) [with Callable
> = llvm::CrashRecoveryContext::RunSafelyOnThread(void (*)(void*), void*,
> unsigned int)::__lambda1; Ret = void]’:
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h:105:53:
> required from ‘llvm::function_ref<Ret()>::function_ref(Callable&&) [with
> Callable = llvm::CrashRecoveryContext::RunSafelyOnThread(void (*)(void*),
> void*, unsigned int)::__lambda1; Ret = void]’
> /home/kevin/llvm_trunk/llvm/include/llvm/Support/CrashRecoveryContext.h:93:73:
> required from here
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h:98:51: error:
> ‘void*’ is not a pointer-to-object type
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h:98:51: error:
> return-statement with a value, in function returning 'void' [-fpermissive]
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h: In instantiation
> of ‘static Ret llvm::function_ref<Ret()>::callback_fn(void*) [with Callable
> = llvm::function_ref<void()>&; Ret = void]’:
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h:105:53:
> required from ‘llvm::function_ref<Ret()>::function_ref(Callable&&) [with
> Callable = llvm::function_ref<void()>&; Ret = void]’
> /home/kevin/llvm_trunk/llvm/lib/Support/CrashRecoveryContext.cpp:346:47:
> required from here
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h:98:51: error:
> ‘void*’ is not a pointer-to-object type
> /home/kevin/llvm_trunk/llvm/include/llvm/ADT/STLExtras.h:98:51: error:
> return-statement with a value, in function returning 'void' [-fpermissive]
> make[2]: ***
> [lib/Support/CMakeFiles/LLVMSupport.dir/CrashRecoveryContext.cpp.o] Error 1
> make[1]: *** [lib/Support/CMakeFiles/LLVMSupport.dir/all] Error 2
>
>
>
> 2014-05-06 9:01 GMT+08:00 Richard Smith <richard-llvm at metafoo.co.uk>:
>
> Author: rsmith
>> Date: Mon May 5 20:01:29 2014
>> New Revision: 208025
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=208025&view=rev
>> Log:
>> Add llvm::function_ref (and a couple of uses of it), representing a
>> type-erased reference to a callable object.
>>
>> Modified:
>> llvm/trunk/include/llvm/ADT/STLExtras.h
>> llvm/trunk/include/llvm/Support/CrashRecoveryContext.h
>> llvm/trunk/include/llvm/Transforms/Utils/CtorUtils.h
>> llvm/trunk/lib/Support/CrashRecoveryContext.cpp
>> llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp
>> llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
>> llvm/trunk/lib/Transforms/Utils/CtorUtils.cpp
>>
>> Modified: llvm/trunk/include/llvm/ADT/STLExtras.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=208025&r1=208024&r2=208025&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ADT/STLExtras.h (original)
>> +++ llvm/trunk/include/llvm/ADT/STLExtras.h Mon May 5 20:01:29 2014
>> @@ -55,6 +55,131 @@ struct greater_ptr : public std::binary_
>> }
>> };
>>
>> +/// An efficient, type-erasing, non-owning reference to a callable. This
>> is
>> +/// intended for use as the type of a function parameter that is not used
>> +/// after the function in question returns.
>> +///
>> +/// This class does not own the callable, so it is not in general safe
>> to store
>> +/// a function_ref.
>> +template<typename Fn> class function_ref;
>> +
>> +#if LLVM_HAS_VARIADIC_TEMPLATES
>> +
>> +template<typename Ret, typename ...Params>
>> +class function_ref<Ret(Params...)> {
>> + Ret (*callback)(void *callable, Params ...params);
>> + void *callable;
>> +
>> + template<typename Callable>
>> + static Ret callback_fn(void *callable, Params ...params) {
>> + return reinterpret_cast<Callable&>(*callable)(
>> + std::forward<Params>(params)...);
>> + }
>> +
>> +public:
>> + template<typename Callable>
>> + function_ref(Callable &&callable)
>> + : callback(callback_fn<Callable>),
>> + callable(reinterpret_cast<void *>(&callable)) {}
>> + Ret operator()(Params ...params) const {
>> + return callback(callable, std::forward<Params>(params)...);
>> + }
>> +};
>> +
>> +#else
>> +
>> +template<typename Ret>
>> +class function_ref<Ret()> {
>> + Ret (*callback)(void *callable);
>> + void *callable;
>> +
>> + template<typename Callable>
>> + static Ret callback_fn(void *callable) {
>> + return reinterpret_cast<Callable&>(*callable)();
>> + }
>> +
>> +public:
>> + template<typename Callable>
>> + function_ref(Callable &&callable)
>> + : callback(callback_fn<Callable>),
>> + callable(reinterpret_cast<void *>(&callable)) {}
>> + Ret operator()() const { return callback(callable); }
>> +};
>> +
>> +template<typename Ret, typename Param1>
>> +class function_ref<Ret(Param1)> {
>> + Ret (*callback)(void *callable, Param1 param1);
>> + void *callable;
>> +
>> + template<typename Callable>
>> + static Ret callback_fn(void *callable, Param1 param1) {
>> + return reinterpret_cast<Callable&>(*callable)(
>> + std::forward<Param1>(param1));
>> + }
>> +
>> +public:
>> + template<typename Callable>
>> + function_ref(Callable &&callable)
>> + : callback(callback_fn<Callable>),
>> + callable(reinterpret_cast<void *>(&callable)) {}
>> + Ret operator()(Param1 param1) {
>> + return callback(callable, std::forward<Param1>(param1));
>> + }
>> +};
>> +
>> +template<typename Ret, typename Param1, typename Param2>
>> +class function_ref<Ret(Param1, Param2)> {
>> + Ret (*callback)(void *callable, Param1 param1, Param2 param2);
>> + void *callable;
>> +
>> + template<typename Callable>
>> + static Ret callback_fn(void *callable, Param1 param1, Param2 param2) {
>> + return reinterpret_cast<Callable&>(*callable)(
>> + std::forward<Param1>(param1),
>> + std::forward<Param2>(param2));
>> + }
>> +
>> +public:
>> + template<typename Callable>
>> + function_ref(Callable &&callable)
>> + : callback(callback_fn<Callable>),
>> + callable(reinterpret_cast<void *>(&callable)) {}
>> + Ret operator()(Param1 param1, Param2 param2) {
>> + return callback(callable,
>> + std::forward<Param1>(param1),
>> + std::forward<Param2>(param2));
>> + }
>> +};
>> +
>> +template<typename Ret, typename Param1, typename Param2, typename Param3>
>> +class function_ref<Ret(Param1, Param2, Param3)> {
>> + Ret (*callback)(void *callable, Param1 param1, Param2 param2, Param3
>> param3);
>> + void *callable;
>> +
>> + template<typename Callable>
>> + static Ret callback_fn(void *callable, Param1 param1, Param2 param2,
>> + Param3 param3) {
>> + return reinterpret_cast<Callable&>(*callable)(
>> + std::forward<Param1>(param1),
>> + std::forward<Param2>(param2),
>> + std::forward<Param3>(param3));
>> + }
>> +
>> +public:
>> + template<typename Callable>
>> + function_ref(Callable &&callable)
>> + : callback(callback_fn<Callable>),
>> + callable(reinterpret_cast<void *>(&callable)) {}
>> + Ret operator()(Param1 param1, Param2 param2, Param3 param3) {
>> + return callback(callable,
>> + std::forward<Param1>(param1),
>> + std::forward<Param2>(param2),
>> + std::forward<Param3>(param3));
>> + }
>> +};
>> +
>> +#endif
>> +
>> // deleter - Very very very simple method that is used to invoke operator
>> // delete on something. It is used like this:
>> //
>>
>> Modified: llvm/trunk/include/llvm/Support/CrashRecoveryContext.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CrashRecoveryContext.h?rev=208025&r1=208024&r2=208025&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Support/CrashRecoveryContext.h (original)
>> +++ llvm/trunk/include/llvm/Support/CrashRecoveryContext.h Mon May 5
>> 20:01:29 2014
>> @@ -12,11 +12,13 @@
>>
>> #include <string>
>>
>> +#include "llvm/ADT/STLExtras.h"
>> +
>> namespace llvm {
>> class StringRef;
>>
>> class CrashRecoveryContextCleanup;
>> -
>> +
>> /// \brief Crash recovery helper object.
>> ///
>> /// This class implements support for running operations in a safe
>> context so
>> @@ -46,21 +48,10 @@ class CrashRecoveryContext {
>> void *Impl;
>> CrashRecoveryContextCleanup *head;
>>
>> - /// An adaptor to convert an arbitrary functor into a void(void*),
>> void* pair.
>> - template<typename T> struct FunctorAdaptor {
>> - T Fn;
>> - static void invoke(void *Data) {
>> - return static_cast<FunctorAdaptor<T>*>(Data)->Fn();
>> - }
>> - typedef void Callback(void*);
>> - Callback *fn() { return &invoke; }
>> - void *arg() { return this; }
>> - };
>> -
>> public:
>> CrashRecoveryContext() : Impl(nullptr), head(nullptr) {}
>> ~CrashRecoveryContext();
>> -
>> +
>> void registerCleanup(CrashRecoveryContextCleanup *cleanup);
>> void unregisterCleanup(CrashRecoveryContextCleanup *cleanup);
>>
>> @@ -86,11 +77,9 @@ public:
>> /// make as little assumptions as possible about the program state when
>> /// RunSafely has returned false. Clients can use getBacktrace() to
>> retrieve
>> /// the backtrace of the crash on failures.
>> - bool RunSafely(void (*Fn)(void*), void *UserData);
>> - template<typename Functor>
>> - bool RunSafely(Functor Fn) {
>> - FunctorAdaptor<Functor> Adaptor = { Fn };
>> - return RunSafely(Adaptor.fn(), Adaptor.arg());
>> + bool RunSafely(function_ref<void()> Fn);
>> + bool RunSafely(void (*Fn)(void*), void *UserData) {
>> + return RunSafely([&]() { Fn(UserData); });
>> }
>>
>> /// \brief Execute the provide callback function (with the given
>> arguments) in
>> @@ -98,12 +87,10 @@ public:
>> /// requested stack size).
>> ///
>> /// See RunSafely() and llvm_execute_on_thread().
>> + bool RunSafelyOnThread(function_ref<void()>, unsigned
>> RequestedStackSize = 0);
>> bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
>> - unsigned RequestedStackSize = 0);
>> - template<typename Functor>
>> - bool RunSafelyOnThread(Functor Fn, unsigned RequestedStackSize = 0) {
>> - FunctorAdaptor<Functor> Adaptor = { Fn };
>> - return RunSafelyOnThread(Adaptor.fn(), Adaptor.arg(),
>> RequestedStackSize);
>> + unsigned RequestedStackSize = 0) {
>> + return RunSafelyOnThread([&]() { Fn(UserData); },
>> RequestedStackSize);
>> }
>>
>> /// \brief Explicitly trigger a crash recovery in the current process,
>> and
>>
>> Modified: llvm/trunk/include/llvm/Transforms/Utils/CtorUtils.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/CtorUtils.h?rev=208025&r1=208024&r2=208025&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Transforms/Utils/CtorUtils.h (original)
>> +++ llvm/trunk/include/llvm/Transforms/Utils/CtorUtils.h Mon May 5
>> 20:01:29 2014
>> @@ -14,8 +14,7 @@
>> #ifndef LLVM_TRANSFORMS_UTILS_CTOR_UTILS_H
>> #define LLVM_TRANSFORMS_UTILS_CTOR_UTILS_H
>>
>> -#include <functional>
>> -#include <vector>
>> +#include "llvm/ADT/STLExtras.h"
>>
>> namespace llvm {
>>
>> @@ -23,12 +22,10 @@ class GlobalVariable;
>> class Function;
>> class Module;
>>
>> -typedef bool (*ShouldRemoveCtor)(void *, Function *);
>> -
>> /// Call "ShouldRemove" for every entry in M's global_ctor list and
>> remove the
>> /// entries for which it returns true. Return true if anything changed.
>> -bool optimizeGlobalCtorsList(Module &M, ShouldRemoveCtor ShouldRemove,
>> - void *Context);
>> +bool optimizeGlobalCtorsList(Module &M,
>> + function_ref<bool(Function *)>
>> ShouldRemove);
>>
>> } // End llvm namespace
>>
>>
>> Modified: llvm/trunk/lib/Support/CrashRecoveryContext.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CrashRecoveryContext.cpp?rev=208025&r1=208024&r2=208025&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Support/CrashRecoveryContext.cpp (original)
>> +++ llvm/trunk/lib/Support/CrashRecoveryContext.cpp Mon May 5 20:01:29
>> 2014
>> @@ -301,7 +301,7 @@ void CrashRecoveryContext::Disable() {
>>
>> #endif
>>
>> -bool CrashRecoveryContext::RunSafely(void (*Fn)(void*), void *UserData) {
>> +bool CrashRecoveryContext::RunSafely(function_ref<void()> Fn) {
>> // If crash recovery is disabled, do nothing.
>> if (gCrashRecoveryEnabled) {
>> assert(!Impl && "Crash recovery context already initialized!");
>> @@ -313,7 +313,7 @@ bool CrashRecoveryContext::RunSafely(voi
>> }
>> }
>>
>> - Fn(UserData);
>> + Fn();
>> return true;
>> }
>>
>> @@ -334,8 +334,7 @@ const std::string &CrashRecoveryContext:
>>
>> namespace {
>> struct RunSafelyOnThreadInfo {
>> - void (*Fn)(void*);
>> - void *Data;
>> + function_ref<void()> Fn;
>> CrashRecoveryContext *CRC;
>> bool Result;
>> };
>> @@ -344,11 +343,11 @@ struct RunSafelyOnThreadInfo {
>> static void RunSafelyOnThread_Dispatch(void *UserData) {
>> RunSafelyOnThreadInfo *Info =
>> reinterpret_cast<RunSafelyOnThreadInfo*>(UserData);
>> - Info->Result = Info->CRC->RunSafely(Info->Fn, Info->Data);
>> + Info->Result = Info->CRC->RunSafely(Info->Fn);
>> }
>> -bool CrashRecoveryContext::RunSafelyOnThread(void (*Fn)(void*), void
>> *UserData,
>> +bool CrashRecoveryContext::RunSafelyOnThread(function_ref<void()> Fn,
>> unsigned
>> RequestedStackSize) {
>> - RunSafelyOnThreadInfo Info = { Fn, UserData, this, false };
>> + RunSafelyOnThreadInfo Info = { Fn, this, false };
>> llvm_execute_on_thread(RunSafelyOnThread_Dispatch, &Info,
>> RequestedStackSize);
>> if (CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *)Impl)
>> CRC->setSwitchedThread();
>>
>> Modified: llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp?rev=208025&r1=208024&r2=208025&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp (original)
>> +++ llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp Mon May 5 20:01:29 2014
>> @@ -54,16 +54,16 @@ namespace {
>>
>> bool RemoveUnusedGlobalValue(GlobalValue &GV);
>> };
>> +}
>>
>> /// Returns true if F contains only a single "ret" instruction.
>> -bool isEmptyFunction(void *Context, Function *F) {
>> +static bool isEmptyFunction(Function *F) {
>> BasicBlock &Entry = F->getEntryBlock();
>> if (Entry.size() != 1 || !isa<ReturnInst>(Entry.front()))
>> return false;
>> ReturnInst &RI = cast<ReturnInst>(Entry.front());
>> return RI.getReturnValue() == NULL;
>> }
>> -}
>>
>> char GlobalDCE::ID = 0;
>> INITIALIZE_PASS(GlobalDCE, "globaldce",
>> @@ -75,7 +75,7 @@ bool GlobalDCE::runOnModule(Module &M) {
>> bool Changed = false;
>>
>> // Remove empty functions from the global ctors list.
>> - Changed |= optimizeGlobalCtorsList(M, isEmptyFunction, nullptr);
>> + Changed |= optimizeGlobalCtorsList(M, isEmptyFunction);
>>
>> // Loop over the module, adding globals which are obviously necessary.
>> for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
>>
>> Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=208025&r1=208024&r2=208025&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
>> +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Mon May 5 20:01:29 2014
>> @@ -3022,10 +3022,9 @@ bool GlobalOpt::runOnModule(Module &M) {
>> LocalChange |= OptimizeFunctions(M);
>>
>> // Optimize global_ctors list.
>> - LocalChange |= optimizeGlobalCtorsList(M, [](void *C, Function *F)
>> -> bool {
>> - GlobalOpt *self = static_cast<GlobalOpt *>(C);
>> - return EvaluateStaticConstructor(F, self->DL, self->TLI);
>> - }, this);
>> + LocalChange |= optimizeGlobalCtorsList(M, [&](Function *F) {
>> + return EvaluateStaticConstructor(F, DL, TLI);
>> + });
>>
>> // Optimize non-address-taken globals.
>> LocalChange |= OptimizeGlobalVars(M);
>>
>> Modified: llvm/trunk/lib/Transforms/Utils/CtorUtils.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CtorUtils.cpp?rev=208025&r1=208024&r2=208025&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Utils/CtorUtils.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Utils/CtorUtils.cpp Mon May 5 20:01:29 2014
>> @@ -132,8 +132,8 @@ GlobalVariable *findGlobalCtors(Module &
>>
>> /// Call "ShouldRemove" for every entry in M's global_ctor list and
>> remove the
>> /// entries for which it returns true. Return true if anything changed.
>> -bool optimizeGlobalCtorsList(Module &M, ShouldRemoveCtor ShouldRemove,
>> - void *Context) {
>> +bool optimizeGlobalCtorsList(Module &M,
>> + function_ref<bool(Function *)>
>> ShouldRemove) {
>> GlobalVariable *GlobalCtors = findGlobalCtors(M);
>> if (!GlobalCtors)
>> return false;
>> @@ -163,7 +163,7 @@ bool optimizeGlobalCtorsList(Module &M,
>> continue;
>>
>> // If we can evaluate the ctor at compile time, do.
>> - if (ShouldRemove(Context, F)) {
>> + if (ShouldRemove(F)) {
>> Ctors.erase(Ctors.begin() + i);
>> MadeChange = true;
>> --i;
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
>
>
> --
> Best Regards,
>
> Kevin Qin
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140505/f14af865/attachment.html>
More information about the llvm-commits
mailing list