Commit d5acf910 authored by Kenneth Moreland's avatar Kenneth Moreland
Browse files

Fix dropped UnknownArrayHandle symbols

For some reason, GCC is dropping the templated function instances use
for the `UnknownArrayHandle` constructor. Apparently, something in the
compiler or the linker is being over aggressive about removing unused
symbols and is actually dropping symbols that are being used. Maybe it
is because the functions are not directly called but their pointers are
used.

To get around this problem, mark these templated functions in
UnknownArrayHandle.h with the `used` attribute to force the compiler/
linker to keep them. There should be no consequence to that as these
function templates are only instantiated if they are used.
parent 149e5aba
Pipeline #251177 passed with stage
in 0 seconds
......@@ -33,8 +33,27 @@ namespace cont
namespace detail
{
#ifdef VTKM_GCC
// On rare occasion, we have seen errors like this:
// `_ZN4vtkm4cont6detailL27UnknownAHNumberOfComponentsIxEEiv' referenced in section
// `.data.rel.ro.local' of CMakeFiles/UnitTests_vtkm_cont_testing.dir/UnitTestCellSet.cxx.o:
// defined in discarded section
// `.text._ZN4vtkm4cont6detailL27UnknownAHNumberOfComponentsIxEEiv[_ZN4vtkm4cont14ArrayGetValuesINS0_15StorageTagBasicExNS0_18StorageTagCountingES2_EEvRKNS0_11ArrayHandleIxT_EERKNS4_IT0_T1_EERNS4_IS9_T2_EE]'
// of CMakeFiles/UnitTests_vtkm_cont_testing.dir/UnitTestCellSet.cxx.o
// I don't know what circumstances exactly lead up to this, but it appears that the compiler is
// being overly aggressive with removing unused symbols. In this instance, it seems to have removed
// a function actually being used. This might be a bug in the compiler (I happen to have seen it in
// gcc 8.3, 9.4, and 11.0), or it could be caused by a link-time optimizer. The problem should be
// able to be solved by explictly saying that this templated method is being used. (I can't think
// of any circumstances where this template would be instantiated but not used.) If the compiler
// knows this is being used, it should know all the templated methods internal are also used.
#define VTKM_FORCE_USED __attribute__((used))
#else
#define VTKM_FORCE_USED
#endif
template <typename T, typename S>
static void UnknownAHDelete(void* mem)
VTKM_FORCE_USED static void UnknownAHDelete(void* mem)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
......@@ -42,13 +61,13 @@ static void UnknownAHDelete(void* mem)
}
template <typename T, typename S>
static void* UnknownAHNewInstance()
VTKM_FORCE_USED static void* UnknownAHNewInstance()
{
return new vtkm::cont::ArrayHandle<T, S>;
}
template <typename T, typename S>
static vtkm::Id UnknownAHNumberOfValues(void* mem)
VTKM_FORCE_USED static vtkm::Id UnknownAHNumberOfValues(void* mem)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
......@@ -69,7 +88,7 @@ struct UnknownAHNumberOfComponentsImpl<T, vtkm::VecTraitsTagSizeVariable>
};
template <typename T>
static vtkm::IdComponent UnknownAHNumberOfComponents()
VTKM_FORCE_USED static vtkm::IdComponent UnknownAHNumberOfComponents()
{
return UnknownAHNumberOfComponentsImpl<T>::Value;
}
......@@ -88,16 +107,16 @@ struct UnknownAHNumberOfComponentsFlatImpl<T, vtkm::VecTraitsTagSizeVariable>
};
template <typename T>
static vtkm::IdComponent UnknownAHNumberOfComponentsFlat()
VTKM_FORCE_USED static vtkm::IdComponent UnknownAHNumberOfComponentsFlat()
{
return UnknownAHNumberOfComponentsFlatImpl<T>::Value;
}
template <typename T, typename S>
static void UnknownAHAllocate(void* mem,
vtkm::Id numValues,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
VTKM_FORCE_USED static void UnknownAHAllocate(void* mem,
vtkm::Id numValues,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
......@@ -105,7 +124,7 @@ static void UnknownAHAllocate(void* mem,
}
template <typename T, typename S>
static void UnknownAHShallowCopy(const void* sourceMem, void* destinationMem)
VTKM_FORCE_USED static void UnknownAHShallowCopy(const void* sourceMem, void* destinationMem)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
const AH* source = reinterpret_cast<const AH*>(sourceMem);
......@@ -114,7 +133,7 @@ static void UnknownAHShallowCopy(const void* sourceMem, void* destinationMem)
}
template <typename T, typename S>
static std::vector<vtkm::cont::internal::Buffer>
VTKM_FORCE_USED static std::vector<vtkm::cont::internal::Buffer>
UnknownAHExtractComponent(void* mem, vtkm::IdComponent componentIndex, vtkm::CopyFlag allowCopy)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
......@@ -125,7 +144,7 @@ UnknownAHExtractComponent(void* mem, vtkm::IdComponent componentIndex, vtkm::Cop
}
template <typename T, typename S>
static void UnknownAHReleaseResources(void* mem)
VTKM_FORCE_USED static void UnknownAHReleaseResources(void* mem)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
......@@ -133,7 +152,7 @@ static void UnknownAHReleaseResources(void* mem)
}
template <typename T, typename S>
static void UnknownAHReleaseResourcesExecution(void* mem)
VTKM_FORCE_USED static void UnknownAHReleaseResourcesExecution(void* mem)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
......@@ -141,7 +160,7 @@ static void UnknownAHReleaseResourcesExecution(void* mem)
}
template <typename T, typename S>
static void UnknownAHPrintSummary(void* mem, std::ostream& out, bool full)
VTKM_FORCE_USED static void UnknownAHPrintSummary(void* mem, std::ostream& out, bool full)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
......@@ -281,60 +300,47 @@ private:
};
template <typename T>
static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(vtkm::VecTraitsTagSizeStatic)
VTKM_FORCE_USED static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(
vtkm::VecTraitsTagSizeStatic)
{
return UnknownAHContainer::Make(vtkm::cont::ArrayHandleBasic<T>{});
}
template <typename T>
static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(vtkm::VecTraitsTagSizeVariable)
VTKM_FORCE_USED static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(
vtkm::VecTraitsTagSizeVariable)
{
throw vtkm::cont::ErrorBadType("Cannot create a basic array container from with ValueType of " +
vtkm::cont::TypeToString<T>());
}
template <typename T>
static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic()
VTKM_FORCE_USED static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic()
{
return UnknownAHNewInstanceBasic<T>(typename vtkm::VecTraits<T>::IsSizeStatic{});
}
template <typename T>
static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(
VTKM_FORCE_USED static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(
vtkm::VecTraitsTagSizeStatic)
{
using FloatT = typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<vtkm::FloatDefault>;
return UnknownAHContainer::Make(vtkm::cont::ArrayHandleBasic<FloatT>{});
}
template <typename T>
static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(
VTKM_FORCE_USED static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(
vtkm::VecTraitsTagSizeVariable)
{
throw vtkm::cont::ErrorBadType("Cannot create a basic array container from with ValueType of " +
vtkm::cont::TypeToString<T>());
}
template <typename T>
static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic()
VTKM_FORCE_USED static std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic()
{
return UnknownAHNewInstanceFloatBasic<T>(typename vtkm::VecTraits<T>::IsSizeStatic{});
}
template <typename T, typename S>
#ifdef VTKM_GCC
// On rare occasion, we have seen errors like this:
// `_ZN4vtkm4cont6detailL27UnknownAHNumberOfComponentsIxEEiv' referenced in section
// `.data.rel.ro.local' of CMakeFiles/UnitTests_vtkm_cont_testing.dir/UnitTestCellSet.cxx.o:
// defined in discarded section
// `.text._ZN4vtkm4cont6detailL27UnknownAHNumberOfComponentsIxEEiv[_ZN4vtkm4cont14ArrayGetValuesINS0_15StorageTagBasicExNS0_18StorageTagCountingES2_EEvRKNS0_11ArrayHandleIxT_EERKNS4_IT0_T1_EERNS4_IS9_T2_EE]'
// of CMakeFiles/UnitTests_vtkm_cont_testing.dir/UnitTestCellSet.cxx.o
// I don't know what circumstances exactly lead up to this, but it appears that the compiler
// is being overly aggressive with removing unused symbols. In this instance, it seems to have
// removed a function actually being used. This might be a bug in the compiler (I happen to have
// seen it in gcc 8.3), or it could be caused by a link-time optimizer. The problem should be
// able to be solved by explictly saying that this templated method is being used. (I can't think
// of any circumstances where this template would be instantiated but not used.) If the compiler
// knows this is being used, it should know all the templated methods internal are also used.
__attribute__((used))
#endif
inline UnknownAHContainer::UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S>& array)
VTKM_FORCE_USED inline UnknownAHContainer::UnknownAHContainer(
const vtkm::cont::ArrayHandle<T, S>& array)
: ArrayHandlePointer(new vtkm::cont::ArrayHandle<T, S>(array))
, ValueType(typeid(T))
, StorageType(typeid(S))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment