tree-vector-builder.h revision 1.1.1.2
1/* A class for building vector tree constants.
2   Copyright (C) 2017-2019 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3.  If not see
18<http://www.gnu.org/licenses/>.  */
19
20#ifndef GCC_TREE_VECTOR_BUILDER_H
21#define GCC_TREE_VECTOR_BUILDER_H
22
23#include "vector-builder.h"
24
25/* This class is used to build VECTOR_CSTs from a sequence of elements.
26   See vector_builder for more details.  */
27class tree_vector_builder : public vector_builder<tree, tree_vector_builder>
28{
29  typedef vector_builder<tree, tree_vector_builder> parent;
30  friend class vector_builder<tree, tree_vector_builder>;
31
32public:
33  tree_vector_builder () : m_type (0) {}
34  tree_vector_builder (tree, unsigned int, unsigned int);
35  tree build ();
36
37  tree type () const { return m_type; }
38
39  void new_vector (tree, unsigned int, unsigned int);
40  bool new_unary_operation (tree, tree, bool);
41  bool new_binary_operation (tree, tree, tree, bool);
42
43  static unsigned int binary_encoded_nelts (tree, tree);
44
45private:
46  bool equal_p (const_tree, const_tree) const;
47  bool allow_steps_p () const;
48  bool integral_p (const_tree) const;
49  wide_int step (const_tree, const_tree) const;
50  tree apply_step (tree, unsigned int, const wide_int &) const;
51  bool can_elide_p (const_tree) const;
52  void note_representative (tree *, tree);
53
54  tree m_type;
55};
56
57/* Create a new builder for a vector of type TYPE.  Initially encode the
58   value as NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements
59   each.  */
60
61inline
62tree_vector_builder::tree_vector_builder (tree type, unsigned int npatterns,
63					  unsigned int nelts_per_pattern)
64{
65  new_vector (type, npatterns, nelts_per_pattern);
66}
67
68/* Start building a new vector of type TYPE.  Initially encode the value
69   as NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each.  */
70
71inline void
72tree_vector_builder::new_vector (tree type, unsigned int npatterns,
73				 unsigned int nelts_per_pattern)
74{
75  m_type = type;
76  parent::new_vector (TYPE_VECTOR_SUBPARTS (type), npatterns,
77		      nelts_per_pattern);
78}
79
80/* Return true if elements I1 and I2 are equal.  */
81
82inline bool
83tree_vector_builder::equal_p (const_tree elt1, const_tree elt2) const
84{
85  return operand_equal_p (elt1, elt2, OEP_BITWISE);
86}
87
88/* Return true if a stepped representation is OK.  We don't allow
89   linear series for anything other than integers, to avoid problems
90   with rounding.  */
91
92inline bool
93tree_vector_builder::allow_steps_p () const
94{
95  return INTEGRAL_TYPE_P (TREE_TYPE (m_type));
96}
97
98/* Return true if ELT can be interpreted as an integer.  */
99
100inline bool
101tree_vector_builder::integral_p (const_tree elt) const
102{
103  return TREE_CODE (elt) == INTEGER_CST;
104}
105
106/* Return the value of element ELT2 minus the value of element ELT1.
107   Both elements are known to be INTEGER_CSTs.  */
108
109inline wide_int
110tree_vector_builder::step (const_tree elt1, const_tree elt2) const
111{
112  return wi::to_wide (elt2) - wi::to_wide (elt1);
113}
114
115/* Return true if we can drop element ELT, even if the retained elements
116   are different.  Return false if this would mean losing overflow
117   information.  */
118
119inline bool
120tree_vector_builder::can_elide_p (const_tree elt) const
121{
122  return !CONSTANT_CLASS_P (elt) || !TREE_OVERFLOW (elt);
123}
124
125/* Record that ELT2 is being elided, given that ELT1_PTR points to the last
126   encoded element for the containing pattern.  */
127
128inline void
129tree_vector_builder::note_representative (tree *elt1_ptr, tree elt2)
130{
131  if (CONSTANT_CLASS_P (elt2) && TREE_OVERFLOW (elt2))
132    {
133      gcc_assert (operand_equal_p (*elt1_ptr, elt2, 0));
134      if (!TREE_OVERFLOW (elt2))
135	*elt1_ptr = elt2;
136    }
137}
138
139#endif
140