65class DirectedGraph :
public std::enable_shared_from_this<DirectedGraph> {
69 typedef std::shared_ptr<DGVertex> ver_ptr;
70 typedef std::shared_ptr<DGArc> arc_ptr;
72 typedef std::multimap<key_type, ver_ptr> VPtrAssociativeContainer;
73 typedef std::list<ver_ptr> VPtrSequenceContainer;
75 typedef VPtrSequenceContainer targets;
76#if USE_ASSOCCONTAINER_BASED_DIRECTEDGRAPH
77 typedef VPtrAssociativeContainer vertices;
79 typedef VPtrSequenceContainer vertices;
81 typedef targets::iterator target_iter;
82 typedef targets::const_iterator target_citer;
83 typedef vertices::iterator ver_iter;
84 typedef vertices::const_iterator ver_citer;
88 typedef unsigned int size;
89 typedef std::vector<address> addresses;
93 static inline const ver_ptr& vertex_ptr(
94 const VPtrAssociativeContainer::value_type& v) {
97 static inline const ver_ptr& vertex_ptr(
98 const VPtrSequenceContainer::value_type& v) {
102 static inline ver_ptr& vertex_ptr(VPtrAssociativeContainer::value_type& v) {
105 static inline ver_ptr& vertex_ptr(VPtrSequenceContainer::value_type& v) {
126 const std::shared_ptr<DGVertex>&
find(
127 const std::shared_ptr<DGVertex>& v)
const {
128 return vertex_is_on(v);
134 std::shared_ptr<DGVertex>
append_vertex(
const std::shared_ptr<DGVertex>& v);
152 template <
class I,
class RR>
154 target->make_a_target();
155 recurse<I, RR>(target);
170 typedef typename RR::TargetType TT;
171 typedef vertices::iterator iter;
172 for (iter v = stack_.begin(); v != stack_.end(); ++v) {
173 ver_ptr& vptr = vertex_ptr(*v);
174 if ((vptr)->num_exit_arcs() != 0)
continue;
175 std::shared_ptr<TT> tptr = std::dynamic_pointer_cast<TT, DGVertex>(v);
176 if (tptr == 0)
continue;
178 std::shared_ptr<RR> rr0(
new RR(tptr));
179 const int num_children = rr0->num_children();
181 for (
int c = 0; c < num_children; c++) {
182 std::shared_ptr<DGVertex> child = rr0->child(c);
184 tptr->add_exit_arc(
arc);
197 void apply(
const std::shared_ptr<Strategy>& strategy,
198 const std::shared_ptr<Tactic>& tactic);
200 typedef void (
DGVertex::*DGVertexMethodPtr)();
204 template <DGVertexMethodPtr method>
206 ((
vertex.get())->*method)();
207 typedef DGVertex::ArcSetType::const_iterator aciter;
210 for (aciter a = abegin; a != aend; ++a) apply_at<method>((*a)->dest());
214 template <
class Method>
215 void foreach (Method& m) {
216 typedef vertices::iterator iter;
217 for (iter v = stack_.begin(); v != stack_.end(); ++v) {
218 ver_ptr& vptr = vertex_ptr(*v);
224 template <
class Method>
225 void foreach (Method& m)
const {
226 typedef vertices::const_iterator citer;
227 for (citer v = stack_.begin(); v != stack_.end(); ++v) {
228 const ver_ptr& vptr = vertex_ptr(*v);
233 template <
class Method>
235 typedef vertices::reverse_iterator riter;
236 for (riter v = stack_.rbegin(); v != stack_.rend(); ++v) {
237 ver_ptr& vptr = vertex_ptr(*v);
243 template <
class Method>
245 typedef vertices::const_reverse_iterator criter;
246 for (criter v = stack_.rbegin(); v != stack_.rend(); ++v) {
247 const ver_ptr& vptr = vertex_ptr(*v);
275 void print_to_dot(
bool symbols, std::ostream& os = std::cout)
const;
285 void generate_code(
const std::shared_ptr<CodeContext>& context,
286 const std::shared_ptr<MemoryManager>& memman,
287 const std::shared_ptr<ImplicitDimensions>& dims,
288 const std::shared_ptr<CodeSymbols>& args,
289 const std::string&
label, std::ostream& decl,
302 unsigned int nchildren = rr->num_children();
303 unsigned int nchildren_on_stack = 0;
304 for (
unsigned int c = 0; c < nchildren; c++) {
305 if (!vertex_is_on(rr->rr_child(c)))
308 nchildren_on_stack++;
311 return nchildren_on_stack;
315 std::shared_ptr<GraphRegistry>&
registry() {
return registry_; }
316 const std::shared_ptr<GraphRegistry>&
registry()
const {
return registry_; }
319 const std::string&
label()
const {
return label_; }
321 void set_label(
const std::string& new_label) { label_ = new_label; }
333 addresses target_accums_;
338 typedef std::map<std::string, bool> FuncNameContainer;
342 FuncNameContainer func_names_;
344#if !USE_ASSOCCONTAINER_BASED_DIRECTEDGRAPH
345 static const unsigned int default_size_ = 100;
349 std::shared_ptr<GraphRegistry> registry_;
351 std::shared_ptr<InternalGraphRegistry> iregistry_;
354 std::shared_ptr<InternalGraphRegistry>& iregistry() {
return iregistry_; }
355 const std::shared_ptr<InternalGraphRegistry>& iregistry()
const {
361 std::shared_ptr<DGVertex> add_vertex(
const std::shared_ptr<DGVertex>&);
364 void add_new_vertex(
const std::shared_ptr<DGVertex>&);
366 const std::shared_ptr<DGVertex>& vertex_is_on(
367 const std::shared_ptr<DGVertex>& vertex)
const;
369 void del_vertex(vertices::iterator&);
373 template <
class I,
class RR>
374 void recurse(
const std::shared_ptr<I>& vertex) {
375 std::shared_ptr<DGVertex> dgvertex = add_vertex(vertex);
376 if (dgvertex != vertex)
return;
378 std::shared_ptr<RR> rr0(
new RR(vertex));
379 const int num_children = rr0->num_children();
381 for (
int c = 0; c < num_children; c++) {
382 std::shared_ptr<DGVertex> child = rr0->child(c);
383 std::shared_ptr<DGArc> arc(
new DGArcRel<RR>(vertex, child, rr0));
384 vertex->add_exit_arc(arc);
386 std::shared_ptr<I> child_cast =
387 std::dynamic_pointer_cast<I, DGVertex>(child);
389 throw std::runtime_error(
390 "DirectedGraph::recurse(const std::shared_ptr<I>& vertex) -- "
391 "dynamic cast failed, most probably this is a logic error!");
392 recurse<I, RR>(child_cast);
400 void recurse(
const std::shared_ptr<DGVertex>& vertex) {
401 std::shared_ptr<DGVertex> dgvertex = add_vertex(vertex);
402 if (dgvertex != vertex)
return;
404 typedef typename RR::TargetType TT;
405 std::shared_ptr<TT> tptr = std::dynamic_pointer_cast<TT, DGVertex>(vertex);
406 if (tptr == 0)
return;
408 std::shared_ptr<RR> rr0(
new RR(tptr));
409 const int num_children = rr0->num_children();
411 for (
int c = 0; c < num_children; c++) {
412 std::shared_ptr<DGVertex> child = rr0->child(c);
413 std::shared_ptr<DGArc> arc(
new DGArcRel<RR>(vertex, child, rr0));
414 vertex->add_exit_arc(arc);
423 void apply_to(
const std::shared_ptr<DGVertex>& vertex,
424 const std::shared_ptr<Strategy>& strategy,
425 const std::shared_ptr<Tactic>& tactic);
428 std::shared_ptr<DGVertex> insert_expr_at(
429 const std::shared_ptr<DGVertex>& where,
430 const std::shared_ptr<AlgebraicOperator<DGVertex> >& expr);
433 void replace_rr_with_expr();
436 void remove_trivial_arithmetics();
441 void handle_trivial_nodes(
const std::shared_ptr<CodeContext>& context);
443 void remove_disconnected_vertices();
447 void find_subtrees();
450 void find_subtrees_from(
const std::shared_ptr<DGVertex>& v);
456 bool remove_vertex_at(
const std::shared_ptr<DGVertex>& v1,
457 const std::shared_ptr<DGVertex>& v2);
460 std::shared_ptr<DGVertex> first_to_compute_;
462 void prepare_to_traverse();
464 void traverse_from(
const std::shared_ptr<DGArc>&);
466 void schedule_computation(
const std::shared_ptr<DGVertex>&);
470 void allocate_mem(
const std::shared_ptr<MemoryManager>& memman,
471 const std::shared_ptr<ImplicitDimensions>& dims,
472 unsigned int min_size_to_alloc = 1);
474 void assign_symbols(
const std::shared_ptr<CodeContext>& context,
475 const std::shared_ptr<ImplicitDimensions>& dims);
478 void assign_oper_symbol(
const std::shared_ptr<CodeContext>& context,
479 std::shared_ptr<DGVertex>& v);
481 void print_def(
const std::shared_ptr<CodeContext>& context, std::ostream& os,
482 const std::shared_ptr<ImplicitDimensions>& dims,
483 const std::shared_ptr<CodeSymbols>& args);
490 bool cannot_enclose_in_outer_vloop()
const;