https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124010
Bug ID: 124010
Summary: Reduce dependency height feeding test
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: law at gcc dot gnu.org
Target Milestone: ---
For riscv64 with -O2 -march=rv64gcbv_zicond at -O2 this code:
typedef long unsigned int size_t;
namespace std
{
typedef long unsigned int size_t;
}
namespace xalanc_1_10 {
template<bool value>
struct XalanCompileErrorBoolean
{
char foo[value];
};
}
extern "C++" {
[[__nodiscard__]] inline
void* operator new(std::size_t, void* __p)
noexcept
{ return __p; }
}
namespace xercesc_2_7 {
class MemoryManager
{
};
}
namespace xalanc_1_10 {
using xercesc_2_7 :: MemoryManager;
template <class C>
struct ConstructValueWithNoMemoryManager
{
ConstructValueWithNoMemoryManager(MemoryManager& ) :
value()
{
}
C value;
};
template <class C>
struct ConstructWithNoMemoryManager
{
typedef ConstructValueWithNoMemoryManager<C> ConstructableType;
static C* construct(C* address, const C& theRhs/*, MemoryManager& */)
{
return (C*) new (address) C(theRhs);
}
};
template <class C>
struct MemoryManagedConstructionTraits
{
typedef ConstructWithNoMemoryManager<C> Constructor;
};
}
namespace __gnu_cxx
{
namespace __ops
{
template<typename _Value>
struct _Iter_equals_val
{
_Value& _M_value;
explicit
_Iter_equals_val(_Value& __value)
: _M_value(__value)
{ }
template<typename _Iterator>
bool
operator()(_Iterator __it)
{ return *__it == _M_value; }
};
template<typename _Value>
inline _Iter_equals_val<_Value>
__iter_equals_val(_Value& __val)
{ return _Iter_equals_val<_Value>(__val); }
}
}
namespace std __attribute__ ((__visibility__ ("default")))
{
template<typename _Iterator, typename _Predicate>
inline _Iterator
__find_if(_Iterator __first, _Iterator __last, _Predicate __pred)
{
#pragma GCC unroll 4
while (__first != __last && !__pred(__first))
++__first;
return __first;
}
}
namespace std __attribute__ ((__visibility__ ("default")))
{
template<typename _InputIterator, typename _Tp>
[[__nodiscard__]]
inline _InputIterator
find(_InputIterator __first, _InputIterator __last, const _Tp& __val)
{
;
return std::__find_if(__first, __last,
__gnu_cxx::__ops::__iter_equals_val(__val));
}
template<typename _InputIterator, typename _Predicate>
[[__nodiscard__]]
inline _InputIterator
find_if(_InputIterator __first, _InputIterator __last,
_Predicate __pred) {}
}
namespace xalanc_1_10 {
using xercesc_2_7 :: MemoryManager;
template <class Type, class ConstructionTraits =
MemoryManagedConstructionTraits<Type> >
class XalanVector
{
public:
typedef Type value_type;
typedef value_type* pointer;
typedef size_t size_type;
typedef value_type* iterator;
typedef typename ConstructionTraits::Constructor Constructor;
iterator
begin()
{
return m_data;
}
iterator
end()
{
return m_data + m_size;
}
void
push_back(const value_type& data)
{
Constructor::construct(m_data + m_size, data);
}
size_type m_size;
value_type* m_data;
};
}
namespace xalanc_1_10 {
class XalanDOMString
{
};
class XalanDOMStringCache
{
public:
typedef XalanVector<XalanDOMString*> StringListType;
bool
release(XalanDOMString& theString);
StringListType m_availableList;
StringListType m_busyList;
};
}
namespace xalanc_1_10 {
bool
XalanDOMStringCache::release(XalanDOMString& theString)
{
using std :: find;
StringListType::iterator
i =
find(m_busyList.begin(),
m_busyList.end(),
&theString);
m_availableList.push_back(*i);
return true;
}
}
Produces something like this in the .optimized dump:
<bb 2> [local count: 114863530]:
_15 = MEM[(struct XalanVector *)this_1(D) + 16B].m_data;
_12 = MEM[(struct XalanVector *)this_1(D) + 16B].m_size;
_13 = _12 * 8;
_14 = _15 + _13;
if (_14 != _15)
goto <bb 4>; [94.50%]
else
goto <bb 3>; [5.50%]
We can replace _14 != _15 with _13 != 0 assuming the types allow. THe value in
_14 is used elsewhere so we still have to generate it, but it does reduce the
dependency height and allows the computation of _14 to sink.