Coverage Report

Created: 2017-04-29 12:21

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/polly/lib/External/isl/isl_schedule_read.c
Line
Count
Source (jump to first uncovered line)
1
#include <string.h>
2
3
#include <isl/schedule.h>
4
#include <isl/stream.h>
5
#include <isl_schedule_private.h>
6
#include <isl_schedule_tree.h>
7
8
/* An enumeration of the various keys that may appear in a YAML mapping
9
 * of a schedule.
10
 */
11
enum isl_schedule_key {
12
  isl_schedule_key_error = -1,
13
  isl_schedule_key_child,
14
  isl_schedule_key_coincident,
15
  isl_schedule_key_context,
16
  isl_schedule_key_contraction,
17
  isl_schedule_key_domain,
18
  isl_schedule_key_expansion,
19
  isl_schedule_key_extension,
20
  isl_schedule_key_filter,
21
  isl_schedule_key_guard,
22
  isl_schedule_key_leaf,
23
  isl_schedule_key_mark,
24
  isl_schedule_key_options,
25
  isl_schedule_key_permutable,
26
  isl_schedule_key_schedule,
27
  isl_schedule_key_sequence,
28
  isl_schedule_key_set
29
};
30
31
/* Extract a mapping key from the token "tok".
32
 * Return isl_schedule_key_error on error, i.e., if "tok" does not
33
 * correspond to any known key.
34
 */
35
static enum isl_schedule_key extract_key(__isl_keep isl_stream *s,
36
  struct isl_token *tok)
37
0
{
38
0
  int type;
39
0
  char *name;
40
0
  enum isl_schedule_key key;
41
0
  isl_ctx *ctx;
42
0
43
0
  ctx = isl_stream_get_ctx(s);
44
0
  type = isl_token_get_type(tok);
45
0
  if (
type != ISL_TOKEN_IDENT && 0
type != ISL_TOKEN_STRING0
)
{0
46
0
    isl_stream_error(s, tok, "expecting key");
47
0
    return isl_schedule_key_error;
48
0
  }
49
0
  name = isl_token_get_str(ctx, tok);
50
0
  if (!strcmp(name, "child"))
51
0
    key = isl_schedule_key_child;
52
0
  else 
if (0
!strcmp(name, "coincident")0
)
53
0
    key = isl_schedule_key_coincident;
54
0
  else 
if (0
!strcmp(name, "context")0
)
55
0
    key = isl_schedule_key_context;
56
0
  else 
if (0
!strcmp(name, "contraction")0
)
57
0
    key = isl_schedule_key_contraction;
58
0
  else 
if (0
!strcmp(name, "domain")0
)
59
0
    key = isl_schedule_key_domain;
60
0
  else 
if (0
!strcmp(name, "expansion")0
)
61
0
    key = isl_schedule_key_expansion;
62
0
  else 
if (0
!strcmp(name, "extension")0
)
63
0
    key = isl_schedule_key_extension;
64
0
  else 
if (0
!strcmp(name, "filter")0
)
65
0
    key = isl_schedule_key_filter;
66
0
  else 
if (0
!strcmp(name, "guard")0
)
67
0
    key = isl_schedule_key_guard;
68
0
  else 
if (0
!strcmp(name, "leaf")0
)
69
0
    key = isl_schedule_key_leaf;
70
0
  else 
if (0
!strcmp(name, "mark")0
)
71
0
    key = isl_schedule_key_mark;
72
0
  else 
if (0
!strcmp(name, "options")0
)
73
0
    key = isl_schedule_key_options;
74
0
  else 
if (0
!strcmp(name, "schedule")0
)
75
0
    key = isl_schedule_key_schedule;
76
0
  else 
if (0
!strcmp(name, "sequence")0
)
77
0
    key = isl_schedule_key_sequence;
78
0
  else 
if (0
!strcmp(name, "set")0
)
79
0
    key = isl_schedule_key_set;
80
0
  else 
if (0
!strcmp(name, "permutable")0
)
81
0
    key = isl_schedule_key_permutable;
82
0
  else
83
0
    isl_die(ctx, isl_error_invalid, "unknown key",
84
0
      key = isl_schedule_key_error);
85
0
  free(name);
86
0
  return key;
87
0
}
88
89
/* Read a key from "s" and return the corresponding enum.
90
 * Return isl_schedule_key_error on error, i.e., if the first token
91
 * on the stream does not correspond to any known key.
92
 */
