IVGCVSW-2037 : separate registry for layer support intrefaces

* because their lifetime is different from backends

Change-Id: I9ba525e7e503b148cde1294933f3954b8bad3d68
diff --git a/include/armnn/BackendId.hpp b/include/armnn/BackendId.hpp
index d2479eb..af3b799 100644
--- a/include/armnn/BackendId.hpp
+++ b/include/armnn/BackendId.hpp
@@ -4,10 +4,12 @@
 //
 #pragma once
 
+#include <ostream>
 #include <set>
 #include <unordered_set>
 #include <string>
 #include <memory>
+#include <vector>
 
 namespace armnn
 {
diff --git a/include/armnn/ILayerSupport.hpp b/include/armnn/ILayerSupport.hpp
index 58adea8..d63c3a7 100644
--- a/include/armnn/ILayerSupport.hpp
+++ b/include/armnn/ILayerSupport.hpp
@@ -8,6 +8,7 @@
 #include <armnn/Optional.hpp>
 #include <vector>
 #include <cctype>
+#include <memory>
 
 namespace armnn
 {
@@ -178,4 +179,6 @@
                                         Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const;
 }; // class ILayerSupport
 
+using ILayerSupportSharedPtr = std::shared_ptr<ILayerSupport>;
+
 } // namespace armnn
diff --git a/include/armnn/Types.hpp b/include/armnn/Types.hpp
index bb0b1e6..cd6e17b 100644
--- a/include/armnn/Types.hpp
+++ b/include/armnn/Types.hpp
@@ -6,8 +6,8 @@
 
 #include <array>
 #include <memory>
-#include "ILayerSupport.hpp"
 #include "BackendId.hpp"
+#include "Exceptions.hpp"
 
 namespace armnn
 {
@@ -148,7 +148,6 @@
 
 public:
     virtual const BackendId& GetId() const = 0;
-    virtual const ILayerSupport& GetLayerSupport() const = 0;
 };
 
 using IBackendSharedPtr = std::shared_ptr<IBackend>;
diff --git a/src/armnn/LayerSupport.cpp b/src/armnn/LayerSupport.cpp
index 2494c74..846da60 100644
--- a/src/armnn/LayerSupport.cpp
+++ b/src/armnn/LayerSupport.cpp
@@ -5,7 +5,7 @@
 #include <armnn/LayerSupport.hpp>
 #include <armnn/Optional.hpp>
 
-#include <backends/BackendRegistry.hpp>
+#include <backends/LayerSupportRegistry.hpp>
 
 #include <boost/assert.hpp>
 
@@ -30,34 +30,17 @@
     }
 }
 
-IBackend& GetBackend(const BackendId& id)
-{
-    static std::unordered_map<BackendId, IBackendUniquePtr> cachedBackends;
-    auto it = cachedBackends.find(id);
-    if (it == cachedBackends.end())
-    {
-        auto factoryFunc = BackendRegistry::Instance().GetFactory(id);
-        auto emplaceResult =
-            cachedBackends.emplace(
-                std::make_pair(id, factoryFunc())
-            );
-        BOOST_ASSERT(emplaceResult.second);
-        it = emplaceResult.first;
-    }
-
-    return *(it->second.get());
-}
-
 }
 
 // Helper macro to avoid code duplication.
 // Forwards function func to funcRef, funcNeon or funcCl, depending on the value of compute.
