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.

Reply via email to