OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [g++.dg/] [opt/] [unroll1.C] - Blame information for rev 718

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 693 jeremybenn
// PR optimization/12340
2
// Origin: Richard Guenther 
3
// Testcase by Eric Botcazou 
4
 
5
// This used to segfault on x86 because the loop optimizer wrongly
6
// interpreted a double assignment to a biv as a double increment,
7
// which subsequently fooled the unroller.
8
 
9
// { dg-do run }
10
// { dg-options "-O2 -fno-exceptions -funroll-loops" }
11
 
12
typedef __SIZE_TYPE__ size_t;
13
 
14
inline void* operator new(size_t, void* __p) throw() { return __p; }
15
inline void operator delete (void*, void*) throw() { };
16
 
17
class Loc;
18
class Interval;
19
 
20
template
21
class DomainBase
22
{
23
public:
24
  typedef typename DT::Domain_t Domain_t;
25
  typedef typename DT::Storage_t Storage_t;
26
 
27
  Domain_t &unwrap() { return *static_cast(this); }
28
 
29
  const Domain_t &unwrap() const {
30
    return *static_cast(const_cast *>(this));
31
  }
32
 
33
protected:
34
  Storage_t domain_m;
35
};
36
 
37
template
38
class Domain : public DomainBase
39
{
40
  typedef DomainBase
Base_t;
41
 
42
public:
43
  typedef typename DT::Size_t Size_t;
44
  typedef typename DT::Element_t Element_t;
45
  typedef typename Base_t::Domain_t Domain_t;
46
  typedef typename Base_t::Storage_t Storage_t;
47
 
48
  Domain_t &operator[](int) { return this->unwrap(); }
49
 
50
  const Domain_t &operator[](int) const { return this->unwrap(); }
51
 
52
  template
53
  void setDomain(const T &newdom) {
54
    DT::setDomain(this->domain_m, newdom);
55
  }
56
 
57
  Element_t first() const { return DT::first(this->domain_m); }
58
 
59
  Size_t length() const { return DT::length(this->domain_m); }
60
 
61
  Size_t size() const { return length(); }
62
};
63
 
64
template
65
struct DomainTraits;
66
 
67
template<>
68
struct DomainTraits
69
{
70
  typedef int Size_t;
71
  typedef int Element_t;
72
  typedef Interval Domain_t;
73
  typedef Interval OneDomain_t;
74
  typedef Loc AskDomain_t;
75
  typedef int Storage_t[2];
76
  enum { dimensions = 1 };
77
  enum { wildcard = false };
78
 
79
  static int first(const Storage_t &d) { return d[0]; }
80
 
81
  static int length(const Storage_t &d) { return d[1]; }
82
 
83
  static OneDomain_t &getDomain(Domain_t &d, int) { return d; }
84
 
85
  static const OneDomain_t &getDomain(const Domain_t &d, int) { return d; }
86
 
87
  template
88
  static void setDomain(Storage_t &dom, const T &newdom) {
89
    dom[0] = newdom.first();
90
    dom[1] = newdom.length();
91
  }
92
 
93
  template
94
  static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval) {
95
    dom[0] = begval;
96
    dom[1] = (endval - begval + 1);
97
  }
98
 
99
};
100
 
101
class Interval : public Domain >
102
{
103
public:
104
  Interval(const Interval &a) : Domain >() {
105
    for (int i=0; i < DomainTraits::dimensions; ++i)
106
      DomainTraits::getDomain(*this, i).setDomain(
107
                                DomainTraits::getDomain(a, i));
108
  }
109
 
110
  Interval(int a) : Domain >()
111
  {
112
    DomainTraits::setDomain(domain_m, 0, a - 1);
113
  }
114
};
115
 
116
template<>
117
struct DomainTraits
118
{
119
  typedef int Size_t;
120
  typedef int Element_t;
121
  typedef Loc Domain_t;
122
  typedef Loc AskDomain_t;
123
  typedef Loc MultResult_t;
124
  typedef int Storage_t;
125
 
126
  static int first(int d) { return d; }
127
 
128
  template
129
  static void setDomain(int &dom, const T &newdom) {
130
    dom = DomainTraits::getFirst(newdom);
131
  }
132
};
133
 
