[llvm] r208025 - Add llvm::function_ref (and a couple of uses of it), representing a type-erased reference to a callable object.
Kevin Qin
kevinqindev at gmail.com
Mon May 5 18:37:25 PDT 2014
This commit make trunk broken. Please have a look.
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/20140506/77d0c35f/attachment.html>
More information about the llvm-commits
mailing list