-#define FORWARD_LAYER_SUPPORT_FUNC(backend, func, ...) \
+#define FORWARD_LAYER_SUPPORT_FUNC(backendId, func, ...) \
     std::string reasonIfUnsupportedFull; \
     bool isSupported; \
     try { \
-        auto const& layerSupportObject = GetBackend(backend).GetLayerSupport(); \
-        isSupported = layerSupportObject.func(__VA_ARGS__, Optional<std::string&>(reasonIfUnsupportedFull)); \
+        auto factoryFunc = LayerSupportRegistryInstance().GetFactory(backendId); \
+        auto layerSupportObject = factoryFunc(); \
+        isSupported = layerSupportObject->func(__VA_ARGS__, Optional<std::string&>(reasonIfUnsupportedFull)); \
         CopyErrorMessage(reasonIfUnsupported, reasonIfUnsupportedFull.c_str(), reasonIfUnsupportedMaxLength); \
     } catch (InvalidArgumentException e) { \
         /* re-throwing with more context information */ \
diff --git a/src/backends/BackendRegistry.cpp b/src/backends/BackendRegistry.cpp
index 1360168..e936121 100644
--- a/src/backends/BackendRegistry.cpp
+++ b/src/backends/BackendRegistry.cpp
@@ -4,54 +4,14 @@
 //
 
 #include "BackendRegistry.hpp"
-#include <armnn/Exceptions.hpp>
 
 namespace armnn
 {
 
-BackendRegistry& BackendRegistry::Instance()
+BackendRegistry& BackendRegistryInstance()
 {
     static BackendRegistry instance;
     return instance;
 }
 
-void BackendRegistry::Register(const BackendId& id, FactoryFunction factory)
-{
-    if (m_BackendFactories.count(id) > 0)
-    {
-        throw InvalidArgumentException(std::string(id) + " already registered as backend",
-                                       CHECK_LOCATION());
-    }
-
-    m_BackendFactories[id] = factory;
-}
-
-BackendRegistry::FactoryFunction BackendRegistry::GetFactory(const BackendId& id) const
-{
-    auto it = m_BackendFactories.find(id);
-    if (it == m_BackendFactories.end())
-    {
-        throw InvalidArgumentException(std::string(id) + " has no backend factory registered",
-                                       CHECK_LOCATION());
-    }
-
-    return it->second;
-}
-
-void BackendRegistry::Swap(BackendRegistry::FactoryStorage& other)
-{
-    BackendRegistry& instance = Instance();
-    std::swap(instance.m_BackendFactories, other);
-}
-
-BackendIdSet BackendRegistry::GetBackendIds() const
-{
-    BackendIdSet result;
-    for (const auto& it : m_BackendFactories)
-    {
-        result.insert(it.first);
-    }
-    return result;
-}
-
 } // namespace armnn
diff --git a/src/backends/BackendRegistry.hpp b/src/backends/BackendRegistry.hpp
index e2c526d..23cb37d 100644
--- a/src/backends/BackendRegistry.hpp
+++ b/src/backends/BackendRegistry.hpp
@@ -5,49 +5,19 @@
 #pragma once
 
 #include <armnn/Types.hpp>
-#include <functional>
-#include <memory>
-#include <unordered_map>
+#include "RegistryCommon.hpp"
 
 namespace armnn
 {
 
-class IBackend;
+using BackendRegistry = RegistryCommon<IBackend, IBackendUniquePtr>;
 
-class BackendRegistry
+BackendRegistry& BackendRegistryInstance();
+
+template <>
+struct RegisteredTypeName<IBackend>
 {
-public:
-    using FactoryFunction = std::function<IBackendUniquePtr()>;
-
-    static BackendRegistry& Instance();
-
-    void Register(const BackendId& id, FactoryFunction factory);
-    FactoryFunction GetFactory(const BackendId& id) const;
-
-    struct Helper
-    {
-        Helper(const BackendId& id, FactoryFunction factory)
-        {
-            BackendRegistry::Instance().Register(id, factory);
-        }
-    };
-
-    size_t Size() const { return m_BackendFactories.size(); }
-    BackendIdSet GetBackendIds() const;
-
-protected:
-    using FactoryStorage = std::unordered_map<BackendId, FactoryFunction>;
-
-    // For testing only
-    static void Swap(FactoryStorage& other);
-    BackendRegistry() {}
-    ~BackendRegistry() {}
-
-private:
-    BackendRegistry(const BackendRegistry&) = delete;
-    BackendRegistry& operator=(const BackendRegistry&) = delete;
-
-    FactoryStorage m_BackendFactories;
+    static const char * Name() { return "IBackend"; }
 };
 
 } // namespace armnn
diff --git a/src/backends/CMakeLists.txt b/src/backends/CMakeLists.txt
index 3079447..045bd2a 100644
--- a/src/backends/CMakeLists.txt
+++ b/src/backends/CMakeLists.txt
@@ -12,11 +12,14 @@
     IBackendInternal.hpp
     ILayerSupport.cpp
     ITensorHandle.hpp
+    LayerSupportRegistry.cpp
+    LayerSupportRegistry.hpp
     MakeWorkloadHelper.hpp
     MemCopyWorkload.cpp
     MemCopyWorkload.hpp
     OutputHandler.cpp
     OutputHandler.hpp
+    RegistryCommon.hpp
     StringMapping.cpp
     StringMapping.hpp
     WorkloadDataCollector.hpp
diff --git a/src/backends/LayerSupportRegistry.cpp b/src/backends/LayerSupportRegistry.cpp
new file mode 100644
index 0000000..63b4da7
--- /dev/null
+++ b/src/backends/LayerSupportRegistry.cpp
@@ -0,0 +1,17 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "LayerSupportRegistry.hpp"
+
+namespace armnn
+{
+
+LayerSupportRegistry& LayerSupportRegistryInstance()
+{
+    static LayerSupportRegistry instance;
+    return instance;
+}
+
+} // namespace armnn
diff --git a/src/backends/LayerSupportRegistry.hpp b/src/backends/LayerSupportRegistry.hpp
new file mode 100644
index 0000000..a5efad0
--- /dev/null
+++ b/src/backends/LayerSupportRegistry.hpp
@@ -0,0 +1,23 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include "RegistryCommon.hpp"
+#include <armnn/ILayerSupport.hpp>
+
+namespace armnn
+{
+
+using LayerSupportRegistry = RegistryCommon<ILayerSupport, ILayerSupportSharedPtr>;
+
+LayerSupportRegistry& LayerSupportRegistryInstance();
+
+template <>
+struct RegisteredTypeName<ILayerSupport>
+{
+    static const char * Name() { return "ILayerSupport"; }
+};
+
+} // namespace armnn
diff --git a/src/backends/RegistryCommon.hpp b/src/backends/RegistryCommon.hpp
new file mode 100644
index 0000000..27663b6
--- /dev/null
+++ b/src/backends/RegistryCommon.hpp
@@ -0,0 +1,100 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include <armnn/BackendId.hpp>
+#include <armnn/Exceptions.hpp>
+#include <functional>
+#include <memory>
+#include <unordered_map>
+
+namespace armnn
+{
+
+template <typename RegisteredType>
+struct RegisteredTypeName
+{
+    static const char * Name() { return "UNKNOWN"; }
+};
+
+template <typename RegisteredType, typename PointerType>
+class RegistryCommon
+{
+public:
+    using FactoryFunction = std::function<PointerType()>;
+
+    void Register(const BackendId& id, FactoryFunction factory)
+    {
+        if (m_Factories.count(id) > 0)
+        {
+            throw InvalidArgumentException(
+                std::string(id) + " already registered as " + RegisteredTypeName<RegisteredType>::Name() + " factory",
+                CHECK_LOCATION());
+        }
+
+        m_Factories[id] = factory;
+    }
+
+    FactoryFunction GetFactory(const BackendId& id) const
+    {
+        auto it = m_Factories.find(id);
+        if (it == m_Factories.end())
+        {
+            throw InvalidArgumentException(
+                std::string(id) + " has no " + RegisteredTypeName<RegisteredType>::Name() + " factory registered",
+                CHECK_LOCATION());
+        }
+
+        return it->second;
+    }
+
+    size_t Size() const
+    {
+        return m_Factories.size();
+    }
+
+    BackendIdSet GetBackendIds() const
+    {
+        BackendIdSet result;
+        for (const auto& it : m_Factories)
+        {
+            result.insert(it.first);
+        }
+        return result;
+    }
+
+    RegistryCommon() {}
+    virtual ~RegistryCommon() {}
+
+protected:
+    using FactoryStorage = std::unordered_map<BackendId, FactoryFunction>;
+
+    // For testing only
+    static void Swap(RegistryCommon& instance, FactoryStorage& other)
+    {
+        std::swap(instance.m_Factories, other);
+    }
+
+private:
+    RegistryCommon(const RegistryCommon&) = delete;
+    RegistryCommon& operator=(const RegistryCommon&) = delete;
+
+    FactoryStorage m_Factories;
+};
+
+template <typename RegistryType>
+struct StaticRegistryInitializer
+{
+    using FactoryFunction = typename RegistryType::FactoryFunction;
+
+    StaticRegistryInitializer(RegistryType& instance,
+                              const BackendId& id,
+                              FactoryFunction factory)
+    {
+        instance.Register(id, factory);
+    }
+};
+
+} // namespace armnn
diff --git a/src/backends/cl/CMakeLists.txt b/src/backends/cl/CMakeLists.txt
index d38fb68..1f99017 100644
--- a/src/backends/cl/CMakeLists.txt
+++ b/src/backends/cl/CMakeLists.txt
@@ -6,6 +6,7 @@
 list(APPEND armnnClBackend_sources
     ClBackend.cpp
     ClBackend.hpp
+    ClBackendId.hpp
     ClContextControl.cpp
     ClContextControl.hpp
     ClLayerSupport.cpp
@@ -16,6 +17,7 @@
 
 if(ARMCOMPUTECL)
     list(APPEND armnnClBackend_sources
+        ClBackendId.hpp
         OpenClTimer.cpp
         OpenClTimer.hpp
     )
diff --git a/src/backends/cl/ClBackend.cpp b/src/backends/cl/ClBackend.cpp
index 29d1b3a..1bab96b 100644
--- a/src/backends/cl/ClBackend.cpp
+++ b/src/backends/cl/ClBackend.cpp
@@ -4,6 +4,7 @@
 //
 
 #include "ClBackend.hpp"
+#include "ClBackendId.hpp"
 #include "ClWorkloadFactory.hpp"
 
 #include <backends/BackendRegistry.hpp>
@@ -16,7 +17,9 @@
 namespace
 {
 
-static BackendRegistry::Helper g_RegisterHelper{
+static StaticRegistryInitializer<BackendRegistry> g_RegisterHelper
+{
+    BackendRegistryInstance(),
     ClBackend::GetIdStatic(),
     []()
     {
@@ -28,15 +31,10 @@
 
 const BackendId& ClBackend::GetIdStatic()
 {
-    static const BackendId s_Id{"GpuAcc"};
+    static const BackendId s_Id{ClBackendId()};
     return s_Id;
 }
 
-const ILayerSupport& ClBackend::GetLayerSupport() const
-{
-    return m_LayerSupport;
-}
-
 std::unique_ptr<IWorkloadFactory> ClBackend::CreateWorkloadFactory() const
 {
     return std::make_unique<ClWorkloadFactory>();
diff --git a/src/backends/cl/ClBackend.hpp b/src/backends/cl/ClBackend.hpp
index 1a99b76..49a7a46 100644
--- a/src/backends/cl/ClBackend.hpp
+++ b/src/backends/cl/ClBackend.hpp
@@ -5,7 +5,6 @@
 #pragma once
 
 #include <backends/IBackendInternal.hpp>
-#include "ClLayerSupport.hpp"
 
 namespace armnn
 {
@@ -19,14 +18,9 @@
     static const BackendId& GetIdStatic();
     const BackendId& GetId() const override { return GetIdStatic(); }
 
-    const ILayerSupport& GetLayerSupport() const override;
-
     std::unique_ptr<IWorkloadFactory> CreateWorkloadFactory() const override;
 
     static void Destroy(IBackend* backend);
-
-private:
-    ClLayerSupport m_LayerSupport;
 };
 
 } // namespace armnn
\ No newline at end of file
diff --git a/src/backends/cl/ClBackendId.hpp b/src/backends/cl/ClBackendId.hpp
new file mode 100644
index 0000000..3f8fec2
--- /dev/null
+++ b/src/backends/cl/ClBackendId.hpp
@@ -0,0 +1,12 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+namespace armnn
+{
+
+constexpr const char * ClBackendId() { return "GpuAcc"; }
+
+} // namespace armnn
diff --git a/src/backends/cl/ClLayerSupport.cpp b/src/backends/cl/ClLayerSupport.cpp
index 6a49a80..3ca8bb5 100644
--- a/src/backends/cl/ClLayerSupport.cpp
+++ b/src/backends/cl/ClLayerSupport.cpp
@@ -4,11 +4,14 @@
 //
 
 #include "ClLayerSupport.hpp"
+#include "ClBackendId.hpp"
 
 #include <armnn/Descriptors.hpp>
 #include <armnn/InternalTypes.hpp>
 #include <armnn/LayerSupportCommon.hpp>
 
+#include <backends/LayerSupportRegistry.hpp>
+
 #include <boost/core/ignore_unused.hpp>
 
 #ifdef ARMCOMPUTECL_ENABLED
@@ -40,6 +43,21 @@
 namespace
 {
 
+ILayerSupportSharedPtr GetLayerSupportPointer()
+{
+    static ILayerSupportSharedPtr instance{new ClLayerSupport};
+    return instance;
+}
+
+static StaticRegistryInitializer<LayerSupportRegistry> g_RegisterHelper{
+    LayerSupportRegistryInstance(),
+    ClBackendId(),
+    []()
+    {
+        return GetLayerSupportPointer();
+    }
+};
+
 template<unsigned int FilterSize>
 bool IsMatchingSize2d(const TensorInfo& weightInfo)
 {
diff --git a/src/backends/common.mk b/src/backends/common.mk
index 498a8f1..2b649ad 100644
--- a/src/backends/common.mk
+++ b/src/backends/common.mk
@@ -12,6 +12,7 @@
     CpuTensorHandle.cpp \
     ILayerSupport.cpp \
     MemCopyWorkload.cpp \
+    LayerSupportRegistry.cpp \
     OutputHandler.cpp \
     StringMapping.cpp \
     WorkloadData.cpp \
diff --git a/src/backends/neon/CMakeLists.txt b/src/backends/neon/CMakeLists.txt
index e294ff7..058553d 100644
--- a/src/backends/neon/CMakeLists.txt
+++ b/src/backends/neon/CMakeLists.txt
@@ -7,6 +7,7 @@
     list(APPEND armnnNeonBackend_sources
         NeonBackend.cpp
         NeonBackend.hpp
+        NeonBackendId.hpp
         NeonInterceptorScheduler.hpp
         NeonInterceptorScheduler.cpp
         NeonLayerSupport.cpp
@@ -26,6 +27,7 @@
 
 else()
     list(APPEND armnnNeonBackend_sources
+        NeonBackendId.hpp
         NeonLayerSupport.cpp
         NeonLayerSupport.hpp
         NeonWorkloadFactory.cpp
diff --git a/src/backends/neon/NeonBackend.cpp b/src/backends/neon/NeonBackend.cpp
index 3c12f77..b710295 100644
--- a/src/backends/neon/NeonBackend.cpp
+++ b/src/backends/neon/NeonBackend.cpp
@@ -4,6 +4,7 @@
 //
 
 #include "NeonBackend.hpp"
+#include "NeonBackendId.hpp"
 #include "NeonWorkloadFactory.hpp"
 
 #include <backends/BackendRegistry.hpp>
@@ -16,7 +17,9 @@
 namespace
 {
 
-static BackendRegistry::Helper g_RegisterHelper{
+static StaticRegistryInitializer<BackendRegistry> g_RegisterHelper
+{
+    BackendRegistryInstance(),
     NeonBackend::GetIdStatic(),
     []()
     {
@@ -28,15 +31,10 @@
 
 const BackendId& NeonBackend::GetIdStatic()
 {
-    static const BackendId s_Id{"CpuAcc"};
+    static const BackendId s_Id{NeonBackendId()};
     return s_Id;
 }
 
-const ILayerSupport& NeonBackend::GetLayerSupport() const
-{
-    return m_LayerSupport;
-}
-
 std::unique_ptr<IWorkloadFactory> NeonBackend::CreateWorkloadFactory() const
 {
     return std::make_unique<NeonWorkloadFactory>();
diff --git a/src/backends/neon/NeonBackend.hpp b/src/backends/neon/NeonBackend.hpp
index c7f7f6e..6280610 100644
--- a/src/backends/neon/NeonBackend.hpp
+++ b/src/backends/neon/NeonBackend.hpp
@@ -5,7 +5,6 @@
 #pragma once
 
 #include <backends/IBackendInternal.hpp>
-#include "NeonLayerSupport.hpp"
 
 namespace armnn
 {
@@ -19,14 +18,9 @@
     static const BackendId& GetIdStatic();
     const BackendId& GetId() const override { return GetIdStatic(); }
 
-    const ILayerSupport& GetLayerSupport() const override;
-
     std::unique_ptr<IWorkloadFactory> CreateWorkloadFactory() const override;
 
     static void Destroy(IBackend* backend);
-
-private:
-    NeonLayerSupport m_LayerSupport;
 };
 
 } // namespace armnn
\ No newline at end of file
diff --git a/src/backends/neon/NeonBackendId.hpp b/src/backends/neon/NeonBackendId.hpp
new file mode 100644
index 0000000..6e6412a
--- /dev/null
+++ b/src/backends/neon/NeonBackendId.hpp
@@ -0,0 +1,12 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+namespace armnn
+{
+
+constexpr const char * NeonBackendId() { return "CpuAcc"; }
+
+} // namespace armnn
diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp
index 0add6f5..3638212 100644
--- a/src/backends/neon/NeonLayerSupport.cpp
+++ b/src/backends/neon/NeonLayerSupport.cpp
@@ -4,6 +4,7 @@
 //
 
 #include "NeonLayerSupport.hpp"
+#include "NeonBackendId.hpp"
 
 #include <armnn/Descriptors.hpp>
 #include <armnn/InternalTypes.hpp>
@@ -11,6 +12,8 @@
 #include <armnn/Tensor.hpp>
 #include <armnn/Types.hpp>
 
+#include <backends/LayerSupportRegistry.hpp>
+
 #include <boost/core/ignore_unused.hpp>
 
 #ifdef ARMCOMPUTENEON_ENABLED
@@ -37,6 +40,21 @@
 namespace
 {
 
+ILayerSupportSharedPtr GetLayerSupportPointer()
+{
+    static ILayerSupportSharedPtr instance{new NeonLayerSupport};
+    return instance;
+}
+
+static StaticRegistryInitializer<LayerSupportRegistry> g_RegisterHelper{
+    LayerSupportRegistryInstance(),
+    NeonBackendId(),
+    []()
+    {
+        return GetLayerSupportPointer();
+    }
+};
+
 bool IsNeonBackendSupported(Optional<std::string&> reasonIfUnsupported)
 {
 #if ARMCOMPUTENEON_ENABLED
diff --git a/src/backends/reference/CMakeLists.txt b/src/backends/reference/CMakeLists.txt
index a0d27cc..5f698f4 100644
--- a/src/backends/reference/CMakeLists.txt
+++ b/src/backends/reference/CMakeLists.txt
@@ -6,6 +6,7 @@
 list(APPEND armnnRefBackend_sources
     RefBackend.cpp
     RefBackend.hpp
+    RefBackendId.hpp
     RefLayerSupport.cpp
     RefLayerSupport.hpp
     RefWorkloadFactory.cpp
diff --git a/src/backends/reference/RefBackend.cpp b/src/backends/reference/RefBackend.cpp
index 1f08d82..9afb42d 100644
--- a/src/backends/reference/RefBackend.cpp
+++ b/src/backends/reference/RefBackend.cpp
@@ -4,6 +4,7 @@
 //
 
 #include "RefBackend.hpp"
+#include "RefBackendId.hpp"
 #include "RefWorkloadFactory.hpp"
 
 #include <backends/BackendRegistry.hpp>
@@ -16,7 +17,9 @@
 namespace
 {
 
-static BackendRegistry::Helper s_RegisterHelper{
+static StaticRegistryInitializer<BackendRegistry> g_RegisterHelper
+{
+    BackendRegistryInstance(),
     RefBackend::GetIdStatic(),
     []()
     {
@@ -28,15 +31,10 @@
 
 const BackendId& RefBackend::GetIdStatic()
 {
-    static const BackendId s_Id{"CpuRef"};
+    static const BackendId s_Id{RefBackendId()};
     return s_Id;
 }
 
-const ILayerSupport& RefBackend::GetLayerSupport() const
-{
-    return m_LayerSupport;
-}
-
 std::unique_ptr<IWorkloadFactory> RefBackend::CreateWorkloadFactory() const
 {
     return std::make_unique<RefWorkloadFactory>();
diff --git a/src/backends/reference/RefBackend.hpp b/src/backends/reference/RefBackend.hpp
index c206dbd..0cd3cf4 100644
--- a/src/backends/reference/RefBackend.hpp
+++ b/src/backends/reference/RefBackend.hpp
@@ -5,7 +5,6 @@
 #pragma once
 
 #include <backends/IBackendInternal.hpp>
-#include "RefLayerSupport.hpp"
 
 namespace armnn
 {
@@ -19,14 +18,9 @@
     static const BackendId& GetIdStatic();
     const BackendId& GetId() const override { return GetIdStatic(); }
 
-    const ILayerSupport& GetLayerSupport() const override;
-
     std::unique_ptr<IWorkloadFactory> CreateWorkloadFactory() const override;
 
     static void Destroy(IBackend* backend);
-
-private:
-    RefLayerSupport m_LayerSupport;
 };
 
 } // namespace armnn
\ No newline at end of file
diff --git a/src/backends/reference/RefBackendId.hpp b/src/backends/reference/RefBackendId.hpp
new file mode 100644
index 0000000..2a7f9f1
--- /dev/null
+++ b/src/backends/reference/RefBackendId.hpp
@@ -0,0 +1,12 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+namespace armnn
+{
+
+constexpr const char * RefBackendId() { return "CpuRef"; }
+
+} // namespace armnn
diff --git a/src/backends/reference/RefLayerSupport.cpp b/src/backends/reference/RefLayerSupport.cpp
index 909df75..253d9c2 100644
--- a/src/backends/reference/RefLayerSupport.cpp
+++ b/src/backends/reference/RefLayerSupport.cpp
@@ -4,11 +4,14 @@
 //
 
 #include "RefLayerSupport.hpp"
+#include "RefBackendId.hpp"
 
 #include <armnn/InternalTypes.hpp>
 #include <armnn/LayerSupportCommon.hpp>
 #include <armnn/Types.hpp>
 
+#include <backends/LayerSupportRegistry.hpp>
+
 #include <boost/core/ignore_unused.hpp>
 
 using namespace boost;
@@ -19,6 +22,21 @@
 namespace
 {
 
+ILayerSupportSharedPtr GetLayerSupportPointer()
+{
+    static ILayerSupportSharedPtr instance{new RefLayerSupport};
+    return instance;
+}
+
+static StaticRegistryInitializer<LayerSupportRegistry> g_RegisterHelper{
+    LayerSupportRegistryInstance(),
+    RefBackendId(),
+    []()
+    {
+        return GetLayerSupportPointer();
+    }
+};
+
 template<typename Float32Func, typename Uint8Func, typename ... Params>
 bool IsSupportedForDataTypeRef(Optional<std::string&> reasonIfUnsupported,
                                DataType dataType,
diff --git a/src/backends/test/BackendRegistryTests.cpp b/src/backends/test/BackendRegistryTests.cpp
index e895df6..f6f7499 100644
--- a/src/backends/test/BackendRegistryTests.cpp
+++ b/src/backends/test/BackendRegistryTests.cpp
@@ -15,16 +15,16 @@
 public:
     SwapRegistryStorage() : armnn::BackendRegistry()
     {
-        Swap(m_TempStorage);
+        Swap(armnn::BackendRegistryInstance(),  m_TempStorage);
     }
 
     ~SwapRegistryStorage()
     {
-        Swap(m_TempStorage);
+        Swap(armnn::BackendRegistryInstance(),m_TempStorage);
     }
 
 private:
-    BackendRegistry::FactoryStorage m_TempStorage;
+    FactoryStorage m_TempStorage;
 };
 
 }
@@ -33,30 +33,36 @@
 
 BOOST_AUTO_TEST_CASE(SwapRegistry)
 {
-    using armnn::BackendRegistry;
-    auto nFactories = BackendRegistry::Instance().Size();
+    using namespace armnn;
+    auto nFactories = BackendRegistryInstance().Size();
     {
         SwapRegistryStorage helper;
-        BOOST_TEST(BackendRegistry::Instance().Size() == 0);
+        BOOST_TEST(BackendRegistryInstance().Size() == 0);
     }
-    BOOST_TEST(BackendRegistry::Instance().Size() == nFactories);
+    BOOST_TEST(BackendRegistryInstance().Size() == nFactories);
 }
 
 BOOST_AUTO_TEST_CASE(TestRegistryHelper)
 {
-    using armnn::BackendRegistry;
+    using namespace armnn;
     SwapRegistryStorage helper;
 
     bool called = false;
-    BackendRegistry::Helper factoryHelper("HelloWorld", [&called]() {
-        called = true;
-        return armnn::IBackendUniquePtr(nullptr, nullptr);
-    } );
+
+    StaticRegistryInitializer<BackendRegistry> factoryHelper(
+        BackendRegistryInstance(),
+        "HelloWorld",
+        [&called]()
+        {
+            called = true;
+            return armnn::IBackendUniquePtr(nullptr, nullptr);
+        }
+    );
 
     // sanity check: the factory has not been called yet
     BOOST_TEST(called == false);
 
-    auto factoryFunction = BackendRegistry::Instance().GetFactory("HelloWorld");
+    auto factoryFunction = BackendRegistryInstance().GetFactory("HelloWorld");
 
     // sanity check: the factory still not called
     BOOST_TEST(called == false);
@@ -67,19 +73,23 @@
 
 BOOST_AUTO_TEST_CASE(TestDirectCallToRegistry)
 {
-    using armnn::BackendRegistry;
+    using namespace armnn;
     SwapRegistryStorage helper;
 
     bool called = false;
-    BackendRegistry::Instance().Register("HelloWorld", [&called]() {
-        called = true;
-        return armnn::IBackendUniquePtr(nullptr, nullptr);
-    } );
+    BackendRegistryInstance().Register(
+        "HelloWorld",
+        [&called]()
+        {
+            called = true;
+            return armnn::IBackendUniquePtr(nullptr, nullptr);
+        }
+    );
 
     // sanity check: the factory has not been called yet
     BOOST_TEST(called == false);
 
-    auto factoryFunction = BackendRegistry::Instance().GetFactory("HelloWorld");
+    auto factoryFunction = BackendRegistryInstance().GetFactory("HelloWorld");
 
     // sanity check: the factory still not called
     BOOST_TEST(called == false);