93
static enum isl_schedule_key get_key(__isl_keep isl_stream *s)
94
0
{
95
0
  struct isl_token *tok;
96
0
  enum isl_schedule_key key;
97
0
98
0
  tok = isl_stream_next_token(s);
99
0
  key = extract_key(s, tok);
100
0
  isl_token_free(tok);
101
0
102
0
  return key;
103
0
}
104
105
static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree(
106
  __isl_keep isl_stream *s);
107
108
/* Read a subtree with context root node from "s".
109
 */
110
static __isl_give isl_schedule_tree *read_context(__isl_keep isl_stream *s)
111
0
{
112
0
  isl_set *context = NULL;
113
0
  isl_schedule_tree *tree;
114
0
  isl_ctx *ctx;
115
0
  struct isl_token *tok;
116
0
  enum isl_schedule_key key;
117
0
  char *str;
118
0
  int more;
119
0
120
0
  ctx = isl_stream_get_ctx(s);
121
0
122
0
  key = get_key(s);
123
0
124
0
  if (isl_stream_yaml_next(s) < 0)
125
0
    return NULL;
126
0
127
0
  tok = isl_stream_next_token(s);
128
0
  if (
!tok0
)
{0
129
0
    isl_stream_error(s, NULL, "unexpected EOF");
130
0
    return NULL;
131
0
  }
132
0
  str = isl_token_get_str(ctx, tok);
133
0
  context = isl_set_read_from_str(ctx, str);
134
0
  free(str);
135
0
  isl_token_free(tok);
136
0
137
0
  more = isl_stream_yaml_next(s);
138
0
  if (more < 0)
139
0
    goto error;
140
0
  
if (0
!more0
)
{0
141
0
    tree = isl_schedule_tree_from_context(context);
142
0
  } else {
143
0
    key = get_key(s);
144
0
    if (key != isl_schedule_key_child)
145
0
      isl_die(ctx, isl_error_invalid, "expecting child",
146
0
        goto error);
147
0
    
if (0
isl_stream_yaml_next(s) < 00
)
148
0
      goto error;
149
0
    tree = isl_stream_read_schedule_tree(s);
150
0
    tree = isl_schedule_tree_insert_context(tree, context);
151
0
  }
152
0
153
0
  return tree;
154
0
error:
155
0
  isl_set_free(context);
156
0
  return NULL;
157
0
}
158
159
/* Read a subtree with domain root node from "s".
160
 */
161
static __isl_give isl_schedule_tree *read_domain(__isl_keep isl_stream *s)
162
0
{
163
0
  isl_union_set *domain = NULL;
164
0
  isl_schedule_tree *tree;
165
0
  isl_ctx *ctx;
166
0
  struct isl_token *tok;
167
0
  enum isl_schedule_key key;
168
0
  char *str;
169
0
  int more;
170
0
171
0
  ctx = isl_stream_get_ctx(s);
172
0
173
0
  key = get_key(s);
174
0
175
0
  if (isl_stream_yaml_next(s) < 0)
176
0
    return NULL;
177
0
178
0
  tok = isl_stream_next_token(s);
179
0
  if (
!tok0
)
{0
180
0
    isl_stream_error(s, NULL, "unexpected EOF");
181
0
    return NULL;
182
0
  }
183
0
  str = isl_token_get_str(ctx, tok);
184
0
  domain = isl_union_set_read_from_str(ctx, str);
185
0
  free(str);
186
0
  isl_token_free(tok);
187
0
188
0
  more = isl_stream_yaml_next(s);
189
0
  if (more < 0)
190
0
    goto error;
191
0
  
if (0
!more0
)
{0
192
0
    tree = isl_schedule_tree_from_domain(domain);
193
0
  } else {
194
0
    key = get_key(s);
195
0
    if (key != isl_schedule_key_child)
196
0
      isl_die(ctx, isl_error_invalid, "expecting child",
197
0
        goto error);
198
0
    
if (0
isl_stream_yaml_next(s) < 00
)
199
0
      goto error;
200
0
    tree = isl_stream_read_schedule_tree(s);
201
0
    tree = isl_schedule_tree_insert_domain(tree, domain);
202
0
  }
203
0
204
0
  return tree;
205
0
error:
206
0
  isl_union_set_free(domain);
207
0
  return NULL;
208
0
}
209
210
/* Read a subtree with expansion root node from "s".
211
 */
