This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[VEC patch] Implement integer type specialization
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, "H. J. Lu" <hjl at lucon dot org>
- Date: Fri, 27 May 2005 14:25:14 +0100
- Subject: [VEC patch] Implement integer type specialization
I've installed this patch to implement a DEF_VEC_I specialization. This means
you don't have to abuse DEF_VEC_P for integer types, and more to the point, you
can have vectors of enumerations.
booted & tested on i686-pc-linux-gnu.
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2005-05-27 Nathan Sidwell <nathan@codesourcery.com>
* vec.h: Implement integral type vector specialization.
(VEC_T): Define a non-GTY structure.
(VEC_T_GTY): Define a GTY structure.
(VEC_TA): Rename to ...
(VEC_TA_GTY): ... here.
(DEF_VEC_I, DEF_VEC_ALLOC_I): New.
(DEF_VEC_P, DEF_VEC_ALLOC_P): Adjust.
(DEF_VEC_FUNC_P, DEF_VEC_ALLOC_FUNC_P): New, broken out of
DEF_VEC_P and DEF_VEC_ALLOC_P.
(DEF_VEC_O, DEF_VEC_ALLOC_O): Adjust.
(DEF_VEC_FUNC_O, DEF_VEC_ALLOC_FUNC_O): New, broken out of
DEF_VEC_O and DEF_VEC_ALLOC_O.
* global.c: Use DEF_VEC_I, DEF_VEC_ALLOC_I.
* lambda-code.c: Likewise.
* tree-into-ssa.c: Likewise.
* tree-ssa-live.c: Likewise.
Index: global.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/global.c,v
retrieving revision 1.126
diff -c -3 -p -r1.126 global.c
*** global.c 1 May 2005 23:34:24 -0000 1.126
--- global.c 26 May 2005 13:52:51 -0000
*************** mark_reg_change (rtx reg, rtx setter, vo
*** 2098,2105 ****
/* Classes of registers which could be early clobbered in the current
insn. */
! DEF_VEC_P(int);
! DEF_VEC_ALLOC_P(int,heap);
static VEC(int,heap) *earlyclobber_regclass;
--- 2098,2105 ----
/* Classes of registers which could be early clobbered in the current
insn. */
! DEF_VEC_I(int);
! DEF_VEC_ALLOC_I(int,heap);
static VEC(int,heap) *earlyclobber_regclass;
Index: lambda-code.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/lambda-code.c,v
retrieving revision 2.40
diff -c -3 -p -r2.40 lambda-code.c
*** lambda-code.c 25 May 2005 14:05:22 -0000 2.40
--- lambda-code.c 26 May 2005 13:52:54 -0000
***************
*** 115,122 ****
Fourier-Motzkin elimination is used to compute the bounds of the base space
of the lattice. */
! DEF_VEC_P(int);
! DEF_VEC_ALLOC_P(int,heap);
static bool perfect_nestify (struct loops *,
struct loop *, VEC(tree,heap) *,
--- 115,122 ----
Fourier-Motzkin elimination is used to compute the bounds of the base space
of the lattice. */
! DEF_VEC_I(int);
! DEF_VEC_ALLOC_I(int,heap);
static bool perfect_nestify (struct loops *,
struct loop *, VEC(tree,heap) *,
Index: tree-into-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-into-ssa.c,v
retrieving revision 2.56
diff -c -3 -p -r2.56 tree-into-ssa.c
*** tree-into-ssa.c 25 May 2005 15:17:12 -0000 2.56
--- tree-into-ssa.c 26 May 2005 13:53:06 -0000
*************** static VEC(tree,heap) *block_defs_stack;
*** 107,114 ****
/* Basic block vectors used in this file ought to be allocated in the
heap. We use pointer vector, because ints can be easily passed by
value. */
! DEF_VEC_P(int);
! DEF_VEC_ALLOC_P(int,heap);
/* Set of existing SSA names being replaced by update_ssa. */
static sbitmap old_ssa_names;
--- 107,114 ----
/* Basic block vectors used in this file ought to be allocated in the
heap. We use pointer vector, because ints can be easily passed by
value. */
! DEF_VEC_I(int);
! DEF_VEC_ALLOC_I(int,heap);
/* Set of existing SSA names being replaced by update_ssa. */
static sbitmap old_ssa_names;
Index: tree-ssa-live.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-live.c,v
retrieving revision 2.35
diff -c -3 -p -r2.35 tree-ssa-live.c
*** tree-ssa-live.c 14 May 2005 13:05:36 -0000 2.35
--- tree-ssa-live.c 26 May 2005 13:53:09 -0000
*************** add_conflicts_if_valid (tpa_p tpa, confl
*** 1281,1288 ****
}
}
! DEF_VEC_P(int);
! DEF_VEC_ALLOC_P(int,heap);
/* Return a conflict graph for the information contained in LIVE_INFO. Only
conflicts between items in the same TPA list are added. If optional
--- 1281,1288 ----
}
}
! DEF_VEC_I(int);
! DEF_VEC_ALLOC_I(int,heap);
/* Return a conflict graph for the information contained in LIVE_INFO. Only
conflicts between items in the same TPA list are added. If optional
Index: vec.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/vec.h,v
retrieving revision 2.27
diff -c -3 -p -r2.27 vec.h
*** vec.h 28 Apr 2005 05:38:35 -0000 2.27
--- vec.h 26 May 2005 13:53:26 -0000
*************** Software Foundation, 59 Temple Place - S
*** 29,45 ****
out-of-line generic functions. The vectors are designed to
interoperate with the GTY machinery.
! Because of the different behavior of objects and of pointers to
! objects, there are two flavors. One to deal with a vector of
! pointers to objects, and one to deal with a vector of objects
! themselves. Both of these pass pointers to objects around -- in
! the former case the pointers are stored into the vector and in the
! latter case the pointers are dereferenced and the objects copied
! into the vector. Therefore, when using a vector of pointers, the
! objects pointed to must be long lived, but when dealing with a
! vector of objects, the source objects need not be. The vector of
! pointers API is also appropriate for small register sized objects
! like integers.
There are both 'index' and 'iterate' accessors. The iterator
returns a boolean iteration condition and updates the iteration
--- 29,42 ----
out-of-line generic functions. The vectors are designed to
interoperate with the GTY machinery.
! Because of the different behavior of structure objects, scalar
! objects and of pointers, there are three flavors, one for each of
! these variants. Both the structure object and pointer variants
! pass pointers to objects around -- in the former case the pointers
! are stored into the vector and in the latter case the pointers are
! dereferenced and the objects copied into the vector. The scalar
! object variant is suitable for int-like objects, and the vector
! elements are returned by value.
There are both 'index' and 'iterate' accessors. The iterator
returns a boolean iteration condition and updates the iteration
*************** Software Foundation, 59 Temple Place - S
*** 96,115 ****
the 'space' predicate will tell you whether there is spare capacity
in the vector. You will not normally need to use these two functions.
! Vector types are defined using a DEF_VEC_{O,P}(TYPEDEF) macro, to
get the non-memory allocation version, and then a
! DEF_VEC_ALLOC_{O,P}(TYPEDEF,ALLOC) macro to get memory managed
vectors. Variables of vector type are declared using a
VEC(TYPEDEF,ALLOC) macro. The ALLOC argument specifies the
allocation strategy, and can be either 'gc' or 'heap' for garbage
collected and heap allocated respectively. It can be 'none' to get
a vector that must be explicitly allocated (for instance as a
! trailing array of another structure). The characters O and P
! indicate whether TYPEDEF is a pointer (P) or object (O) type. Be
! careful to pick the correct one, as you'll get an awkward and
! inefficient API if you get the wrong one. There is a check, which
! results in a compile-time warning, for the P versions, but there is
! no check for the O versions, as that is not possible in plain C.
An example of their use would be,
--- 93,116 ----
the 'space' predicate will tell you whether there is spare capacity
in the vector. You will not normally need to use these two functions.
! Vector types are defined using a DEF_VEC_{O,P,I}(TYPEDEF) macro, to
get the non-memory allocation version, and then a
! DEF_VEC_ALLOC_{O,P,I}(TYPEDEF,ALLOC) macro to get memory managed
vectors. Variables of vector type are declared using a
VEC(TYPEDEF,ALLOC) macro. The ALLOC argument specifies the
allocation strategy, and can be either 'gc' or 'heap' for garbage
collected and heap allocated respectively. It can be 'none' to get
a vector that must be explicitly allocated (for instance as a
! trailing array of another structure). The characters O, P and I
! indicate whether TYPEDEF is a pointer (P), object (O) or integral
! (I) type. Be careful to pick the correct one, as you'll get an
! awkward and inefficient API if you use the wrong one. There is a
! check, which results in a compile-time warning, for the P and I
! versions, but there is no check for the O versions, as that is not
! possible in plain C. Due to the way GTY works, you must annotate
! any structures you wish to insert or reference from a vector with a
! GTY(()) tag. You need to do this even if you never declare the GC
! allocated variants.
An example of their use would be,
*************** Software Foundation, 59 Temple Place - S
*** 147,152 ****
--- 148,154 ----
#define VEC_length(T,V) (VEC_OP(T,base,length)(VEC_BASE(V)))
/* Get the final element of the vector.
+ T VEC_T_last(VEC(T) *v); // Integer
T VEC_T_last(VEC(T) *v); // Pointer
T *VEC_T_last(VEC(T) *v); // Object
*************** Software Foundation, 59 Temple Place - S
*** 155,160 ****
--- 157,163 ----
#define VEC_last(T,V) (VEC_OP(T,base,last)(VEC_BASE(V) VEC_CHECK_INFO))
/* Index into vector
+ T VEC_T_index(VEC(T) *v, unsigned ix); // Integer
T VEC_T_index(VEC(T) *v, unsigned ix); // Pointer
T *VEC_T_index(VEC(T) *v, unsigned ix); // Object
*************** Software Foundation, 59 Temple Place - S
*** 163,168 ****
--- 166,172 ----
#define VEC_index(T,V,I) (VEC_OP(T,base,index)(VEC_BASE(V),I VEC_CHECK_INFO))
/* Iterate over vector
+ int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Integer
int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Pointer
int VEC_T_iterate(VEC(T) *v, unsigned ix, T *&ptr); // Object
*************** Software Foundation, 59 Temple Place - S
*** 228,233 ****
--- 232,238 ----
(VEC_OP(T,A,reserve)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
/* Push object with no reallocation
+ T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer
T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object
*************** Software Foundation, 59 Temple Place - S
*** 240,245 ****
--- 245,251 ----
(VEC_OP(T,base,quick_push)(VEC_BASE(V),O VEC_CHECK_INFO))
/* Push object with reallocation
+ T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Integer
T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Pointer
T *VEC_T_A_safe_push (VEC(T,A) *&v, T *obj); // Object
*************** Software Foundation, 59 Temple Place - S
*** 251,256 ****
--- 257,263 ----
(VEC_OP(T,A,safe_push)(&(V),O VEC_CHECK_INFO MEM_STAT_INFO))
/* Pop element off end
+ T VEC_T_pop (VEC(T) *v); // Integer
T VEC_T_pop (VEC(T) *v); // Pointer
void VEC_T_pop (VEC(T) *v); // Object
*************** Software Foundation, 59 Temple Place - S
*** 279,284 ****
--- 286,292 ----
(VEC_OP(T,A,safe_grow)(&(V),I VEC_CHECK_INFO))
/* Replace element
+ T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Integer
T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Pointer
T *VEC_T_replace (VEC(T) *v, unsigned ix, T *val); // Object
*************** Software Foundation, 59 Temple Place - S
*** 292,297 ****
--- 300,306 ----
(VEC_OP(T,base,replace)(VEC_BASE(V),I,O VEC_CHECK_INFO))
/* Insert object with no reallocation
+ T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer
T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer
T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object
*************** Software Foundation, 59 Temple Place - S
*** 304,309 ****
--- 313,319 ----
(VEC_OP(T,base,quick_insert)(VEC_BASE(V),I,O VEC_CHECK_INFO))
/* Insert object with reallocation
+ T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Integer
T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Pointer
T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T *val); // Object
*************** Software Foundation, 59 Temple Place - S
*** 316,321 ****
--- 326,332 ----
(VEC_OP(T,A,safe_insert)(&(V),I,O VEC_CHECK_INFO MEM_STAT_INFO))
/* Remove element retaining order
+ T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer
T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer
void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Object
*************** Software Foundation, 59 Temple Place - S
*** 327,332 ****
--- 338,344 ----
(VEC_OP(T,base,ordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO))
/* Remove element destroying order
+ T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer
T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer
void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Object
*************** Software Foundation, 59 Temple Place - S
*** 347,352 ****
--- 359,366 ----
/* Find the first index in the vector not less than the object.
unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
+ bool (*lessthan) (const T, const T)); // Integer
+ unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
bool (*lessthan) (const T, const T)); // Pointer
unsigned VEC_T_lower_bound (VEC(T) *v, const T *val,
bool (*lessthan) (const T*, const T*)); // Object
*************** extern void vec_assert_fail (const char
*** 397,402 ****
--- 411,424 ----
/* Base of vector type, not user visible. */
#define VEC_T(T,B) \
+ typedef struct VEC(T,B) \
+ { \
+ unsigned num; \
+ unsigned alloc; \
+ T vec[1]; \
+ } VEC(T,B)
+
+ #define VEC_T_GTY(T,B) \
typedef struct VEC(T,B) GTY(()) \
{ \
unsigned num; \
*************** typedef struct VEC(T,B) GTY(())
*** 405,411 ****
} VEC(T,B)
/* Derived vector type, user visible. */
! #define VEC_TA(T,B,A,GTY) \
typedef struct VEC(T,A) GTY \
{ \
VEC(T,B) base; \
--- 427,433 ----
} VEC(T,B)
/* Derived vector type, user visible. */
! #define VEC_TA_GTY(T,B,A,GTY) \
typedef struct VEC(T,A) GTY \
{ \
VEC(T,B) base; \
*************** typedef struct VEC(T,A) GTY \
*** 414,433 ****
/* Convert to base type. */
#define VEC_BASE(P) ((P) ? &(P)->base : 0)
/* Vector of pointer to object. */
#if IN_GENGTYPE
! {"DEF_VEC_P", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
! {"DEF_VEC_ALLOC_P", VEC_STRINGIFY (VEC_TA (#0,#1,#2,#3)) ";", NULL},
#else
-
#define DEF_VEC_P(T) \
! VEC_T(T,base); \
! \
! static inline void VEC_OP (T,must,be_a_pointer_or_integer) (void) \
{ \
! (void)((T)0 == (void *)0); \
} \
\
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
{ \
return vec_ ? vec_->num : 0; \
--- 436,484 ----
/* Convert to base type. */
#define VEC_BASE(P) ((P) ? &(P)->base : 0)
+ /* Vector of integer-like object. */
+ #if IN_GENGTYPE
+ {"DEF_VEC_I", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
+ {"DEF_VEC_ALLOC_I", VEC_STRINGIFY (VEC_TA (#0,#1,#2,#3)) ";", NULL},
+ #else
+ #define DEF_VEC_I(T) \
+ static inline void VEC_OP (T,must_be,integral_type) (void) \
+ { \
+ (void)~(T)0; \
+ } \
+ \
+ VEC_T(T,base); \
+ VEC_TA_GTY(T,base,none,); \
+ DEF_VEC_FUNC_P(T) \
+ struct vec_swallow_trailing_semi
+ #define DEF_VEC_ALLOC_I(T,A) \
+ VEC_TA_GTY(T,base,A,); \
+ DEF_VEC_ALLOC_FUNC_P(T,A) \
+ struct vec_swallow_trailing_semi
+ #endif
+
/* Vector of pointer to object. */
#if IN_GENGTYPE
! {"DEF_VEC_P", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
! {"DEF_VEC_ALLOC_P", VEC_STRINGIFY (VEC_TA_GTY (#0,#1,#2,#3)) ";", NULL},
#else
#define DEF_VEC_P(T) \
! static inline void VEC_OP (T,must_be,pointer_type) (void) \
{ \
! (void)((T)1 == (void *)1); \
} \
\
+ VEC_T_GTY(T,base); \
+ VEC_TA_GTY(T,base,none,); \
+ DEF_VEC_FUNC_P(T) \
+ struct vec_swallow_trailing_semi
+ #define DEF_VEC_ALLOC_P(T,A) \
+ VEC_TA_GTY(T,base,A,); \
+ DEF_VEC_ALLOC_FUNC_P(T,A) \
+ struct vec_swallow_trailing_semi
+ #endif
+
+ #define DEF_VEC_FUNC_P(T) \
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
{ \
return vec_ ? vec_->num : 0; \
*************** static inline unsigned VEC_OP (T,base,lo
*** 598,610 ****
len_ = half_; \
} \
return first_; \
! } \
! \
! VEC_TA(T,base,none,)
!
! #define DEF_VEC_ALLOC_P(T,A) \
! VEC_TA(T,base,A,); \
! \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \
{ \
--- 649,657 ----
len_ = half_; \
} \
return first_; \
! }
!
! #define DEF_VEC_ALLOC_FUNC_P(T,A) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \
{ \
*************** static inline T *VEC_OP (T,A,safe_insert
*** 659,678 ****
\
return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
VEC_CHECK_PASS); \
! } \
! \
! struct vec_swallow_trailing_semi
! #endif
/* Vector of object. */
#if IN_GENGTYPE
! {"DEF_VEC_O", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
! {"DEF_VEC_ALLOC_O", VEC_STRINGIFY (VEC_TA(#0,#1,#2,#3)) ";", NULL},
#else
-
#define DEF_VEC_O(T) \
! VEC_T(T,base); \
! \
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
{ \
return vec_ ? vec_->num : 0; \
--- 706,730 ----
\
return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
VEC_CHECK_PASS); \
! }
/* Vector of object. */
#if IN_GENGTYPE
! {"DEF_VEC_O", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
! {"DEF_VEC_ALLOC_O", VEC_STRINGIFY (VEC_TA_GTY(#0,#1,#2,#3)) ";", NULL},
#else
#define DEF_VEC_O(T) \
! VEC_T_GTY(T,base); \
! VEC_TA_GTY(T,base,none,); \
! DEF_VEC_FUNC_O(T) \
! struct vec_swallow_trailing_semi
! #define DEF_VEC_ALLOC_O(T,A) \
! VEC_TA_GTY(T,base,A,); \
! DEF_VEC_ALLOC_FUNC_O(T,A) \
! struct vec_swallow_trailing_semi
! #endif
!
! #define DEF_VEC_FUNC_O(T) \
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
{ \
return vec_ ? vec_->num : 0; \
*************** static inline unsigned VEC_OP (T,base,lo
*** 830,842 ****
len_ = half_; \
} \
return first_; \
! } \
! \
! VEC_TA(T,base,none,)
! #define DEF_VEC_ALLOC_O(T,A) \
! VEC_TA(T,base,A,); \
! \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \
{ \
--- 882,890 ----
len_ = half_; \
} \
return first_; \
! }
! #define DEF_VEC_ALLOC_FUNC_O(T,A) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \
{ \
*************** static inline T *VEC_OP (T,A,safe_insert
*** 899,907 ****
\
return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
VEC_CHECK_PASS); \
! } \
! \
! struct vec_swallow_trailing_semi
! #endif
!
#endif /* GCC_VEC_H */
--- 947,951 ----
\
return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
VEC_CHECK_PASS); \
! }
#endif /* GCC_VEC_H */