public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: cleanup patch
       [not found] ` <BANLkTin7PszDoBZ2yshMWuU7Bq_JGT0Xgw@mail.gmail.com>
@ 2011-06-29 20:56   ` François Dumont
  0 siblings, 0 replies; 4+ messages in thread
From: François Dumont @ 2011-06-29 20:56 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1033 bytes --]

Attached patch applied

2011-06-29  François Dumont <francois.cppdevs@free.fr>

         * include/debug/set.h, unordered_map, multiset.h, forward_list,
         unordered_set, vector, deque, string, list, multimap.h: Remove base
         class default constructor calls.
         * include/debug/map.h: Likewise and cleanup several redefinition of
         base iterator typedef.

Regards

On 06/29/2011 10:34 AM, Jonathan Wakely wrote:
> On 28 June 2011 21:36, François Dumont wrote:
>> Here is a small patch to cleanup debug code.
>>
>> 2011-06-28  François Dumont<francois.cppdevs@free.fr>
>>
>>         * include/debug/set.h, unordered_map, multiset.h, forward_list,
>>         unordered_set, vector, deque, string, list, multimap.h: Remove base
>>         class default constructor calls.
>>         * include/debug/map.h: Likewise and cleanup several redefinition of
>>         base iterator typedef.
>>
>>
>> Tested under linux x86_64.
> (Remember to CC gcc-patches for all patches)
>
> This is OK to check in, thanks.
>