212
static __isl_give isl_schedule_tree *read_expansion(isl_stream *s)
213
0
{
214
0
  isl_ctx *ctx;
215
0
  isl_union_pw_multi_aff *contraction = NULL;
216
0
  isl_union_map *expansion = NULL;
217
0
  isl_schedule_tree *tree = NULL;
218
0
  int more;
219
0
220
0
  ctx = isl_stream_get_ctx(s);
221
0
222
0
  do {
223
0
    struct isl_token *tok;
224
0
    enum isl_schedule_key key;
225
0
    char *str;
226
0
227
0
    key = get_key(s);
228
0
    if (isl_stream_yaml_next(s) < 0)
229
0
      goto error;
230
0
231
0
    switch (key) {
232
0
    case isl_schedule_key_contraction:
233
0
      isl_union_pw_multi_aff_free(contraction);
234
0
      tok = isl_stream_next_token(s);
235
0
      str = isl_token_get_str(ctx, tok);
236
0
      contraction = isl_union_pw_multi_aff_read_from_str(ctx,
237
0
                  str);
238
0
      free(str);
239
0
      isl_token_free(tok);
240
0
      if (!contraction)
241
0
        goto error;
242
0
      break;
243
0
    case isl_schedule_key_expansion:
244
0
      isl_union_map_free(expansion);
245
0
      tok = isl_stream_next_token(s);
246
0
      str = isl_token_get_str(ctx, tok);
247
0
      expansion = isl_union_map_read_from_str(ctx, str);
248
0
      free(str);
249
0
      isl_token_free(tok);
250
0
      if (!expansion)
251
0
        goto error;
252
0
      break;
253
0
    case isl_schedule_key_child:
254
0
      isl_schedule_tree_free(tree);
255
0
      tree = isl_stream_read_schedule_tree(s);
256
0
      if (!tree)
257
0
        goto error;
258
0
      break;
259
0
    default:
260
0
      isl_die(ctx, isl_error_invalid, "unexpected key",
261
0
        goto error);
262
0
    }
263
0
  } while ((more = isl_stream_yaml_next(s)) > 0);
264
0
265
0
  
if (0
more < 00
)
266
0
    goto error;
267
0
268
0
  
if (0
!contraction0
)
269
0
    isl_die(ctx, isl_error_invalid, "missing contraction",
270
0
      goto error);
271
0
  
if (0
!expansion0
)
272
0
    isl_die(ctx, isl_error_invalid, "missing expansion",
273
0
      goto error);
274
0
275
0
  
if (0
!tree0
)
276
0
    return isl_schedule_tree_from_expansion(contraction, expansion);
277
0
  return isl_schedule_tree_insert_expansion(tree, contraction, expansion);
278
0
error:
279
0
  isl_schedule_tree_free(tree);
280
0
  isl_union_pw_multi_aff_free(contraction);
281
0
  isl_union_map_free(expansion);
282
0
  return NULL;
283
0
}
284
285
/* Read a subtree with extension root node from "s".
286
 */