134
template<>
135
struct DomainTraits
136
 {
137
  enum { dimensions = 1 };
138
  enum { wildcard = false };
139
 
140
  static int getPointDomain(int d, int) { return d; }
141
 
142
  static int getFirst(const int &d) { return d; }
143
};
144
 
145
class Loc : public Domain >
146
{
147
public:
148
  explicit Loc(const int &a) : Domain >() {
149
    for (int i=0; i < 1; ++i)
150
      (*this)[i].setDomain(DomainTraits::getPointDomain(a, 0));
151
  }
152
};
153
 
154
struct ElementProperties
155
{
156
  enum { hasTrivialDefaultConstructor = false };
157
  enum { hasTrivialDestructor = false };
158
 
159
  static void construct(double* addr)
160
  {
161
    new (addr) double();
162
  }
163
 
164
  static void construct(double* addr, const double& model)
165
  {
166
    new (addr) double(model);
167
  }
168
 
169
  static void destruct(double *addr) {}
170
};
171
 
172
class RefCounted
173
{
174
public:
175
  RefCounted() : count_m(0) {}
176
 
177
  void addReference() { ++count_m; }
178
  bool removeRefAndCheckGarbage()
179
  {
180
    return (--count_m == 0);
181
  }
182
 
183
private:
184
  int count_m;
185
};
186
 
187
class RefBlockController : public RefCounted
188
{
189
public:
190
  explicit RefBlockController(unsigned int size)
191
    : pBegin_m(0), pEnd_m(0), pEndOfStorage_m(0), dealloc_m(false)
192
  {
193
    reallocateStorage(size, false);
194
 
195
    if (!ElementProperties::hasTrivialDefaultConstructor)
196
      {
197
        for (double * pt = begin(); pt != end(); ++pt)
198
          ElementProperties::construct(pt);
199
      }
200
  }
201
 
202
  ~RefBlockController()
203
  {
204
    deleteStorage();
205
  }
206
 
207
  double *begin() const
208
  {
209
    return pBegin_m;
210
  }
211
 
212
  double *end() const
213
  {
214
    return pEnd_m;
215
  }
216
 
217
  bool isMine() const
218
  {
219
    return dealloc_m;
220
  }
221
 
222
private:
223
  void deleteStorage()
224
  {
225
    if (isMine() && pBegin_m != 0)
226
      {
227
        if (!ElementProperties::hasTrivialDestructor)
228
          for (double *pt = begin(); pt != end(); ++pt)
229
            ElementProperties::destruct(pt);
230
 
231
        char *tmp = reinterpret_cast(pBegin_m);
232
        delete [] tmp;
233
      }
234
  }
235
 
236
  void reallocateStorage(unsigned int newsize, bool copyold = false)
237
  {
238
    double *pBeginNew = 0;
239
    double *pEndNew = 0;
240
    double *pEndOfStorageNew = 0;
241
 
242
    if (newsize > 0)
243
      {
244
        int nsize = newsize * sizeof(double);
245
        char *tmp = new char[nsize];
246
        pBeginNew = reinterpret_cast(tmp);
247
        pEndNew = pBeginNew + newsize;
248
        pEndOfStorageNew = pBeginNew + (nsize / sizeof(double));
249
 
250
        if (copyold)
251
          {
252
            double * pOld = begin();
253
            double * pNew = pBeginNew;
254
            while (pOld != end() && pNew != pEndNew)
255
              ElementProperties::construct(pNew++,*pOld++);
256
          }
257
      }
258
 
259
    deleteStorage();
260
 
261
    pBegin_m = pBeginNew;
262
    pEnd_m = pEndNew;
263
    pEndOfStorage_m = pEndOfStorageNew;
264
    dealloc_m = true;
265
  }
266
 
267
  double *pBegin_m;
268
  double *pEnd_m;
269
  double *pEndOfStorage_m;
270
  bool dealloc_m;
271
};
272
 
