10 #include <isl/printer.h>
15 static at_init
register_history_entry(history_entry::register_type
);
17 void history_entry::register_type()
19 static struct_description d
= { create
};
20 YAML_PTR_FIELD(d
, history_entry
, tool
, str
);
21 YAML_PTR_FIELD(d
, history_entry
, version
, str
);
22 YAML_SEQ_FIELD(d
, history_entry
, arguments
, str
);
23 structure::register_type("perl/history_entry", &typeid(history_entry
), &d
.d
);
26 static at_init
register_pdg(PDG::register_type
);
28 void PDG::register_type()
30 static struct_description pdg_d
= { create
};
31 YAML_INT_FIELD(pdg_d
, PDG
, dimension
);
32 YAML_INT_FIELD(pdg_d
, PDG
, cacheline
);
33 YAML_INT_FIELD(pdg_d
, PDG
, root
);
34 YAML_PTR_FIELD(pdg_d
, PDG
, placement
, str
);
35 YAML_SEQ_FIELD(pdg_d
, PDG
, nodes
, node
);
36 YAML_SEQ_FIELD(pdg_d
, PDG
, arrays
, array
);
37 YAML_SEQ_FIELD(pdg_d
, PDG
, dependences
, dependence
);
38 YAML_SEQ_FIELD(pdg_d
, PDG
, params
, parameter
);
39 YAML_PTR_FIELD(pdg_d
, PDG
, context
, IslSet
);
40 YAML_SEQ_FIELD(pdg_d
, PDG
, history
, history_entry
);
41 YAML_PTR_FIELD(pdg_d
, PDG
, name
, str
);
42 YAML_SEQ_FIELD(pdg_d
, PDG
, statement_dimensions
, int);
43 structure::register_type("perl/PDG", &typeid(PDG
), &pdg_d
.d
);
46 PDG
*PDG::Load(char *str
, isl_ctx
*ctx
)
48 return yaml::Load
<PDG
>(str
, ctx
);
51 PDG
*PDG::Load(FILE *fp
, isl_ctx
*ctx
)
53 return yaml::Load
<PDG
>(fp
, ctx
);
62 isl_ctx
*PDG::get_isl_ctx()
65 ctx
= isl_ctx_alloc();
72 /* Return the context of this PDG.
73 * If this PDG has no context, then return a universe parametric set
74 * with the same parameters as this PDG.
76 isl_set
*PDG::get_context_isl_set()
78 isl_ctx
*ctx
= get_isl_ctx();
82 set
= context
->get_isl_set(ctx
);
84 isl_space
*dims
= isl_space_params_alloc(ctx
, params
.size());
85 isl_dim_set_parameter_names(dims
, params
);
86 set
= isl_set_universe(dims
);
92 void PDG::add_history_line(const char *tool
, int argc
, char * argv
[])
94 history_entry
*he
= new history_entry();
95 he
->tool
= new str(string(tool
));
96 he
->version
= new str(string(pdg_version()));
97 for (int i
= 1; i
< argc
; ++i
)
98 he
->arguments
.push_back(new str(argv
[i
]));
99 history
.push_back(he
);
102 static at_init
register_array(array::register_type
);
104 void array::register_type()
106 static const char *at_names
[array::last
];
107 at_names
[input
] = "input";
108 at_names
[output
] = "output";
109 at_names
[temp
] = "temp";
110 static struct_description d
= { create
};
111 YAML_INT_FIELD(d
, array
, id
);
112 YAML_PTR_FIELD(d
, array
, name
, str
);
113 YAML_SEQ_FIELD(d
, array
, dims
, int);
114 YAML_PTR_FIELD(d
, array
, element_type
, str
);
115 YAML_ENUM_FIELD(d
, array
, type
, at_names
);
116 YAML_SEQ_FIELD(d
, array
, analysis_performed
, dependence_type
);
117 YAML_PTR_FIELD(d
, array
, value_bounds
, IslSet
);
118 YAML_INT_FIELD(d
, array
, uniquely_defined
);
119 YAML_INT_FIELD(d
, array
, killed
);
120 structure::register_type("perl/array", &typeid(array
), &d
.d
);
123 static at_init
register_parameter(parameter::register_type
);
125 void parameter::register_type()
127 static struct_description d
= { create
};
128 YAML_INT_FIELD(d
, parameter
, id
);
129 YAML_PTR_FIELD(d
, parameter
, name
, str
);
130 YAML_PTR_FIELD(d
, parameter
, value
, integer
);
131 structure::register_type("perl/parameter", &typeid(parameter
), &d
.d
);
134 void pdg::isl_dim_set_parameter_names(isl_space
*dim
,
135 const seq
<parameter
>& params
)
137 for (int i
= 0; i
< params
.size(); ++i
)
138 dim
= isl_space_set_dim_name(dim
, isl_dim_param
, i
,
139 params
[i
]->name
->s
.c_str());
142 isl_set
*pdg::isl_set_set_parameter_names(isl_set
*set
,
143 const seq
<parameter
>& params
)
145 for (int i
= 0; i
< params
.size(); ++i
)
146 set
= isl_set_set_dim_name(set
, isl_dim_param
, i
,
147 params
[i
]->name
->s
.c_str());
151 static at_init
register_access(pdg::access::register_type
);
153 void pdg::access::register_type()
155 static const char *at_names
[access::last
];
156 at_names
[write
] = "write";
157 at_names
[read
] = "read";
158 static struct_description d
= { create
};
159 YAML_PTR_FIELD(d
, pdg::access
, array
, pdg::array
);
160 YAML_ENUM_FIELD(d
, pdg::access
, type
, at_names
);
161 YAML_PTR_FIELD(d
, pdg::access
, map
, IslMap
);
162 YAML_INT_FIELD(d
, pdg::access
, nr
);
163 YAML_PTR_FIELD(d
, pdg::access
, extension
, IslMap
);
164 YAML_PTR_FIELD(d
, pdg::access
, extended_map
, IslMap
);
165 YAML_SEQ_FIELD(d
, pdg::access
, nested
, call_or_access
);
166 YAML_SEQ_FIELD(d
, pdg::access
, sources
, IslMap
);
167 structure::register_type("perl/access", &typeid(pdg::access
), &d
.d
);
170 static at_init
register_function_call(function_call::register_type
);
172 void function_call::register_type()
174 static struct_description s_d
= { create
};
175 YAML_SEQ_FIELD(s_d
, function_call
, arguments
, call_or_access
);
176 YAML_PTR_FIELD(s_d
, function_call
, name
, str
);
177 structure::register_type("perl/function_call", &typeid(function_call
), &s_d
.d
);
180 static at_init
register_call_or_access(call_or_access::register_type
);
182 void call_or_access::register_type()
184 static const char *cat_names
[call_or_access::last
];
185 cat_names
[t_access
] = "access";
186 cat_names
[t_call
] = "call";
187 static struct_description s_d
= { create
};
188 YAML_ENUM_FIELD(s_d
, pdg::call_or_access
, type
, cat_names
);
189 YAML_PTR_FIELD(s_d
, pdg::call_or_access
, access
, pdg::access
);
190 YAML_PTR_FIELD(s_d
, pdg::call_or_access
, call
, function_call
);
191 structure::register_type("perl/call_or_access", &typeid(call_or_access
), &s_d
.d
);
194 static at_init
register_stat(statement::register_type
);
196 void statement::register_type()
198 static struct_description s_d
= { create
};
199 YAML_INT_FIELD(s_d
, statement
, operation
);
200 YAML_INT_FIELD(s_d
, statement
, line
);
201 YAML_SEQ_FIELD(s_d
, statement
, accesses
, access
);
202 YAML_PTR_FIELD(s_d
, statement
, top_function
, function_call
);
203 YAML_SEQ_FIELD(s_d
, statement
, top_outputs
, access
);
204 structure::register_type("perl/statement", &typeid(statement
), &s_d
.d
);
207 static at_init
register_node(node::register_type
);
209 void node::register_type()
211 static struct_description node_d
= { create
};
212 YAML_INT_FIELD(node_d
, node
, nr
);
213 YAML_PTR_FIELD(node_d
, node
, name
, str
);
214 YAML_PTR_FIELD(node_d
, node
, source
, IslSet
);
215 YAML_PTR_FIELD(node_d
, node
, schedule
, IslMap
);
216 YAML_PTR_FIELD(node_d
, node
, statement
, pdg::statement
);
217 YAML_SEQ_FIELD(node_d
, node
, prefix
, int);
218 YAML_SEQ_FIELD(node_d
, node
, filters
, call_or_access
);
219 structure::register_type("perl/node", &typeid(node
), &node_d
.d
);
222 static at_init
register_dependence(dependence::register_type
);
224 void dependence::register_type()
226 static const char *dt_names
[dependence::last
];
227 dt_names
[flow
] = "flow";
228 dt_names
[anti
] = "anti";
230 dt_names
[pn_union
] = "pn_union";
231 dt_names
[pn_part
] = "pn_part";
232 dt_names
[pn_wire
] = "pn_wire";
233 dt_names
[pn_hold
] = "pn_hold";
234 dt_names
[pn_shift
] = "pn_shift";
235 dt_names
[reuse
] = "reuse";
236 dt_names
[reuse_pair
] = "reuse_pair";
237 dt_names
[output
] = "output";
238 dt_names
[uninitialized
] = "uninitialized";
239 static struct_description dependence_d
= { create
};
240 YAML_PTR_FIELD(dependence_d
, dependence
, relation
, IslMap
);
241 YAML_PTR_FIELD(dependence_d
, dependence
, extended_relation
, IslMap
);
242 YAML_PTR_FIELD(dependence_d
, dependence
, controlled_relation
, IslMap
);
243 YAML_PTR_FIELD(dependence_d
, dependence
, from
, pdg::node
);
244 YAML_PTR_FIELD(dependence_d
, dependence
, to
, pdg::node
);
245 YAML_PTR_FIELD(dependence_d
, dependence
, from_access
, pdg::access
);
246 YAML_PTR_FIELD(dependence_d
, dependence
, to_access
, pdg::access
);
247 YAML_ENUM_FIELD(dependence_d
, dependence
, type
, dt_names
);
248 YAML_PTR_FIELD(dependence_d
, dependence
, array
, pdg::array
);
249 YAML_SEQ_FIELD(dependence_d
, dependence
, from_controls
, str
);
250 YAML_SEQ_FIELD(dependence_d
, dependence
, to_controls
, str
);
251 YAML_INT_FIELD(dependence_d
, dependence
, reordering
);
252 YAML_INT_FIELD(dependence_d
, dependence
, multiplicity
);
253 YAML_PTR_FIELD(dependence_d
, dependence
, size
, enumerator
);
254 YAML_PTR_FIELD(dependence_d
, dependence
, container
, dependence
);
255 YAML_PTR_FIELD(dependence_d
, dependence
, value_size
, integer
);
256 structure::register_type("perl/dependence", &typeid(dependence
), &dependence_d
.d
);
258 static struct_description dependence_type_d
= { dependence_type::create
};
259 YAML_ENUM_FIELD(dependence_type_d
, dependence_type
, type
, dt_names
);
260 structure::register_type("perl/dependence_type", &typeid(dependence_type
), &dependence_type_d
.d
);
263 static at_init
register_enumerator(pdg::enumerator::register_type
);
265 void pdg::enumerator::register_type()
267 static struct_description e_d
= { create
, convert
};
268 structure::register_type("perl/PDG::enumerator", &typeid(enumerator
), &e_d
.d
);
271 void pdg::enumerator::init(SyckParser
*p
, SyckNode
*n
)
273 s
= new string(n
->data
.str
->ptr
, n
->data
.str
->len
);
276 serialize
*pdg::enumerator::convert(anchor_map
*am
, serialize
*node
,
277 const type_info
*type
)
279 str
*s
= dynamic_cast<str
*>(node
);
285 e
= new enumerator(new string(s
->s
));
292 void pdg::enumerator::dump(emitter
& e
)
295 yll_emitter_write_string(e
.e
, s
->c_str());
297 yll_emitter_write_int(e
.e
, value
);
302 pdg::enumerator::~enumerator()
308 static at_init
register_isl_set(IslSet::register_type
);
310 void IslSet::register_type()
312 static struct_description s_d
= { create
, convert
};
313 structure::register_type("", &typeid(IslSet
), &s_d
.d
);
316 serialize
*IslSet::convert(anchor_map
*am
, serialize
*node
,
317 const type_info
*type
)
319 str
*s
= dynamic_cast<str
*>(node
);
320 isl_ctx
*ctx
= (isl_ctx
*) am
->user
;
324 set
= isl_set_read_from_str(ctx
, s
->s
.c_str());
326 return new IslSet(set
);
332 void IslSet::dump(emitter
&e
)
338 yll_emitter_write_null(e
.e
);
342 p
= isl_printer_to_str(isl_set_get_ctx(set
));
343 p
= isl_printer_print_set(p
, set
);
344 s
= isl_printer_get_str(p
);
347 yll_emitter_write_string(e
.e
, s
);
352 static at_init
register_isl_map(IslMap::register_type
);
354 void IslMap::register_type()
356 static struct_description s_d
= { create
, convert
};
357 structure::register_type("", &typeid(IslMap
), &s_d
.d
);
360 serialize
*IslMap::convert(anchor_map
*am
, serialize
*node
,
361 const type_info
*type
)
363 str
*s
= dynamic_cast<str
*>(node
);
364 isl_ctx
*ctx
= (isl_ctx
*) am
->user
;
368 map
= isl_map_read_from_str(ctx
, s
->s
.c_str());
370 return new IslMap(map
);
376 void IslMap::dump(emitter
&e
)
382 yll_emitter_write_null(e
.e
);
386 p
= isl_printer_to_str(isl_map_get_ctx(map
));
387 p
= isl_printer_print_map(p
, map
);
388 s
= isl_printer_get_str(p
);
391 yll_emitter_write_string(e
.e
, s
);
396 /* Schedule the given dependence relations "map" according to the schedules
397 * of the source and target of "dep".
399 __isl_give isl_map
*pdg::schedule_dependence(PDG
*pdg
, pdg::dependence
*dep
,
400 __isl_take isl_map
*map
)
402 isl_map
*sr
= dep
->to
->schedule
->get_isl_map();
403 map
= isl_map_apply_range(map
, sr
);
405 isl_map
*sw
= dep
->from
->schedule
->get_isl_map();
406 map
= isl_map_apply_domain(map
, sw
);
412 __isl_give isl_map
*pdg::scatter_dependence(PDG
*pdg
, pdg::dependence
*dep
)
414 return schedule_dependence(pdg
, dep
, dep
->relation
->get_isl_map());
417 /* Assuming this is a read access, construct a map from the domain
418 * of the access relation to the access relation of the corresponding
419 * writes. If we are unable to determine the corresponding writes, then
420 * return a map to the read access.
422 * For example, if the access relation is
426 * and there is a single source of the form
428 * [W[0,i] -> A[]] -> [S[i] -> A[]]
430 * then the returned map is
432 * S[i] -> [W[0,i] -> A[]]
434 * If there are multiple writes involved, then the range of the result lives
435 * in different spaces.
437 * If no source was found then return
439 * S[i] -> [S[i] -> A[]]
441 __isl_give isl_union_map
*pdg::access::extract_access_map()
447 access_map
= map
->get_isl_map();
448 access_map
= isl_map_reverse(isl_map_domain_map(access_map
));
450 if (sources
.size() == 0)
451 return isl_union_map_from_map(access_map
);
453 ctx
= isl_map_get_ctx(access_map
);
454 res
= isl_union_map_empty(isl_space_params_alloc(ctx
, 0));
456 for (int i
= 0; i
< sources
.size(); ++i
) {
458 source_map
= sources
[i
]->get_isl_map();
459 source_map
= isl_map_reverse(source_map
);
460 source_map
= isl_map_apply_range(isl_map_copy(access_map
),
462 res
= isl_union_map_add_map(res
, source_map
);
465 isl_map_free(access_map
);
470 /* Return the number of outer loops that are affected by filters.
472 * A loop iterator is affected by a filter if it is involved
473 * in any of the iteration domain constraints that also involves filters,
474 * if any of the filter accesses depends on the loop iterator,
475 * or if any of the sources of a filter depends on the loop iterator.
476 * If no sources were recorded, then we conservatively assume that
477 * all loops are affected by filters.
479 int node::get_filter_depth()
485 if (filter_depth
>= 0)
489 value
= isl_set_unwrap(source
->get_isl_set());
490 n_in
= isl_map_dim(value
, isl_dim_in
);
491 n_out
= isl_map_dim(value
, isl_dim_out
);
493 dom
= isl_map_domain(isl_map_copy(value
));
494 value
= isl_map_gist_domain(value
, isl_set_copy(dom
));
495 for (int j
= n_in
- 1; j
>= 0; --j
) {
496 if (!isl_map_involves_dims(value
, isl_dim_in
, j
, 1))
498 if (j
>= filter_depth
)
499 filter_depth
= j
+ 1;
503 for (int i
= 0; i
< n_out
; ++i
) {
504 pdg::call_or_access
*coa
;
507 assert(coa
->type
== pdg::call_or_access::t_access
);
509 if (coa
->access
->sources
.size() == 0) {
514 for (int j
= 0; j
< coa
->access
->sources
.size(); ++j
) {
516 map
= coa
->access
->sources
[j
]->get_isl_map();
517 map
= isl_map_zip(map
);
518 map
= isl_set_unwrap(isl_map_domain(map
));
519 map
= isl_map_gist_range(map
, isl_set_copy(dom
));
521 for (int k
= n_in
- 1; k
>= 0; --k
) {
522 if (!isl_map_involves_dims(map
,
525 if (k
>= filter_depth
)
526 filter_depth
= k
+ 1;
533 for (int j
= n_in
- 1; j
>= 0; --j
) {
534 if (!isl_map_involves_dims(coa
->access
->map
->map
,
537 if (j
>= filter_depth
)
538 filter_depth
= j
+ 1;