287
static __isl_give isl_schedule_tree *read_extension(isl_stream *s)
288
0
{
289
0
  isl_union_map *extension = NULL;
290
0
  isl_schedule_tree *tree;
291
0
  isl_ctx *ctx;
292
0
  struct isl_token *tok;
293
0
  enum isl_schedule_key key;
294
0
  char *str;
295
0
  int more;
296
0
297
0
  ctx = isl_stream_get_ctx(s);
298
0
299
0
  key = get_key(s);
300
0
301
0
  if (isl_stream_yaml_next(s) < 0)
302
0
    return NULL;
303
0
304
0
  tok = isl_stream_next_token(s);
305
0
  if (
!tok0
)
{0
306
0
    isl_stream_error(s, NULL, "unexpected EOF");
307
0
    return NULL;
308
0
  }
309
0
  str = isl_token_get_str(ctx, tok);
310
0
  extension = isl_union_map_read_from_str(ctx, str);
311
0
  free(str);
312
0
  isl_token_free(tok);
313
0
314
0
  more = isl_stream_yaml_next(s);
315
0
  if (more < 0)
316
0
    goto error;
317
0
  
if (0
!more0
)
{0
318
0
    tree = isl_schedule_tree_from_extension(extension);
319
0
  } else {
320
0
    key = get_key(s);
321
0
    if (key != isl_schedule_key_child)
322
0
      isl_die(ctx, isl_error_invalid, "expecting child",
323
0
        goto error);
324
0
    
if (0
isl_stream_yaml_next(s) < 00
)
325
0
      goto error;
326
0
    tree = isl_stream_read_schedule_tree(s);
327
0
    tree = isl_schedule_tree_insert_extension(tree, extension);
328
0
  }
329
0
330
0
  return tree;
331
0
error:
332
0
  isl_union_map_free(extension);
333
0
  return NULL;
334
0
}
335
336
/* Read a subtree with filter root node from "s".
337
 */
338
static __isl_give isl_schedule_tree *read_filter(__isl_keep isl_stream *s)
339
0
{
340
0
  isl_union_set *filter = NULL;
341
0
  isl_schedule_tree *tree;
342
0
  isl_ctx *ctx;
343
0
  struct isl_token *tok;
344
0
  enum isl_schedule_key key;
345
0
  char *str;
346
0
  int more;
347
0
348
0
  ctx = isl_stream_get_ctx(s);
349
0
350
0
  key = get_key(s);
351
0
352
0
  if (isl_stream_yaml_next(s) < 0)
353
0
    return NULL;
354
0
355
0
  tok = isl_stream_next_token(s);
356
0
  if (
!tok0
)
{0
357
0
    isl_stream_error(s, NULL, "unexpected EOF");
358
0
    return NULL;
359
0
  }
360
0
  str = isl_token_get_str(ctx, tok);
361
0
  filter = isl_union_set_read_from_str(ctx, str);
362
0
  free(str);
363
0
  isl_token_free(tok);
364
0
365
0
  more = isl_stream_yaml_next(s);
366
0
  if (more < 0)
367
0
    goto error;
368
0
  
if (0
!more0
)
{0
369
0
    tree = isl_schedule_tree_from_filter(filter);
370
0
  } else {
371
0
    key = get_key(s);
372
0
    if (key != isl_schedule_key_child)
373
0
      isl_die(ctx, isl_error_invalid, "expecting child",
374
0
        goto error);
375
0
    
if (0
isl_stream_yaml_next(s) < 00
)
376
0
      goto error;
377
0
    tree = isl_stream_read_schedule_tree(s);
378
0
    tree = isl_schedule_tree_insert_filter(tree, filter);
379
0
  }
380
0
381
0
  return tree;
382
0
error:
383
0
  isl_union_set_free(filter);
384
0
  return NULL;
385
0
}
386
387
/* Read a subtree with guard root node from "s".
388
 */