[-- Attachment #2: cleanup.patch --]
[-- Type: text/x-patch, Size: 17606 bytes --]

Index: include/debug/set.h
===================================================================
--- include/debug/set.h	(revision 175553)
+++ include/debug/set.h	(working copy)
@@ -46,7 +46,6 @@
       public __gnu_debug::_Safe_sequence<set<_Key, _Compare, _Allocator> >
     {
       typedef _GLIBCXX_STD_C::set<_Key, _Compare, _Allocator> _Base;
-      typedef __gnu_debug::_Safe_sequence<set> _Safe_base;
 
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
@@ -88,21 +87,21 @@
 		__comp, __a) { }
 
       set(const set& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       set(const _Base& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       set(set&& __x)
       noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _Base(std::move(__x)), _Safe_base()
+      : _Base(std::move(__x))
       { this->_M_swap(__x); }
 
       set(initializer_list<value_type> __l,
 	  const _Compare& __comp = _Compare(),
 	  const allocator_type& __a = allocator_type())
-      : _Base(__l, __comp, __a), _Safe_base() { }
+      : _Base(__l, __comp, __a) { }
 #endif
 
       ~set() _GLIBCXX_NOEXCEPT { }
@@ -206,7 +205,6 @@
       std::pair<iterator, bool>
       insert(value_type&& __x)
       {
-	typedef typename _Base::iterator _Base_iterator;
 	std::pair<_Base_iterator, bool> __res
 	  = _Base::insert(std::move(__x));
 	return std::pair<iterator, bool>(iterator(__res.first, this),
Index: include/debug/unordered_map
===================================================================
--- include/debug/unordered_map	(revision 175553)
+++ include/debug/unordered_map	(working copy)
@@ -89,25 +89,25 @@
 	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
 		__gnu_debug::__base(__last), __n,
-		__hf, __eql, __a), _Safe_base() { }
+		__hf, __eql, __a) { }
 
       unordered_map(const unordered_map& __x) 
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       unordered_map(const _Base& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       unordered_map(unordered_map&& __x)
       noexcept(__and_<is_nothrow_copy_constructible<_Hash>,
 	              is_nothrow_copy_constructible<_Pred>>::value)
-      : _Base(std::move(__x)), _Safe_base() { }
+      : _Base(std::move(__x)) { }
 
       unordered_map(initializer_list<value_type> __l,
 		    size_type __n = 0,
 		    const hasher& __hf = hasher(),
 		    const key_equal& __eql = key_equal(),
 		    const allocator_type& __a = allocator_type())
-      : _Base(__l, __n, __hf, __eql, __a), _Safe_base() { }
+      : _Base(__l, __n, __hf, __eql, __a) { }
 
       ~unordered_map() noexcept { }
 
@@ -381,25 +381,25 @@
 	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
 		__gnu_debug::__base(__last), __n,
-		__hf, __eql, __a), _Safe_base() { }
+		__hf, __eql, __a) { }
 
       unordered_multimap(const unordered_multimap& __x) 
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       unordered_multimap(const _Base& __x) 
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       unordered_multimap(unordered_multimap&& __x)
       noexcept(__and_<is_nothrow_copy_constructible<_Hash>,
 	              is_nothrow_copy_constructible<_Pred>>::value)
-      : _Base(std::move(__x)), _Safe_base() { }
+      : _Base(std::move(__x)) { }
 
       unordered_multimap(initializer_list<value_type> __l,
 			 size_type __n = 0,
 			 const hasher& __hf = hasher(),
 			 const key_equal& __eql = key_equal(),
 			 const allocator_type& __a = allocator_type())
-      : _Base(__l, __n, __hf, __eql, __a), _Safe_base() { }
+      : _Base(__l, __n, __hf, __eql, __a) { }
 
       ~unordered_multimap() noexcept { }
 
Index: include/debug/multiset.h
===================================================================
--- include/debug/multiset.h	(revision 175553)
+++ include/debug/multiset.h	(working copy)
@@ -46,7 +46,6 @@
       public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> >
     {
       typedef _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator> _Base;
-      typedef __gnu_debug::_Safe_sequence<multiset> _Safe_base;
 
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
@@ -88,21 +87,21 @@
 		__comp, __a) { }
 
       multiset(const multiset& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       multiset(const _Base& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       multiset(multiset&& __x)
       noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _Base(std::move(__x)), _Safe_base()
+      : _Base(std::move(__x))
       { this->_M_swap(__x); }
 
       multiset(initializer_list<value_type> __l,
 	       const _Compare& __comp = _Compare(),
 	       const allocator_type& __a = allocator_type())
-      : _Base(__l, __comp, __a), _Safe_base() { }
+      : _Base(__l, __comp, __a) { }
 #endif
 
       ~multiset() _GLIBCXX_NOEXCEPT { }
Index: include/debug/forward_list
===================================================================
--- include/debug/forward_list	(revision 175553)
+++ include/debug/forward_list	(working copy)
@@ -46,7 +46,6 @@
       public __gnu_debug::_Safe_sequence<forward_list<_Tp, _Alloc> >
     {
       typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base;
-      typedef __gnu_debug::_Safe_sequence<forward_list> _Safe_base;
 
       typedef typename _Base::iterator       _Base_iterator;
       typedef typename _Base::const_iterator _Base_const_iterator;
Index: include/debug/vector
===================================================================
--- include/debug/vector	(revision 175553)
+++ include/debug/vector	(working copy)
@@ -47,7 +47,6 @@
       public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> >
     {
       typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;
-      typedef __gnu_debug::_Safe_sequence<vector>              _Safe_base;
 
       typedef typename _Base::iterator _Base_iterator;
       typedef typename _Base::const_iterator _Base_const_iterator;
@@ -102,15 +101,15 @@
         { _M_update_guaranteed_capacity(); }
 
       vector(const vector& __x)
-      : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
+      : _Base(__x), _M_guaranteed_capacity(__x.size()) { }
 
       /// Construction from a release-mode vector
       vector(const _Base& __x)
-      : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
+      : _Base(__x), _M_guaranteed_capacity(__x.size()) { }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       vector(vector&& __x) noexcept
-      : _Base(std::move(__x)), _Safe_base(),
+      : _Base(std::move(__x)),
 	_M_guaranteed_capacity(this->size())
       {
 	this->_M_swap(__x);
@@ -119,7 +118,7 @@
 
       vector(initializer_list<value_type> __l,
 	     const allocator_type& __a = allocator_type())
-      : _Base(__l, __a), _Safe_base(),
+      : _Base(__l, __a),
 	_M_guaranteed_capacity(__l.size()) { }
 #endif
 
Index: include/debug/unordered_set
===================================================================
--- include/debug/unordered_set	(revision 175553)
+++ include/debug/unordered_set	(working copy)
@@ -89,25 +89,25 @@
 	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
 		__gnu_debug::__base(__last), __n,
-		__hf, __eql, __a), _Safe_base() { }
+		__hf, __eql, __a) { }
 
       unordered_set(const unordered_set& __x) 
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       unordered_set(const _Base& __x) 
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       unordered_set(unordered_set&& __x)
       noexcept(__and_<is_nothrow_copy_constructible<_Hash>,
 	              is_nothrow_copy_constructible<_Pred>>::value)
-      : _Base(std::move(__x)), _Safe_base() { }
+      : _Base(std::move(__x)) { }
 
       unordered_set(initializer_list<value_type> __l,
 		    size_type __n = 0,
 		    const hasher& __hf = hasher(),
 		    const key_equal& __eql = key_equal(),
 		    const allocator_type& __a = allocator_type())
-      : _Base(__l, __n, __hf, __eql, __a), _Safe_base() { }
+      : _Base(__l, __n, __hf, __eql, __a) { }
 
       ~unordered_set() noexcept { }
 
@@ -370,25 +370,25 @@
 	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
 		__gnu_debug::__base(__last), __n,
-		__hf, __eql, __a), _Safe_base() { }
+		__hf, __eql, __a) { }
 
       unordered_multiset(const unordered_multiset& __x) 
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       unordered_multiset(const _Base& __x) 
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       unordered_multiset(unordered_multiset&& __x)
       noexcept(__and_<is_nothrow_copy_constructible<_Hash>,
 	              is_nothrow_copy_constructible<_Pred>>::value)
-      : _Base(std::move(__x)), _Safe_base() { }
+      : _Base(std::move(__x)) { }
 
       unordered_multiset(initializer_list<value_type> __l,
 			 size_type __n = 0,
 			 const hasher& __hf = hasher(),
 			 const key_equal& __eql = key_equal(),
 			 const allocator_type& __a = allocator_type())
-      : _Base(__l, __n, __hf, __eql, __a), _Safe_base() { }
+      : _Base(__l, __n, __hf, __eql, __a) { }
 
       ~unordered_multiset() noexcept { }
 
Index: include/debug/map.h
===================================================================
--- include/debug/map.h	(revision 175553)
+++ include/debug/map.h	(working copy)
@@ -46,7 +46,6 @@
       public __gnu_debug::_Safe_sequence<map<_Key, _Tp, _Compare, _Allocator> >
     {
       typedef _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator> _Base;
-      typedef __gnu_debug::_Safe_sequence<map> _Safe_base;
 
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
@@ -61,9 +60,9 @@
       typedef typename _Base::reference             reference;
       typedef typename _Base::const_reference       const_reference;
 
-      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, map>
+      typedef __gnu_debug::_Safe_iterator<_Base_iterator, map>
                                                     iterator;
-      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, map>
+      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, map>
                                                     const_iterator;
 
       typedef typename _Base::size_type             size_type;
@@ -85,24 +84,24 @@
 	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
 		__gnu_debug::__base(__last),
-		__comp, __a), _Safe_base() { }
+		__comp, __a) { }
 
       map(const map& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       map(const _Base& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       map(map&& __x)
       noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _Base(std::move(__x)), _Safe_base()
+      : _Base(std::move(__x))
       { this->_M_swap(__x); }
 
       map(initializer_list<value_type> __l,
 	  const _Compare& __c = _Compare(),
 	  const allocator_type& __a = allocator_type())
-      : _Base(__l, __c, __a), _Safe_base() { }
+      : _Base(__l, __c, __a) { }
 #endif
 
       ~map() _GLIBCXX_NOEXCEPT { }
@@ -206,7 +205,6 @@
       std::pair<iterator, bool>
       insert(const value_type& __x)
       {
-	typedef typename _Base::iterator _Base_iterator;
 	std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
 	return std::pair<iterator, bool>(iterator(__res.first, this),
 					 __res.second);
@@ -219,7 +217,6 @@
         std::pair<iterator, bool>
         insert(_Pair&& __x)
         {
-	  typedef typename _Base::iterator _Base_iterator;
 	  std::pair<_Base_iterator, bool> __res
 	    = _Base::insert(std::forward<_Pair>(__x));
 	  return std::pair<iterator, bool>(iterator(__res.first, this),
@@ -384,7 +381,6 @@
       std::pair<iterator,iterator>
       equal_range(const key_type& __x)
       {
-	typedef typename _Base::iterator _Base_iterator;
 	std::pair<_Base_iterator, _Base_iterator> __res =
 	_Base::equal_range(__x);
 	return std::make_pair(iterator(__res.first, this),
@@ -394,7 +390,6 @@
       std::pair<const_iterator,const_iterator>
       equal_range(const key_type& __x) const
       {
-	typedef typename _Base::const_iterator _Base_const_iterator;
 	std::pair<_Base_const_iterator, _Base_const_iterator> __res =
 	_Base::equal_range(__x);
 	return std::make_pair(const_iterator(__res.first, this),
@@ -411,7 +406,6 @@
       void
       _M_invalidate_all()
       {
-	typedef typename _Base::const_iterator _Base_const_iterator;
 	typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
 	this->_M_invalidate_if(_Not_equal(_M_base().end()));
       }
Index: include/debug/deque
===================================================================
--- include/debug/deque	(revision 175553)
+++ include/debug/deque	(working copy)
@@ -45,7 +45,6 @@
       public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
     {
       typedef  _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base;
-      typedef __gnu_debug::_Safe_sequence<deque> _Safe_base;
 
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
@@ -98,19 +97,19 @@
         { }
 
       deque(const deque& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       deque(const _Base& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       deque(deque&& __x)
-      : _Base(std::move(__x)), _Safe_base()
+      : _Base(std::move(__x))
       { this->_M_swap(__x); }
 
       deque(initializer_list<value_type> __l,
 	    const allocator_type& __a = allocator_type())
-      : _Base(__l, __a), _Safe_base() { }
+      : _Base(__l, __a) { }
 #endif
 
       ~deque() _GLIBCXX_NOEXCEPT { }
Index: include/debug/string
===================================================================
--- include/debug/string	(revision 175553)
+++ include/debug/string	(working copy)
@@ -75,12 +75,12 @@
     { }
 
     // Provides conversion from a release-mode string to a debug-mode string
-    basic_string(const _Base& __base) : _Base(__base), _Safe_base() { }
+    basic_string(const _Base& __base) : _Base(__base) { }
 
     // _GLIBCXX_RESOLVE_LIB_DEFECTS
     // 42. string ctors specify wrong default allocator
     basic_string(const basic_string& __str)
-    : _Base(__str, 0, _Base::npos, __str.get_allocator()), _Safe_base()
+    : _Base(__str, 0, _Base::npos, __str.get_allocator())
     { }
 
     // _GLIBCXX_RESOLVE_LIB_DEFECTS
Index: include/debug/list
===================================================================
--- include/debug/list	(revision 175553)
+++ include/debug/list	(working copy)
@@ -45,7 +45,6 @@
       public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
     {
       typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
-      typedef __gnu_debug::_Safe_sequence<list>  _Safe_base;
 
       typedef typename _Base::iterator       _Base_iterator;
       typedef typename _Base::const_iterator _Base_const_iterator;
@@ -100,19 +99,19 @@
 
 
       list(const list& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       list(const _Base& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       list(list&& __x) noexcept
-      : _Base(std::move(__x)), _Safe_base()
+      : _Base(std::move(__x))
       { this->_M_swap(__x); }
 
       list(initializer_list<value_type> __l,
            const allocator_type& __a = allocator_type())
-        : _Base(__l, __a), _Safe_base() { }
+        : _Base(__l, __a) { }
 #endif
 
       ~list() _GLIBCXX_NOEXCEPT { }
@@ -395,7 +394,7 @@
       insert(iterator __p, initializer_list<value_type> __l)
       {
 	__glibcxx_check_insert(__p);
-	_Base::insert(__p, __l);
+	_Base::insert(__p.base(), __l);
       }
 #endif
 
Index: include/debug/multimap.h
===================================================================
--- include/debug/multimap.h	(revision 175553)
+++ include/debug/multimap.h	(working copy)
@@ -47,7 +47,6 @@
 						  _Compare, _Allocator> >
     {
       typedef _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
-      typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base;
 
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
@@ -89,21 +88,21 @@
 	      __comp, __a) { }
 
       multimap(const multimap& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
       multimap(const _Base& __x)
-      : _Base(__x), _Safe_base() { }
+      : _Base(__x) { }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       multimap(multimap&& __x)
       noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _Base(std::move(__x)), _Safe_base()
+      : _Base(std::move(__x))
       { this->_M_swap(__x); }
 
       multimap(initializer_list<value_type> __l,
 	       const _Compare& __c = _Compare(),
 	       const allocator_type& __a = allocator_type())
-      : _Base(__l, __c, __a), _Safe_base() { }
+      : _Base(__l, __c, __a) { }
 #endif
 
       ~multimap() _GLIBCXX_NOEXCEPT { }

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Cleanup patch
  1999-01-06 17:24 ` Mark Mitchell
@ 1999-01-06 17:52   ` Jeffrey A Law
  0 siblings, 0 replies; 4+ messages in thread
From: Jeffrey A Law @ 1999-01-06 17:52 UTC (permalink / raw)
  To: mark; +Cc: egcs-patches

  In message < 199901070126.RAA11987@adsl-206-170-148-33.dsl.pacbell.net >you wri
te:
  > 
  > Jeff --
  > 
  >   It looks like special_function_p would treat a member function named
  > `alloca' as `alloca', even though it's not.  I'm not suggesting you
  > introduced this bug; it may well have been there before.  But, I
  > suggest that you bracked the assignment to may_be_alloca with the same
  > kind of logic that appears directly below it.
Good point.  I'll take a look at it.

jeff

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Cleanup patch
  1999-01-06 15:15 Cleanup patch Jeffrey A Law
@ 1999-01-06 17:24 ` Mark Mitchell
  1999-01-06 17:52   ` Jeffrey A Law
  0 siblings, 1 reply; 4+ messages in thread
From: Mark Mitchell @ 1999-01-06 17:24 UTC (permalink / raw)
  To: law; +Cc: egcs-patches

Jeff --

  It looks like special_function_p would treat a member function named
`alloca' as `alloca', even though it's not.  I'm not suggesting you
introduced this bug; it may well have been there before.  But, I
suggest that you bracked the assignment to may_be_alloca with the same
kind of logic that appears directly below it.

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Cleanup patch
@ 1999-01-06 15:15 Jeffrey A Law
  1999-01-06 17:24 ` Mark Mitchell
  0 siblings, 1 reply; 4+ messages in thread
From: Jeffrey A Law @ 1999-01-06 15:15 UTC (permalink / raw)
  To: egcs-patches

This patch breaks up parts of expand_call into some smaller, easier to
read functions.  It should not change the behavior of the compiler in
any way shape or form.


        * calls.c (special_function_p): New function broken out of
        expand_call.
        (precompute_register_parameters): Likewise.
        (store_one_arg): Likewise.
        (store_unaligned_argumetns_into_pseudos): Likewise.
        (save_fixed_argument_area): Likewise.
        (restore_fixed_argument_area): Likewise.
        (expand_call): Corresponding changes.

Index: calls.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/calls.c,v
retrieving revision 1.34
diff -c -3 -p -r1.34 calls.c
*** calls.c	1998/12/16 20:54:01	1.34
--- calls.c	1999/01/06 23:10:20
*************** static int highest_outgoing_arg_in_use;
*** 124,136 ****
  int stack_arg_under_construction;
  #endif
  
! static int calls_function	PROTO((tree, int));
! static int calls_function_1	PROTO((tree, int));
! static void emit_call_1		PROTO((rtx, tree, tree, HOST_WIDE_INT,
! 				       HOST_WIDE_INT, rtx, rtx,
! 				       int, rtx, int));
  static void store_one_arg	PROTO ((struct arg_data *, rtx, int, int,
  					int));
  \f
  /* If WHICH is 1, return 1 if EXP contains a call to the built-in function
     `alloca'.
--- 124,147 ----
  int stack_arg_under_construction;
  #endif
  
! static int calls_function	PROTO ((tree, int));
! static int calls_function_1	PROTO ((tree, int));
! static void emit_call_1		PROTO ((rtx, tree, tree, HOST_WIDE_INT,
! 				        HOST_WIDE_INT, rtx, rtx,
! 				        int, rtx, int));
! static void special_function_p	PROTO ((char *, tree, int *, int *,
! 					int *, int *));
! static void precompute_register_parameters	PROTO ((int, struct arg_data *,
! 							int *));
  static void store_one_arg	PROTO ((struct arg_data *, rtx, int, int,
  					int));
+ static void store_unaligned_arguments_into_pseudos PROTO ((struct arg_data *,
+ 							   int));
+ 
+ #if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
+ static rtx save_fixed_argument_area	PROTO ((int, rtx, int *, int *));
+ static void restore_fixed_argument_area	PROTO ((rtx, rtx, int, int));
+ #endif
  \f
  /* If WHICH is 1, return 1 if EXP contains a call to the built-in function
     `alloca'.
*************** emit_call_1 (funexp, fndecl, funtype, st
*** 475,480 ****
--- 486,823 ----
  #endif
  }
  
+ /* Determine if the function identified by NAME and FNDECL is one with
+    special properties we wish to know about.
+ 
+    For example, if the function might return more than one time (setjmp), then
+    set RETURNS_TWICE to a nonzero value.
+ 
+    Similarly set IS_LONGJMP for if the function is in the longjmp family.
+ 
+    Set IS_MALLOC for any of the standard memory allocation functions which
+    allocate from the heap.
+ 
+    Set MAY_BE_ALLOCA for any memory allocation function that might allocate
+    space from the stack such as alloca.  */
+ 
+ static void
+ special_function_p (name, fndecl, returns_twice, is_longjmp,
+ 		    is_malloc, may_be_alloca)
+      char *name;
+      tree fndecl;
+      int *returns_twice;
+      int *is_longjmp;
+      int *is_malloc;
+      int *may_be_alloca;
+ {
+   *returns_twice = 0;
+   *is_longjmp = 0;
+   *is_malloc = 0;
+   *may_be_alloca = 0;
+ 
+   /* We assume that alloca will always be called by name.  It
+      makes no sense to pass it as a pointer-to-function to
+      anything that does not understand its behavior.  */
+   *may_be_alloca
+     = (name && ((IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 6
+ 		 && name[0] == 'a'
+ 		 && ! strcmp (name, "alloca"))
+ 		|| (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 16
+ 		    && name[0] == '_'
+ 		    && ! strcmp (name, "__builtin_alloca"))));
+ 
+   if (name != 0 && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 17
+       /* Exclude functions not at the file scope, or not `extern',
+ 	 since they are not the magic functions we would otherwise
+ 	 think they are.  */
+       && DECL_CONTEXT (fndecl) == NULL_TREE && TREE_PUBLIC (fndecl))
+     {
+       char *tname = name;
+ 
+       /* Disregard prefix _, __ or __x.  */
+       if (name[0] == '_')
+ 	{
+ 	  if (name[1] == '_' && name[2] == 'x')
+ 	    tname += 3;
+ 	  else if (name[1] == '_')
+ 	    tname += 2;
+ 	  else
+ 	    tname += 1;
+ 	}
+ 
+       if (tname[0] == 's')
+ 	{
+ 	  *returns_twice
+ 	     = ((tname[1] == 'e'
+ 		 && (! strcmp (tname, "setjmp")
+ 		     || ! strcmp (tname, "setjmp_syscall")))
+ 	        || (tname[1] == 'i'
+ 		    && ! strcmp (tname, "sigsetjmp"))
+ 	        || (tname[1] == 'a'
+ 		    && ! strcmp (tname, "savectx")));
+ 	  if (tname[1] == 'i'
+ 	      && ! strcmp (tname, "siglongjmp"))
+ 	    *is_longjmp = 1;
+ 	}
+       else if ((tname[0] == 'q' && tname[1] == 's'
+ 		&& ! strcmp (tname, "qsetjmp"))
+ 	       || (tname[0] == 'v' && tname[1] == 'f'
+ 		   && ! strcmp (tname, "vfork")))
+ 	*returns_twice = 1;
+ 
+       else if (tname[0] == 'l' && tname[1] == 'o'
+ 	       && ! strcmp (tname, "longjmp"))
+ 	*is_longjmp = 1;
+       /* XXX should have "malloc" attribute on functions instead
+ 	 of recognizing them by name.  */
+       else if (! strcmp (tname, "malloc")
+ 	       || ! strcmp (tname, "calloc")
+ 	       || ! strcmp (tname, "realloc")
+ 	       /* Note use of NAME rather than TNAME here.  These functions
+ 		  are only reserved when preceded with __.  */
+ 	       || ! strcmp (name, "__vn")	/* mangled __builtin_vec_new */
+ 	       || ! strcmp (name, "__nw")	/* mangled __builtin_new */
+ 	       || ! strcmp (name, "__builtin_new")
+ 	       || ! strcmp (name, "__builtin_vec_new"))
+ 	*is_malloc = 1;
+     }
+ }
+ 
+ /* Precompute all register parameters as described by ARGS, storing values
+    into fields within the ARGS array.
+ 
+    NUM_ACTUALS indicates the total number elements in the ARGS array.
+ 
+    Set REG_PARM_SEEN if we encounter a register parameter.  */
+ 
+ static void
+ precompute_register_parameters (num_actuals, args, reg_parm_seen)
+      int num_actuals;
+      struct arg_data *args;
+      int *reg_parm_seen;
+ {
+   int i;
+ 
+   *reg_parm_seen = 0;
+ 
+   for (i = 0; i < num_actuals; i++)
+     if (args[i].reg != 0 && ! args[i].pass_on_stack)
+       {
+ 	*reg_parm_seen = 1;
+ 
+ 	if (args[i].value == 0)
+ 	  {
+ 	    push_temp_slots ();
+ 	    args[i].value = expand_expr (args[i].tree_value, NULL_RTX,
+ 					 VOIDmode, 0);
+ 	    preserve_temp_slots (args[i].value);
+ 	    pop_temp_slots ();
+ 
+ 	    /* ANSI doesn't require a sequence point here,
+ 	       but PCC has one, so this will avoid some problems.  */
+ 	    emit_queue ();
+ 	  }
+ 
+ 	/* If we are to promote the function arg to a wider mode,
+ 	   do it now.  */
+ 
+ 	if (args[i].mode != TYPE_MODE (TREE_TYPE (args[i].tree_value)))
+ 	  args[i].value
+ 	    = convert_modes (args[i].mode,
+ 			     TYPE_MODE (TREE_TYPE (args[i].tree_value)),
+ 			     args[i].value, args[i].unsignedp);
+ 
+ 	/* If the value is expensive, and we are inside an appropriately 
+ 	   short loop, put the value into a pseudo and then put the pseudo
+ 	   into the hard reg.
+ 
+ 	   For small register classes, also do this if this call uses
+ 	   register parameters.  This is to avoid reload conflicts while
+ 	   loading the parameters registers.  */
+ 
+ 	if ((! (GET_CODE (args[i].value) == REG
+ 		|| (GET_CODE (args[i].value) == SUBREG
+ 		    && GET_CODE (SUBREG_REG (args[i].value)) == REG)))
+ 	    && args[i].mode != BLKmode
+ 	    && rtx_cost (args[i].value, SET) > 2
+ 	    && ((SMALL_REGISTER_CLASSES && *reg_parm_seen)
+ 		|| preserve_subexpressions_p ()))
+ 	  args[i].value = copy_to_mode_reg (args[i].mode, args[i].value);
+       }
+ }
+ 
+ #if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
+ 
+   /* The argument list is the property of the called routine and it
+      may clobber it.  If the fixed area has been used for previous
+      parameters, we must save and restore it.  */
+ static rtx
+ save_fixed_argument_area (reg_parm_stack_space, argblock,
+ 			  low_to_save, high_to_save)
+      int reg_parm_stack_space;
+      rtx argblock;
+      int *low_to_save;
+      int *high_to_save;
+ {
+   int i;
+   rtx save_area = NULL_RTX;
+ 
+   /* Compute the boundary of the that needs to be saved, if any.  */
+ #ifdef ARGS_GROW_DOWNWARD
+   for (i = 0; i < reg_parm_stack_space + 1; i++)
+ #else
+   for (i = 0; i < reg_parm_stack_space; i++)
+ #endif
+     {
+       if (i >= highest_outgoing_arg_in_use
+ 	  || stack_usage_map[i] == 0)
+ 	continue;
+ 
+       if (*low_to_save == -1)
+ 	*low_to_save = i;
+ 
+       *high_to_save = i;
+     }
+ 
+   if (*low_to_save >= 0)
+     {
+       int num_to_save = *high_to_save - *low_to_save + 1;
+       enum machine_mode save_mode
+ 	= mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1);
+       rtx stack_area;
+ 
+       /* If we don't have the required alignment, must do this in BLKmode.  */
+       if ((*low_to_save & (MIN (GET_MODE_SIZE (save_mode),
+ 			        BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1)))
+ 	save_mode = BLKmode;
+ 
+ #ifdef ARGS_GROW_DOWNWARD
+       stack_area = gen_rtx_MEM (save_mode,
+ 				memory_address (save_mode,
+ 						plus_constant (argblock,
+ 							       - *high_to_save)));
+ #else
+       stack_area = gen_rtx_MEM (save_mode,
+ 				memory_address (save_mode,
+ 						plus_constant (argblock,
+ 							       *low_to_save)));
+ #endif
+       if (save_mode == BLKmode)
+ 	{
+ 	  save_area = assign_stack_temp (BLKmode, num_to_save, 0);
+ 	  MEM_IN_STRUCT_P (save_area) = 0;
+ 	  emit_block_move (validize_mem (save_area), stack_area,
+ 			   GEN_INT (num_to_save),
+ 			   PARM_BOUNDARY / BITS_PER_UNIT);
+ 	}
+       else
+ 	{
+ 	  save_area = gen_reg_rtx (save_mode);
+ 	  emit_move_insn (save_area, stack_area);
+ 	}
+     }
+   return save_area;
+ }
+ 
+ static void
+ restore_fixed_argument_area (save_area, argblock, high_to_save, low_to_save)
+      rtx save_area;
+      rtx argblock;
+      int high_to_save;
+      int low_to_save;
+ {
+   enum machine_mode save_mode = GET_MODE (save_area);
+ #ifdef ARGS_GROW_DOWNWARD
+   rtx stack_area
+     = gen_rtx_MEM (save_mode,
+ 		   memory_address (save_mode,
+ 				   plus_constant (argblock,
+ 						  - high_to_save)));
+ #else
+   rtx stack_area
+     = gen_rtx_MEM (save_mode,
+ 		   memory_address (save_mode,
+ 				   plus_constant (argblock,
+ 						  low_to_save)));
+ #endif
+ 
+   if (save_mode != BLKmode)
+     emit_move_insn (stack_area, save_area);
+   else
+     emit_block_move (stack_area, validize_mem (save_area),
+ 		     GEN_INT (high_to_save - low_to_save + 1),
+ 		     PARM_BOUNDARY / BITS_PER_UNIT);
+ }
+ #endif
+ 	  
+ /* If any elements in ARGS refer to parameters that are to be passed in
+    registers, but not in memory, and whose alignment does not permit a
+    direct copy into registers.  Copy the values into a group of pseudos
+    which we will later copy into the appropriate hard registers.  */
+ static void
+ store_unaligned_arguments_into_pseudos (args, num_actuals)
+      struct arg_data *args;
+      int num_actuals;
+ {
+   int i, j;
+      
+   for (i = 0; i < num_actuals; i++)
+     if (args[i].reg != 0 && ! args[i].pass_on_stack
+ 	&& args[i].mode == BLKmode
+ 	&& (TYPE_ALIGN (TREE_TYPE (args[i].tree_value))
+ 	    < (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
+       {
+ 	int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
+ 	int big_endian_correction = 0;
+ 
+ 	args[i].n_aligned_regs
+ 	  = args[i].partial ? args[i].partial
+ 	    : (bytes + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+ 
+ 	args[i].aligned_regs = (rtx *) alloca (sizeof (rtx)
+ 					       * args[i].n_aligned_regs);
+ 
+ 	/* Structures smaller than a word are aligned to the least
+ 	   significant byte (to the right).  On a BYTES_BIG_ENDIAN machine,
+ 	   this means we must skip the empty high order bytes when
+ 	   calculating the bit offset.  */
+ 	if (BYTES_BIG_ENDIAN && bytes < UNITS_PER_WORD)
+ 	  big_endian_correction = (BITS_PER_WORD  - (bytes * BITS_PER_UNIT));
+ 
+ 	for (j = 0; j < args[i].n_aligned_regs; j++)
+ 	  {
+ 	    rtx reg = gen_reg_rtx (word_mode);
+ 	    rtx word = operand_subword_force (args[i].value, j, BLKmode);
+ 	    int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
+ 	    int bitalign = TYPE_ALIGN (TREE_TYPE (args[i].tree_value));
+ 
+ 	    args[i].aligned_regs[j] = reg;
+ 
+ 	    /* There is no need to restrict this code to loading items
+ 	       in TYPE_ALIGN sized hunks.  The bitfield instructions can
+ 	       load up entire word sized registers efficiently.
+ 
+ 	       ??? This may not be needed anymore.
+ 	       We use to emit a clobber here but that doesn't let later
+ 	       passes optimize the instructions we emit.  By storing 0 into
+ 	       the register later passes know the first AND to zero out the
+ 	       bitfield being set in the register is unnecessary.  The store
+ 	       of 0 will be deleted as will at least the first AND.  */
+ 
+ 	    emit_move_insn (reg, const0_rtx);
+ 
+ 	    bytes -= bitsize / BITS_PER_UNIT;
+ 	    store_bit_field (reg, bitsize, big_endian_correction, word_mode,
+ 			     extract_bit_field (word, bitsize, 0, 1,
+ 						NULL_RTX, word_mode,
+ 						word_mode,
+ 						bitalign / BITS_PER_UNIT,
+ 						BITS_PER_WORD),
+ 			     bitalign / BITS_PER_UNIT, BITS_PER_WORD);
+ 	  }
+       }
+ }
+ 
  /* Generate all the code for a function call
     and return an rtx for its value.
     Store the value in TARGET (specified as an rtx) if convenient.
*************** expand_call (exp, target, ignore)
*** 827,916 ****
    if (fndecl && DECL_NAME (fndecl))
      name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
  
- #if 0
-   /* Unless it's a call to a specific function that isn't alloca,
-      if it has one argument, we must assume it might be alloca.  */
- 
-   may_be_alloca
-     = (!(fndecl != 0 && strcmp (name, "alloca"))
-        && actparms != 0
-        && TREE_CHAIN (actparms) == 0);
- #else
-   /* We assume that alloca will always be called by name.  It
-      makes no sense to pass it as a pointer-to-function to
-      anything that does not understand its behavior.  */
-   may_be_alloca
-     = (name && ((IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 6
- 		 && name[0] == 'a'
- 		 && ! strcmp (name, "alloca"))
- 		|| (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 16
- 		    && name[0] == '_'
- 		    && ! strcmp (name, "__builtin_alloca"))));
- #endif
- 
    /* See if this is a call to a function that can return more than once
!      or a call to longjmp.  */
! 
!   returns_twice = 0;
!   is_longjmp = 0;
!   is_malloc = 0;
! 
!   if (name != 0 && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 17
!       /* Exclude functions not at the file scope, or not `extern',
! 	 since they are not the magic functions we would otherwise
! 	 think they are.  */
!       && DECL_CONTEXT (fndecl) == NULL_TREE && TREE_PUBLIC (fndecl))
!     {
!       char *tname = name;
  
-       /* Disregard prefix _, __ or __x.  */
-       if (name[0] == '_')
- 	{
- 	  if (name[1] == '_' && name[2] == 'x')
- 	    tname += 3;
- 	  else if (name[1] == '_')
- 	    tname += 2;
- 	  else
- 	    tname += 1;
- 	}
- 
-       if (tname[0] == 's')
- 	{
- 	  returns_twice
- 	    = ((tname[1] == 'e'
- 		&& (! strcmp (tname, "setjmp")
- 		    || ! strcmp (tname, "setjmp_syscall")))
- 	       || (tname[1] == 'i'
- 		   && ! strcmp (tname, "sigsetjmp"))
- 	       || (tname[1] == 'a'
- 		   && ! strcmp (tname, "savectx")));
- 	  if (tname[1] == 'i'
- 	      && ! strcmp (tname, "siglongjmp"))
- 	    is_longjmp = 1;
- 	}
-       else if ((tname[0] == 'q' && tname[1] == 's'
- 		&& ! strcmp (tname, "qsetjmp"))
- 	       || (tname[0] == 'v' && tname[1] == 'f'
- 		   && ! strcmp (tname, "vfork")))
- 	returns_twice = 1;
- 
-       else if (tname[0] == 'l' && tname[1] == 'o'
- 	       && ! strcmp (tname, "longjmp"))
- 	is_longjmp = 1;
-       /* XXX should have "malloc" attribute on functions instead
- 	 of recognizing them by name.  */
-       else if (! strcmp (tname, "malloc")
- 	       || ! strcmp (tname, "calloc")
- 	       || ! strcmp (tname, "realloc")
- 	       /* Note use of NAME rather than TNAME here.  These functions
- 		  are only reserved when preceded with __.  */
- 	       || ! strcmp (name, "__vn")	/* mangled __builtin_vec_new */
- 	       || ! strcmp (name, "__nw")	/* mangled __builtin_new */
- 	       || ! strcmp (name, "__builtin_new")
- 	       || ! strcmp (name, "__builtin_vec_new"))
- 	is_malloc = 1;
-     }
- 
    if (may_be_alloca)
      current_function_calls_alloca = 1;
  
--- 1170,1180 ----
    if (fndecl && DECL_NAME (fndecl))
      name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
  
    /* See if this is a call to a function that can return more than once
!      or a call to longjmp or malloc.  */
!   special_function_p (name, fndecl, &returns_twice, &is_longjmp,
! 		      &is_malloc, &may_be_alloca);
  
    if (may_be_alloca)
      current_function_calls_alloca = 1;
  
*************** expand_call (exp, target, ignore)
*** 1650,1764 ****
  
    /* Precompute all register parameters.  It isn't safe to compute anything
       once we have started filling any specific hard regs.  */
!   reg_parm_seen = 0;
!   for (i = 0; i < num_actuals; i++)
!     if (args[i].reg != 0 && ! args[i].pass_on_stack)
!       {
! 	reg_parm_seen = 1;
! 
! 	if (args[i].value == 0)
! 	  {
! 	    push_temp_slots ();
! 	    args[i].value = expand_expr (args[i].tree_value, NULL_RTX,
! 					 VOIDmode, 0);
! 	    preserve_temp_slots (args[i].value);
! 	    pop_temp_slots ();
  
- 	    /* ANSI doesn't require a sequence point here,
- 	       but PCC has one, so this will avoid some problems.  */
- 	    emit_queue ();
- 	  }
- 
- 	/* If we are to promote the function arg to a wider mode,
- 	   do it now.  */
- 
- 	if (args[i].mode != TYPE_MODE (TREE_TYPE (args[i].tree_value)))
- 	  args[i].value
- 	    = convert_modes (args[i].mode,
- 			     TYPE_MODE (TREE_TYPE (args[i].tree_value)),
- 			     args[i].value, args[i].unsignedp);
- 
- 	/* If the value is expensive, and we are inside an appropriately 
- 	   short loop, put the value into a pseudo and then put the pseudo
- 	   into the hard reg.
- 
- 	   For small register classes, also do this if this call uses
- 	   register parameters.  This is to avoid reload conflicts while
- 	   loading the parameters registers.  */
- 
- 	if ((! (GET_CODE (args[i].value) == REG
- 		|| (GET_CODE (args[i].value) == SUBREG
- 		    && GET_CODE (SUBREG_REG (args[i].value)) == REG)))
- 	    && args[i].mode != BLKmode
- 	    && rtx_cost (args[i].value, SET) > 2
- 	    && ((SMALL_REGISTER_CLASSES && reg_parm_seen)
- 		|| preserve_subexpressions_p ()))
- 	  args[i].value = copy_to_mode_reg (args[i].mode, args[i].value);
-       }
- 
  #if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
- 
-   /* The argument list is the property of the called routine and it
-      may clobber it.  If the fixed area has been used for previous
-      parameters, we must save and restore it.
- 
-      Here we compute the boundary of the that needs to be saved, if any.  */
- 
- #ifdef ARGS_GROW_DOWNWARD
-   for (i = 0; i < reg_parm_stack_space + 1; i++)
- #else
-   for (i = 0; i < reg_parm_stack_space; i++)
- #endif
-     {
-       if (i >=  highest_outgoing_arg_in_use
- 	  || stack_usage_map[i] == 0)
- 	continue;
- 
-       if (low_to_save == -1)
- 	low_to_save = i;
- 
-       high_to_save = i;
-     }
- 
-   if (low_to_save >= 0)
-     {
-       int num_to_save = high_to_save - low_to_save + 1;
-       enum machine_mode save_mode
- 	= mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1);
-       rtx stack_area;
- 
-       /* If we don't have the required alignment, must do this in BLKmode.  */
-       if ((low_to_save & (MIN (GET_MODE_SIZE (save_mode),
- 			       BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1)))
- 	save_mode = BLKmode;
  
! #ifdef ARGS_GROW_DOWNWARD
!       stack_area = gen_rtx_MEM (save_mode,
! 				memory_address (save_mode,
! 						plus_constant (argblock,
! 							       - high_to_save)));
! #else
!       stack_area = gen_rtx_MEM (save_mode,
! 				memory_address (save_mode,
! 						plus_constant (argblock,
! 							       low_to_save)));
! #endif
!       if (save_mode == BLKmode)
! 	{
! 	  save_area = assign_stack_temp (BLKmode, num_to_save, 0);
! 	  MEM_IN_STRUCT_P (save_area) = 0;
! 	  emit_block_move (validize_mem (save_area), stack_area,
! 			   GEN_INT (num_to_save),
! 			   PARM_BOUNDARY / BITS_PER_UNIT);
! 	}
!       else
! 	{
! 	  save_area = gen_reg_rtx (save_mode);
! 	  emit_move_insn (save_area, stack_area);
! 	}
!     }
  #endif
! 	  
  
    /* Now store (and compute if necessary) all non-register parms.
       These come before register parms, since they can require block-moves,
--- 1914,1929 ----
  
    /* Precompute all register parameters.  It isn't safe to compute anything
       once we have started filling any specific hard regs.  */
!   precompute_register_parameters (num_actuals, args, &reg_parm_seen);
  
  #if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
  
!   /* Save the fixed argument area if it's part of the caller's frame and
!      is clobbered by argument setup for this call.  */
!   save_area = save_fixed_argument_area (reg_parm_stack_space, argblock,
! 					&low_to_save, &high_to_save);
  #endif
! 			
  
    /* Now store (and compute if necessary) all non-register parms.
       These come before register parms, since they can require block-moves,
*************** expand_call (exp, target, ignore)
*** 1775,1838 ****
       and whose alignment does not permit a direct copy into registers,
       make a group of pseudos that correspond to each register that we
       will later fill.  */
- 
    if (STRICT_ALIGNMENT)
!     for (i = 0; i < num_actuals; i++)
!       if (args[i].reg != 0 && ! args[i].pass_on_stack
! 	&& args[i].mode == BLKmode
! 	  && (TYPE_ALIGN (TREE_TYPE (args[i].tree_value))
! 	      < (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
! 	{
! 	  int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
! 	  int big_endian_correction = 0;
! 
! 	  args[i].n_aligned_regs
! 	    = args[i].partial ? args[i].partial
! 	      : (bytes + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
! 
! 	  args[i].aligned_regs = (rtx *) alloca (sizeof (rtx)
! 						 * args[i].n_aligned_regs);
! 
! 	  /* Structures smaller than a word are aligned to the least
! 	     significant byte (to the right).  On a BYTES_BIG_ENDIAN machine,
! 	     this means we must skip the empty high order bytes when
! 	     calculating the bit offset.  */
! 	  if (BYTES_BIG_ENDIAN && bytes < UNITS_PER_WORD)
! 	    big_endian_correction = (BITS_PER_WORD  - (bytes * BITS_PER_UNIT));
  
- 	  for (j = 0; j < args[i].n_aligned_regs; j++)
- 	    {
- 	      rtx reg = gen_reg_rtx (word_mode);
- 	      rtx word = operand_subword_force (args[i].value, j, BLKmode);
- 	      int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
- 	      int bitalign = TYPE_ALIGN (TREE_TYPE (args[i].tree_value));
- 
- 	      args[i].aligned_regs[j] = reg;
- 
- 	      /* There is no need to restrict this code to loading items
- 		 in TYPE_ALIGN sized hunks.  The bitfield instructions can
- 		 load up entire word sized registers efficiently.
- 
- 		 ??? This may not be needed anymore.
- 		 We use to emit a clobber here but that doesn't let later
- 		 passes optimize the instructions we emit.  By storing 0 into
- 		 the register later passes know the first AND to zero out the
- 		 bitfield being set in the register is unnecessary.  The store
- 		 of 0 will be deleted as will at least the first AND.  */
- 
- 	      emit_move_insn (reg, const0_rtx);
- 
- 	      bytes -= bitsize / BITS_PER_UNIT;
- 	      store_bit_field (reg, bitsize, big_endian_correction, word_mode,
- 			       extract_bit_field (word, bitsize, 0, 1,
- 						  NULL_RTX, word_mode,
- 						  word_mode,
- 						  bitalign / BITS_PER_UNIT,
- 						  BITS_PER_WORD),
- 			       bitalign / BITS_PER_UNIT, BITS_PER_WORD);
- 	    }
- 	}
- 
    /* Now store any partially-in-registers parm.
       This is the last place a block-move can happen.  */
    if (reg_parm_seen)
--- 1940,1948 ----
       and whose alignment does not permit a direct copy into registers,
       make a group of pseudos that correspond to each register that we
       will later fill.  */
    if (STRICT_ALIGNMENT)
!     store_unaligned_arguments_into_pseudos (args, num_actuals);
  
    /* Now store any partially-in-registers parm.
       This is the last place a block-move can happen.  */
    if (reg_parm_seen)
*************** expand_call (exp, target, ignore)
*** 2152,2182 ****
      {
  #ifdef REG_PARM_STACK_SPACE
        if (save_area)
! 	{
! 	  enum machine_mode save_mode = GET_MODE (save_area);
! #ifdef ARGS_GROW_DOWNWARD
! 	  rtx stack_area
! 	    = gen_rtx_MEM (save_mode,
! 			   memory_address (save_mode,
! 					   plus_constant (argblock,
! 							  - high_to_save)));
! #else
! 	  rtx stack_area
! 	    = gen_rtx_MEM (save_mode,
! 			   memory_address (save_mode,
! 					   plus_constant (argblock,
! 							  low_to_save)));
  #endif
  
- 	  if (save_mode != BLKmode)
- 	    emit_move_insn (stack_area, save_area);
- 	  else
- 	    emit_block_move (stack_area, validize_mem (save_area),
- 			     GEN_INT (high_to_save - low_to_save + 1),
- 			     PARM_BOUNDARY / BITS_PER_UNIT);
- 	}
- #endif
- 	  
        /* If we saved any argument areas, restore them.  */
        for (i = 0; i < num_actuals; i++)
  	if (args[i].save_area)
--- 2262,2271 ----
      {
  #ifdef REG_PARM_STACK_SPACE
        if (save_area)
! 	restore_fixed_argument_area (save_area, argblock,
! 				     high_to_save, low_to_save);
  #endif
  
        /* If we saved any argument areas, restore them.  */
        for (i = 0; i < num_actuals; i++)
  	if (args[i].save_area)


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-06-29 20:17 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <4E0A3B51.1050805@free.fr>
     [not found] ` <BANLkTin7PszDoBZ2yshMWuU7Bq_JGT0Xgw@mail.gmail.com>
2011-06-29 20:56   ` cleanup patch François Dumont
1999-01-06 15:15 Cleanup patch Jeffrey A Law
1999-01-06 17:24 ` Mark Mitchell
1999-01-06 17:52   ` Jeffrey A Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).