This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
small improvement for fill and fill_n
- From: Dan Nicolaescu <dann at godzilla dot ics dot uci dot edu>
- To: libstdc++ at gcc dot gnu dot org
- Date: Thu, 17 Jun 2004 11:41:18 -0700
- Subject: small improvement for fill and fill_n
I found this when looking at the tree dumps for the testcase in
PR8361:
_OutputIterator std::fill_n(_OutputIterator, _Size, const_Tp&) [with _OutputIterator = unsigned int
*, _Size = unsigned int, _Tp = unsigned int] (__first, __n, __value)
{
<bb 0>:
if (__n != 0) goto <L0>; else goto <L2>;
<L0>:;
*__first = *__value;
__n = __n - 1;
__first = __first + 4B;
if (__n != 0) goto <L0>; else goto <L2>;
<L2>:;
return __first;
}
Note that the memory location pointed to by __value is accessed in
each loop iteration, the compiler cannot prove that __first and
__value do not alias. One solution would be to use a temporary like
so:
2004-06-17 Dan Nicolaescu <dann@ics.uci.edu>
* include/bits/stl_algobase.h (fill, fill_n): Use a temporary to
avoid a memory read in each iteration.
*** stl_algobase.h.~1.30.~ 2004-03-02 10:46:37.000000000 -0800
--- stl_algobase.h 2004-06-17 11:32:20.000000000 -0700
***************
*** 520,527 ****
_ForwardIterator>)
__glibcxx_requires_valid_range(__first, __last);
for ( ; __first != __last; ++__first)
! *__first = __value;
}
/**
--- 520,528 ----
_ForwardIterator>)
__glibcxx_requires_valid_range(__first, __last);
+ const _Tp __tmp = __value;
for ( ; __first != __last; ++__first)
! *__first = __tmp;
}
/**
***************
*** 542,549 ****
// concept requirements
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,_Tp>)
for ( ; __n > 0; --__n, ++__first)
! *__first = __value;
return __first;
}
--- 543,551 ----
// concept requirements
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,_Tp>)
+ const _Tp __tmp = __value;
for ( ; __n > 0; --__n, ++__first)
! *__first = __tmp;
return __first;
}