389
static __isl_give isl_schedule_tree *read_guard(isl_stream *s)
390
0
{
391
0
  isl_set *guard = NULL;
392
0
  isl_schedule_tree *tree;
393
0
  isl_ctx *ctx;
394
0
  struct isl_token *tok;
395
0
  enum isl_schedule_key key;
396
0
  char *str;
397
0
  int more;
398
0
399
0
  ctx = isl_stream_get_ctx(s);
400
0
401
0
  key = get_key(s);
402
0
403
0
  if (isl_stream_yaml_next(s) < 0)
404
0
    return NULL;
405
0
406
0
  tok = isl_stream_next_token(s);
407
0
  if (
!tok0
)
{0
408
0
    isl_stream_error(s, NULL, "unexpected EOF");
409
0
    return NULL;
410
0
  }
411
0
  str = isl_token_get_str(ctx, tok);
412
0
  guard = isl_set_read_from_str(ctx, str);
413
0
  free(str);
414
0
  isl_token_free(tok);
415
0
416
0
  more = isl_stream_yaml_next(s);
417
0
  if (more < 0)
418
0
    goto error;
419
0
  
if (0
!more0
)
{0
420
0
    tree = isl_schedule_tree_from_guard(guard);
421
0
  } else {
422
0
    key = get_key(s);
423
0
    if (key != isl_schedule_key_child)
424
0
      isl_die(ctx, isl_error_invalid, "expecting child",
425
0
        goto error);
426
0
    
if (0
isl_stream_yaml_next(s) < 00
)
427
0
      goto error;
428
0
    tree = isl_stream_read_schedule_tree(s);
429
0
    tree = isl_schedule_tree_insert_guard(tree, guard);
430
0
  }
431
0
432
0
  return tree;
433
0
error:
434
0
  isl_set_free(guard);
435
0
  return NULL;
436
0
}
437
438
/* Read a subtree with mark root node from "s".
439
 */
440
static __isl_give isl_schedule_tree *read_mark(isl_stream *s)
441
0
{
442
0
  isl_id *mark;
443
0
  isl_schedule_tree *tree;
444
0
  isl_ctx *ctx;
445
0
  struct isl_token *tok;
446
0
  enum isl_schedule_key key;
447
0
  char *str;
448
0
  int more;
449
0
450
0
  ctx = isl_stream_get_ctx(s);
451
0
452
0
  key = get_key(s);
453
0
454
0
  if (isl_stream_yaml_next(s) < 0)
455
0
    return NULL;
456
0
457
0
  tok = isl_stream_next_token(s);
458
0
  if (
!tok0
)
{0
459
0
    isl_stream_error(s, NULL, "unexpected EOF");
460
0
    return NULL;
461
0
  }
462
0
  str = isl_token_get_str(ctx, tok);
463
0
  mark = isl_id_alloc(ctx, str, NULL);
464
0
  free(str);
465
0
  isl_token_free(tok);
466
0
467
0
  more = isl_stream_yaml_next(s);
468
0
  if (more < 0)
469
0
    goto error;
470
0
  
if (0
!more0
)
{0
471
0
    isl_die(ctx, isl_error_invalid, "expecting child",
472
0
      goto error);
473
0
  } else {
474
0
    key = get_key(s);
475
0
    if (key != isl_schedule_key_child)
476
0
      isl_die(ctx, isl_error_invalid, "expecting child",
477
0
        goto error);
478
0
    
if (0
isl_stream_yaml_next(s) < 00
)
479
0
      goto error;
480
0
    tree = isl_stream_read_schedule_tree(s);
481
0
    tree = isl_schedule_tree_insert_mark(tree, mark);
482
0
  }
483
0
484
0
  return tree;
485
0
error:
486
0
  isl_id_free(mark);
487
0
  return NULL;
488
0
}
489
490
/* Read a sequence of integers from "s" (representing the coincident
491
 * property of a band node).
492
 */
