On 06/17/2014 10:09 PM, Paolo Carlini wrote:
Hi,
On 13/06/14 12:24, mliska wrote:
The optimization is inspired by Microsoft /OPT:ICF optimization
(http://msdn.microsoft.com/en-us/library/bxwfs976.aspx) that merges COMDAT
sections with each function reside in a separate section.
In terms of C++ testcases, I'm wondering if you already double checked that the
new pass already does well on the typical examples on which, I was told, the
Microsoft optimization is known to do well, eg, code instantiating std::vector
for different pointer types, or even long and long long on x86_64-linux, things
like that.
I've just added another C++ test case:
#include <vector>
using namespace std;
static vector<vector<int> *> a;
static vector<void *> b;
int main()
{
return b.size() + a.size ();
}
where the pass identifies following equality:
Semantic equality hit:std::vector<_Tp, _Alloc>::size_type std::vector<_Tp, _Alloc>::size() const [with _Tp =
std::vector<int>*; _Alloc = std::allocator<std::vector<int>*>; std::vector<_Tp, _Alloc>::size_type = long unsigned
int]->std::vector<_Tp, _Alloc>::size_type std::vector<_Tp, _Alloc>::size() const [with _Tp = void*; _Alloc =
std::allocator<void*>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]
Semantic equality hit:static void std::_Destroy_aux<true>::__destroy(_ForwardIterator,
_ForwardIterator) [with _ForwardIterator = void**]->static void
std::_Destroy_aux<true>::__destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator
= std::vector<int>**]
Semantic equality hit:void std::_Destroy(_ForwardIterator, _ForwardIterator) [with
_ForwardIterator = void**]->void std::_Destroy(_ForwardIterator, _ForwardIterator)
[with _ForwardIterator = std::vector<int>**]
Semantic equality hit:void std::_Destroy(_ForwardIterator, _ForwardIterator, std::allocator<_T2>&) [with
_ForwardIterator = void**; _Tp = void*]->void std::_Destroy(_ForwardIterator, _ForwardIterator,
std::allocator<_T2>&) [with _ForwardIterator = std::vector<int>**; _Tp = std::vector<int>*]
Semantic equality hit:void __gnu_cxx::new_allocator<_Tp>::deallocate(__gnu_cxx::new_allocator<_Tp>::pointer,
__gnu_cxx::new_allocator<_Tp>::size_type) [with _Tp = void*; __gnu_cxx::new_allocator<_Tp>::pointer = void**;
__gnu_cxx::new_allocator<_Tp>::size_type = long unsigned int]->void
__gnu_cxx::new_allocator<_Tp>::deallocate(__gnu_cxx::new_allocator<_Tp>::pointer, __gnu_cxx::new_allocator<_Tp>::size_type) [with _Tp =
std::vector<int>*; __gnu_cxx::new_allocator<_Tp>::pointer = std::vector<int>**; __gnu_cxx::new_allocator<_Tp>::size_type = long
unsigned int]
Semantic equality hit:static void __gnu_cxx::__alloc_traits<_Alloc>::deallocate(_Alloc&, __gnu_cxx::__alloc_traits<_Alloc>::pointer,
__gnu_cxx::__alloc_traits<_Alloc>::size_type) [with _Alloc = std::allocator<void*>; __gnu_cxx::__alloc_traits<_Alloc>::pointer = void**;
__gnu_cxx::__alloc_traits<_Alloc>::size_type = long unsigned int]->static void __gnu_cxx::__alloc_traits<_Alloc>::deallocate(_Alloc&,
__gnu_cxx::__alloc_traits<_Alloc>::pointer, __gnu_cxx::__alloc_traits<_Alloc>::size_type) [with _Alloc = std::allocator<std::vector<int>*>;
__gnu_cxx::__alloc_traits<_Alloc>::pointer = std::vector<int>**; __gnu_cxx::__alloc_traits<_Alloc>::size_type = long unsigned int]
As one would expect, there is a function 'size'.
Martin
Thanks,
Paolo.