273
class DataBlockController : public RefBlockController
274
{
275
public:
276
  explicit
277
  DataBlockController(unsigned int size)
278
    : RefBlockController(size), dataObjectPtr_m(new char), owned_m(true) {}
279
 
280
  ~DataBlockController()
281
  {
282
    if (owned_m) delete dataObjectPtr_m;
283
  }
284
 
285
private:
286
  mutable char *dataObjectPtr_m;
287
  bool owned_m;
288
};
289
 
290
class RefCountedPtr
291
{
292
public:
293
  RefCountedPtr(DataBlockController * const pT) : ptr_m(pT)
294
    { if (isValid()) ptr_m->addReference(); }
295
 
296
  ~RefCountedPtr() { invalidate(); }
297
 
298
  DataBlockController* operator->() const { return ptr_m; }
299
  void invalidate();
300
  bool isValid() const { return ptr_m != 0; }
301
 
302
private:
303
  friend class RefCountedBlockPtr;
304
  DataBlockController * ptr_m;
305
};
306
 
307
inline void RefCountedPtr::invalidate()
308
{
309
  if ( isValid() && ptr_m->removeRefAndCheckGarbage() )
310
    delete ptr_m;
311
  ptr_m = 0;
312
}
313
 
314
class RefCountedBlockPtr
315
{
316
public:
317
  explicit RefCountedBlockPtr(unsigned int size)
318
    : offset_m(0),
319
      blockControllerPtr_m(new DataBlockController(size)) {}
320
 
321
  int offset() const
322
  {
323
    return offset_m;
324
  }
325
 
326
  double *beginPointer() const
327
  {
328
    return blockControllerPtr_m->begin();
329
  }
330
 
331
  double *currentPointer() const
332
  {
333
    return beginPointer() + offset();
334
  }
335
 
336
protected:
337
  int offset_m;
338
  RefCountedPtr blockControllerPtr_m;
339
};
340
 
341
class DataBlockPtr : public RefCountedBlockPtr
342
{
343
public:
344
  explicit DataBlockPtr(unsigned int size) : RefCountedBlockPtr(size) {}
345
};
346
 
347
class Node
348
{
349
public:
350
  Node(const Interval &owned, const Interval &allocated)
351
    : domain_m(owned), allocated_m(allocated) {}
352
 
353
  const Interval &allocated() const { return allocated_m; }
354
 
355
private:
356
  Interval domain_m;
357
  Interval allocated_m;
358
};
359
 
360
class DomainLayout
361
{
362
public:
363
  explicit DomainLayout(const Interval &dom) : node_m(0, dom) {}
364
 
365
  const Interval &domain() const
366
  {
367
    return node_m.allocated();
368
  }
369
 
370
private:
371
  Node node_m;
372
};
373
 
374
class BrickBase
375
{
376
public:
377
  explicit BrickBase(const Interval &domain);
378
 
379
  int offset(const Loc &dom) const { return off_m + dom[0].first(); }
380
 
381
protected:
382
  DomainLayout layout_m;
383
  int firsts_m;
384
  int off_m;
385
};
386
 
387
BrickBase::BrickBase(const Interval &dom)
388
  : layout_m(dom)
389
{
390
  firsts_m = layout_m.domain()[0].first();
391
  off_m = -firsts_m;
392
}
393
 
394
class Engine : public BrickBase
395
{
396
public:
397
  explicit Engine(const Interval &dom)
398
  : BrickBase(dom), dataBlock_m(dom.size()), data_m(dataBlock_m.currentPointer()) {}
399
 
400
  double& operator()(const Loc &loc) const
401
  {
402
    return data_m[this->offset(loc)];
403
  }
404
 
405
private:
406
  DataBlockPtr dataBlock_m;
407
  double *data_m;
408
};
409
 
410
 
411
int main()
412
{
413
  Interval I(10);
414
  Engine A(I);
415
 
416
  for (int i = 0; i < 10; i++)
417
    A(Loc(i)) = 2.0 + i - i*i;
418
 
419
  return 0;
420
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.