493
static __isl_give isl_val_list *read_coincident(__isl_keep isl_stream *s)
494
0
{
495
0
  isl_ctx *ctx;
496
0
  isl_val_list *list;
497
0
  int more;
498
0
499
0
  ctx = isl_stream_get_ctx(s);
500
0
501
0
  if (isl_stream_yaml_read_start_sequence(s) < 0)
502
0
    return NULL;
503
0
504
0
  list = isl_val_list_alloc(ctx, 0);
505
0
  while  (
(more = isl_stream_yaml_next(s)) > 00
)
{0
506
0
    isl_val *val;
507
0
508
0
    val = isl_stream_read_val(s);
509
0
    list = isl_val_list_add(list, val);
510
0
  }
511
0
512
0
  if (
more < 0 || 0
isl_stream_yaml_read_end_sequence(s)0
)
513
0
    list = isl_val_list_free(list);
514
0
515
0
  return list;
516
0
}
517
518
/* Set the (initial) coincident properties of "band" according to
519
 * the (initial) elements of "coincident".
520
 */
521
static __isl_give isl_schedule_band *set_coincident(
522
  __isl_take isl_schedule_band *band, __isl_take isl_val_list *coincident)
523
0
{
524
0
  int i;
525
0
  int n, m;
526
0
527
0
  n = isl_schedule_band_n_member(band);
528
0
  m = isl_val_list_n_val(coincident);
529
0
530
0
  for (i = 0; 
i < n && 0
i < m0
;
++i0
)
{0
531
0
    isl_val *v;
532
0
533
0
    v = isl_val_list_get_val(coincident, i);
534
0
    if (!v)
535
0
      band = isl_schedule_band_free(band);
536
0
    band = isl_schedule_band_member_set_coincident(band, i,
537
0
              !isl_val_is_zero(v));
538
0
    isl_val_free(v);
539
0
  }
540
0
  isl_val_list_free(coincident);
541
0
  return band;
542
0
}
543
544
/* Read a subtree with band root node from "s".
545
 */
546
static __isl_give isl_schedule_tree *read_band(isl_stream *s)
547
0
{
548
0
  isl_multi_union_pw_aff *schedule = NULL;
549
0
  isl_schedule_tree *tree = NULL;
550
0
  isl_val_list *coincident = NULL;
551
0
  isl_union_set *options = NULL;
552
0
  isl_ctx *ctx;
553
0
  isl_schedule_band *band;
554
0
  int permutable = 0;
555
0
  int more;
556
0
557
0
  ctx = isl_stream_get_ctx(s);
558
0
559
0
  do {
560
0
    struct isl_token *tok;
561
0
    enum isl_schedule_key key;
562
0
    char *str;
563
0
    isl_val *v;
564
0
565
0
    key = get_key(s);
566
0
    if (isl_stream_yaml_next(s) < 0)
567
0
      goto error;
568
0
569
0
    switch (key) {
570
0
    case isl_schedule_key_schedule:
571
0
      schedule = isl_multi_union_pw_aff_free(schedule);
572
0
      tok = isl_stream_next_token(s);
573
0
      if (
!tok0
)
{0
574
0
        isl_stream_error(s, NULL, "unexpected EOF");
575
0
        goto error;
576
0
      }
577
0
      str = isl_token_get_str(ctx, tok);
578
0
      schedule = isl_multi_union_pw_aff_read_from_str(ctx,
579
0
                  str);
580
0
      free(str);
581
0
      isl_token_free(tok);
582
0
      if (!schedule)
583
0
        goto error;
584
0
      break;
585
0
    case isl_schedule_key_coincident:
586
0
      coincident = read_coincident(s);
587
0
      if (!coincident)
588
0
        goto error;
589
0
      break;
590
0
    case isl_schedule_key_permutable:
591
0
      v = isl_stream_read_val(s);
592
0
      permutable = !isl_val_is_zero(v);
593
0
      isl_val_free(v);
594
0
      break;
595
0
    case isl_schedule_key_options:
596
0
      isl_union_set_free(options);
597
0
      tok = isl_stream_next_token(s);
598
0
      str = isl_token_get_str(ctx, tok);
599
0
      options = isl_union_set_read_from_str(ctx, str);
600
0
      free(str);
601
0
      isl_token_free(tok);
602
0
      if (!options)
603
0
        goto error;
604
0
      break;
605
0
    case isl_schedule_key_child:
606
0
      isl_schedule_tree_free(tree);
607
0
      tree = isl_stream_read_schedule_tree(s);
608
0
      if (!tree)
609
0
        goto error;
610
0
      break;
611
0
    default:
612
0
      isl_die(ctx, isl_error_invalid, "unexpected key",
613
0
        goto error);
614
0
    }
615
0
  } while ((more = isl_stream_yaml_next(s)) > 0);
616
0
617
0
  
if (0
more < 00
)
618
0
    goto error;
619
0
620
0
  
if (0
!schedule0
)
621
0
    isl_die(ctx, isl_error_invalid, "missing schedule", goto error);
622
0
623
0
  band = isl_schedule_band_from_multi_union_pw_aff(schedule);
624
0
  band = isl_schedule_band_set_permutable(band, permutable);
625
0
  if (coincident)
626
0
    band = set_coincident(band, coincident);
627
0
  if (options)
628
0
    band = isl_schedule_band_set_ast_build_options(band, options);
629
0
  if (tree)
630
0
    tree = isl_schedule_tree_insert_band(tree, band);
631
0
  else
632
0
    tree = isl_schedule_tree_from_band(band);
633
0
634
0
  return tree;
635
0
error:
636
0
  isl_val_list_free(coincident);
637
0
  isl_union_set_free(options);
638
0
  isl_schedule_tree_free(tree);
639
0
  isl_multi_union_pw_aff_free(schedule);
640
0
  return NULL;
641
0
}
642
643
/* Read a subtree with root node of type "type" from "s".
644
 * The node is represented by a sequence of children.
645
 */
646
static __isl_give isl_schedule_tree *read_children(isl_stream *s,
647
  enum isl_schedule_node_type type)
648
0
{
649
0
  isl_ctx *ctx;
650
0
  isl_schedule_tree_list *list;
651
0
  int more;
652
0
653
0
  ctx = isl_stream_get_ctx(s);
654
0
655
0
  isl_token_free(isl_stream_next_token(s));
656
0
657
0
  if (isl_stream_yaml_next(s) < 0)
658
0
    return NULL;
659
0
660
0
  
if (0
isl_stream_yaml_read_start_sequence(s)0
)
661
0
    return NULL;
662
0
663
0
  list = isl_schedule_tree_list_alloc(ctx, 0);
664
0
  while (
(more = isl_stream_yaml_next(s)) > 00
)
{0
665
0
    isl_schedule_tree *tree;
666
0
667
0
    tree = isl_stream_read_schedule_tree(s);
668
0
    list = isl_schedule_tree_list_add(list, tree);
669
0
  }
670
0
671
0
  if (
more < 0 || 0
isl_stream_yaml_read_end_sequence(s)0
)
672
0
    list = isl_schedule_tree_list_free(list);
673
0
674
0
  return isl_schedule_tree_from_children(type, list);
675
0
}
676
677
/* Read a subtree with sequence root node from "s".
678
 */
679
static __isl_give isl_schedule_tree *read_sequence(isl_stream *s)
680
0
{
681
0
  return read_children(s, isl_schedule_node_sequence);
682
0
}
683
684
/* Read a subtree with set root node from "s".
685
 */
686
static __isl_give isl_schedule_tree *read_set(isl_stream *s)
687
0
{
688
0
  return read_children(s, isl_schedule_node_set);
689
0
}
690
691
/* Read a schedule (sub)tree from "s".
692
 *
693
 * We first determine the type of the root node based on the first
694
 * mapping key and then hand over to a function tailored to reading
695
 * nodes of this type.
696
 */
697
static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree(
698
  struct isl_stream *s)
699
0
{
700
0
  enum isl_schedule_key key;
701
0
  struct isl_token *tok;
702
0
  isl_schedule_tree *tree = NULL;
703
0
  int more;
704
0
705
0
  if (isl_stream_yaml_read_start_mapping(s))
706
0
    return NULL;
707
0
  more = isl_stream_yaml_next(s);
708
0
  if (more < 0)
709
0
    return NULL;
710
0
  
if (0
!more0
)
{0
711
0
    isl_stream_error(s, NULL, "missing key");
712
0
    return NULL;
713
0
  }
714
0
715
0
  tok = isl_stream_next_token(s);
716
0
  key = extract_key(s, tok);
717
0
  isl_stream_push_token(s, tok);
718
0
  if (key < 0)
719
0
    return NULL;
720
0
  switch (key) {
721
0
  case isl_schedule_key_context:
722
0
    tree = read_context(s);
723
0
    break;
724
0
  case isl_schedule_key_domain:
725
0
    tree = read_domain(s);
726
0
    break;
727
0
  case isl_schedule_key_contraction:
728
0
  case isl_schedule_key_expansion:
729
0
    tree = read_expansion(s);
730
0
    break;
731
0
  case isl_schedule_key_extension:
732
0
    tree = read_extension(s);
733
0
    break;
734
0
  case isl_schedule_key_filter:
735
0
    tree = read_filter(s);
736
0
    break;
737
0
  case isl_schedule_key_guard:
738
0
    tree = read_guard(s);
739
0
    break;
740
0
  case isl_schedule_key_leaf:
741
0
    isl_token_free(isl_stream_next_token(s));
742
0
    tree = isl_schedule_tree_leaf(isl_stream_get_ctx(s));
743
0
    break;
744
0
  case isl_schedule_key_mark:
745
0
    tree = read_mark(s);
746
0
    break;
747
0
  case isl_schedule_key_sequence:
748
0
    tree = read_sequence(s);
749
0
    break;
750
0
  case isl_schedule_key_set:
751
0
    tree = read_set(s);
752
0
    break;
753
0
  case isl_schedule_key_schedule:
754
0
  case isl_schedule_key_coincident:
755
0
  case isl_schedule_key_options:
756
0
  case isl_schedule_key_permutable:
757
0
    tree = read_band(s);
758
0
    break;
759
0
  case isl_schedule_key_child:
760
0
    isl_die(isl_stream_get_ctx(s), isl_error_unsupported,
761
0
      "cannot identity node type", return NULL);
762
0
  case isl_schedule_key_error:
763
0
    return NULL;
764
0
  }
765
0
766
0
  
if (0
isl_stream_yaml_read_end_mapping(s) < 00
)
{0
767
0
    isl_stream_error(s, NULL, "unexpected extra elements");
768
0
    return isl_schedule_tree_free(tree);
769
0
  }
770
0
771
0
  return tree;
772
0
}
773
774
/* Read an isl_schedule from "s".
775
 */
776
__isl_give isl_schedule *isl_stream_read_schedule(isl_stream *s)
777
0
{
778
0
  isl_ctx *ctx;
779
0
  isl_schedule_tree *tree;
780
0
781
0
  if (!s)
782
0
    return NULL;
783
0
784
0
  ctx = isl_stream_get_ctx(s);
785
0
  tree = isl_stream_read_schedule_tree(s);
786
0
  return isl_schedule_from_schedule_tree(ctx, tree);
787
0
}
788
789
/* Read an isl_schedule from "input".
790
 */
791
__isl_give isl_schedule *isl_schedule_read_from_file(isl_ctx *ctx, FILE *input)
792
0
{
793
0
  struct isl_stream *s;
794
0
  isl_schedule *schedule;
795
0
796
0
  s = isl_stream_new_file(ctx, input);
797
0
  if (!s)
798
0
    return NULL;
799
0
  schedule = isl_stream_read_schedule(s);
800
0
  isl_stream_free(s);
801
0
802
0
  return schedule;
803
0
}
804
805
/* Read an isl_schedule from "str".
806
 */
807
__isl_give isl_schedule *isl_schedule_read_from_str(isl_ctx *ctx,
808
  const char *str)
809
0
{
810
0
  struct isl_stream *s;
811
0
  isl_schedule *schedule;
812
0
813
0
  s = isl_stream_new_str(ctx, str);
814
0
  if (!s)
815
0
    return NULL;
816
0
  schedule = isl_stream_read_schedule(s);
817
0
  isl_stream_free(s);
818
0
819
0
  return schedule;
820
0
}