2 * Project: libFIRM/extension module/GRS-matcher
3 * File name: ext/action.c
4 * Purpose: funcytions to construct for libfirm grs actions
6 * Modified by: Andreas Schoesser
7 * Created: 29. August 2005
9 * Copyright: (c) 2005 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
17 #define ext_grs_PSEUDO_PREFIX "_pseudo__"
19 #define MAX(a,b) (a)>=(b) ? (a) : (b)
22 /* counter to create action ids from */
23 static int action_counter = 0;
25 /* obstack to store actions on */
26 static struct obstack obst;
27 /* tells whether the obstack has already been initialized */
28 static int obst_init = 0;
32 static int not_injective = 0;
33 static int multiple_entry = 0;
34 static int already_exists = 0;
37 /* a pointer to pointer map elem */
40 ext_grs_elem_kind_t kind;
46 ext_grs_ptr_map_entry_t;
48 int ptr_map_cmp_func(const void *elt, const void *key) {
50 ext_grs_ptr_map_entry_t *entry1 = (ext_grs_ptr_map_entry_t *) elt;
51 ext_grs_ptr_map_entry_t *entry2 = (ext_grs_ptr_map_entry_t *) key;
53 if (entry1->pre != entry2->pre && entry1->img == entry2->img)
56 if (entry1->pre == entry2->pre && entry1->img != entry2->img)
59 if (entry1->pre == entry2->pre && entry1->img == entry2->img)
62 return entry1->pre != entry2->pre;
68 static void init_graph(ext_grs_graph_t *graph,
69 ext_grs_action_t *act, ext_grs_graph_kind_t kind)
71 memset(graph, 0, sizeof(*graph));
75 LC_INIT_LIST_HEAD(& graph->nodes);
76 LC_INIT_LIST_HEAD(& graph->edges);
81 * Copy all nodes into the action and gen pseudo edges
82 * modeling the explicit matching of a node
83 * PseudoEdge == Edge modelled as a node
85 static int import_graph_info(ext_grs_action_t *action, ext_grs_graph_t *graph)
87 int edge_aiid = action->max_edge_aiid;
91 assert (action->kind != ext_grs_k_replacement &&
92 "import_graph_info() is not meant for calling on replacement graphs");
95 /* init the graphs root node */
96 graph->root_node.kind = ext_grs_k_pseudo_node;
97 graph->root_node.graph = graph;
98 LC_INIT_LIST_HEAD(& graph->root_node.edges[ext_grs_in]);
99 LC_INIT_LIST_HEAD(& graph->root_node.edges[ext_grs_out]);
100 graph->root_node.name = ext_grs_PSEUDO_PREFIX "root_node";
102 lc_list_for_each (pos, & graph->nodes) {
104 ext_grs_node_t *node = lc_list_entry(pos, ext_grs_node_t, node_list);
105 ext_grs_edge_t *pseudo_edge = obstack_alloc(&obst, sizeof(*pseudo_edge));
107 memset(pseudo_edge, 0, sizeof(*pseudo_edge));
109 /* store the node in the actions node array */
110 if (action->nodes[node->aiid] == NULL) {
111 action->nodes[node->aiid] = node;
114 printf("module ext/grs: ERROR in function ext_grs_act_mature()\n");
115 printf(" Multiple assigned node id encountered.\n");
116 printf(" You may have added nodes with the same id via ext_grs_act_add_node().\n\n");
120 /* for each node setup the pseudo edge modeling the
121 * explicit matching of that node */
122 pseudo_edge->graph = graph;
123 pseudo_edge->kind = ext_grs_k_pseudo_edge;
124 pseudo_edge->aiid = ++edge_aiid;
125 pseudo_edge->arg = node;
126 pseudo_edge->func = & graph->root_node;
127 pseudo_edge->genuine_elem.kind = ext_grs_k_node;
128 pseudo_edge->genuine_elem.val.n = node;
129 pseudo_edge->name = obstack_alloc(
131 (1 + strlen(ext_grs_PSEUDO_PREFIX) + strlen(node->name)) * sizeof(char)
133 strcpy(pseudo_edge->name, ext_grs_PSEUDO_PREFIX);
134 strcat(pseudo_edge->name, node->name);
136 /* add the pseudo edge to the graphs edge list */
137 lc_list_add(& pseudo_edge->edge_list, & graph->edges);
138 /* add the pseudo edge to the tgt- and src-nodes in- and out-lists */
139 lc_list_add(& pseudo_edge->list[ext_grs_in],
140 & pseudo_edge->func->edges[ext_grs_in]);
141 lc_list_add(& pseudo_edge->list[ext_grs_out],
142 & pseudo_edge->arg->edges[ext_grs_out]);
143 /* add the pseudo edge to the action */
144 action->edges[edge_aiid] = pseudo_edge;
147 /* copy all pattern edges into the action and for every
148 * edge gen a pseudo edge modeling the traversal of the original edge
149 * against its direction */
150 lc_list_for_each_safe (pos, n, & graph->edges) {
152 ext_grs_edge_t *edge = lc_list_entry(pos, ext_grs_edge_t, edge_list);
153 ext_grs_edge_t *pseudo_edge;
155 if (edge->kind == ext_grs_k_pseudo_edge)
158 pseudo_edge = obstack_alloc(&obst, sizeof(*pseudo_edge));
159 memset(pseudo_edge, 0, sizeof(*pseudo_edge));
161 /* store the node in the actions node array */
162 action->edges[edge->aiid] = edge;
164 /* for each edge setup the pseudo edge modelling the
165 * against-direction-traversal of that edge */
166 pseudo_edge->graph = edge->graph;
167 pseudo_edge->kind = ext_grs_k_pseudo_edge;
168 pseudo_edge->aiid = ++edge_aiid;
169 pseudo_edge->arg = edge->func;
170 pseudo_edge->func = edge->arg;
171 pseudo_edge->genuine_elem.kind = ext_grs_k_edge;
172 pseudo_edge->genuine_elem.val.e = edge;
173 pseudo_edge->name = obstack_alloc(
175 (1 + strlen(ext_grs_PSEUDO_PREFIX) + strlen(edge->name)) * sizeof(char)
177 strcpy(pseudo_edge->name, ext_grs_PSEUDO_PREFIX);
178 strcat(pseudo_edge->name, edge->name);
180 /* add the pseudo edge to the graphs edge list */
181 lc_list_add(& pseudo_edge->edge_list, & graph->edges);
182 /* add the pseudo edge to the tgt- and src-nodes in- and out-lists */
183 lc_list_add(& pseudo_edge->list[ext_grs_in],
184 & pseudo_edge->func->edges[ext_grs_in]);
185 lc_list_add(& pseudo_edge->list[ext_grs_out],
186 & pseudo_edge->arg->edges[ext_grs_out]);
187 /* add the pseudo edge to the action */
188 action->edges[edge_aiid] = pseudo_edge;
189 /* each actual edge knows the respective pseudo edge */
190 edge->backward_edge = pseudo_edge;
193 action->max_edge_aiid = edge_aiid;
200 static void set_up_condition_stuff(ext_grs_action_t *action) {
205 /* alloc space for bitsets telling which (pattern or negative) nodes and edges
206 * are involved in which conditions and vice versa wich conditions are refered
207 * by which nodes or edges */
209 obstack_alloc(&obst, action->n_conditions * sizeof(*action->conditions));
210 action->conds_involved_nodes =
211 obstack_alloc(&obst, action->n_conditions * sizeof(*action->conds_involved_nodes));
212 action->conds_involved_edges =
213 obstack_alloc(&obst, action->n_conditions * sizeof(*action->conds_involved_edges));
215 action->nodes_refering_conds =
216 obstack_alloc(&obst, (action->max_node_aiid+1) * sizeof(*action->nodes_refering_conds));
217 action->edges_refering_conds =
218 obstack_alloc(&obst, (action->max_edge_aiid+1) * sizeof(*action->edges_refering_conds));
220 /* alloc a bitset for every (pattern or negative) node and edge */
221 for(i = 0; i <= action->max_node_aiid; i++)
222 action->nodes_refering_conds[i] =
223 lc_bitset_obstack_alloc(&obst, action->n_conditions);
224 for(i = 0; i <= action->max_edge_aiid; i++)
225 action->edges_refering_conds[i] =
226 lc_bitset_obstack_alloc(&obst, action->n_conditions);
228 /* alloc two bitset for every condition (telling which nodes and edges are involved),
229 * and setup the hole condition information */
231 lc_list_for_each(pos, & action->listed_conditions) {
235 ext_grs_cond_descr_t *cond_descr =
236 lc_list_entry(pos, ext_grs_cond_descr_t, condition_list);
238 action->conditions[i] = cond_descr->condition;
240 /* alloc the bitset, which represents the information about the
241 * (pattern or negative) nodes involved in the current condition */
242 bs = action->conds_involved_nodes[i] =
243 lc_bitset_obstack_alloc(&obst, action->max_node_aiid+1);
245 /* store that info in the bitset */
246 for (j = 0; j < cond_descr->n_nodes; j++) {
247 int aiid = cond_descr->nodes[j]->aiid;
248 lc_bitset_set(bs, aiid);
249 lc_bitset_set(action->nodes_refering_conds[aiid], i); // CRASH!!!
252 /* alloc the bitset, which represents the information about the
253 * (pattern or negative) edges involved in the current condition */
254 bs = action->conds_involved_edges[i] =
255 lc_bitset_obstack_alloc(&obst, action->max_edge_aiid+1);
257 /* store that info in the bitset */
258 for (j = 0; j < cond_descr->n_edges; j++) {
259 int aiid = cond_descr->edges[j]->aiid;
260 lc_bitset_set(bs, aiid);
261 lc_bitset_set(action->edges_refering_conds[aiid], i);
267 assert(i == action->n_conditions && "inconsistent number of registered condition functions");
274 /** create a new graph action of the given kind */
275 ext_grs_action_t *ext_grs_new_action(ext_grs_action_kind_t kind, char *name) {
277 ext_grs_action_t *action;
279 /* allocate a new action */
280 action = (ext_grs_action_t *) obstack_alloc(&obst, sizeof(*action));
281 if (action == NULL) {
282 printf("module ext/grs: internal ERROR in function ext_grs_act_allow_nodes_hom()\n");
283 printf(" Failed to allocate a new action.\n\n");
286 memset(action, 0, sizeof(*action));
287 /* set the actions kind and id */
289 action->id = action_counter++;
291 action->max_node_aiid = -1;
292 action->max_edge_aiid = -1;
293 action->max_repl_node_aiid = -1;
294 action->max_repl_edge_aiid = -1;
296 LC_INIT_LIST_HEAD(& action->negatives);
297 LC_INIT_LIST_HEAD(& action->listed_conditions);
298 LC_INIT_LIST_HEAD(& action->listed_evals);
301 /* allocate this actions pattern graph */
302 action->pattern = (ext_grs_graph_t *)
303 obstack_alloc(&obst, sizeof(*(action->pattern)));
304 if (action->pattern == NULL) {
305 printf("module ext/grs: internal ERROR in function ext_grs_new_action()\n");
306 printf(" Failed to allocate a pattern graph for the new action.\n\n");
307 obstack_free(&obst, action);
310 init_graph(action->pattern, action, ext_grs_k_pattern);
312 /* if action is a rule, allocate a replacemant graph */
313 if (kind == ext_grs_k_rule) {
314 action->replacement = (ext_grs_graph_t *)
315 obstack_alloc(&obst, sizeof(*(action->replacement)));
316 if (action->replacement == NULL) {
317 printf("module ext/grs: internal ERROR in function ext_grs_new_action()\n");
318 printf(" Failed to allocate a replacement graph for the new action.\n\n");
319 obstack_free(&obst, action);
322 init_graph(action->replacement, action, ext_grs_k_replacement);
325 action->kept_elems = lc_pset_new(ptr_map_cmp_func, 256);
330 /** get the kind of an action */
331 ext_grs_action_kind_t ext_grs_act_get_kind(ext_grs_action_t *act) {
335 /** impose a new negative graph pattern on the given action */
336 ext_grs_graph_t *ext_grs_act_impose_negative(ext_grs_action_t *action) {
338 ext_grs_graph_t *negative;
340 /* if action is already mature no further changes are allowed */
341 if (action->mature) return NULL;
343 /* create new graph */
344 negative = (ext_grs_graph_t *) obstack_alloc(&obst, sizeof(*negative));
345 if (negative == NULL) {
346 printf("module ext/grs: ERROR in function ext_grs_act_impose_negative()\n");
347 printf(" failed to allocate a new action!\n");
350 init_graph(negative, action, ext_grs_k_negative);
352 /* store the new graph in the given action
353 * as a negative pattern graph */
354 lc_list_add(& negative->negative_list, & action->negatives);
360 /** get the pattern graph of an action */
361 ext_grs_graph_t *ext_grs_act_get_pattern(ext_grs_action_t *action) {
362 return action->pattern;
365 /** get the replacement graph of an action */
366 ext_grs_graph_t *ext_grs_act_get_replacement(ext_grs_action_t *action) {
368 if (action->kind == ext_grs_k_rule) {
369 assert (action->replacement->kind == ext_grs_k_replacement &&
370 "replacement graph has wrong kind");
371 return action->replacement;
374 /* if action is no rule, no replacement can be returned */
378 /** add a node to a given pattern graph */
379 ext_grs_node_t *ext_grs_act_add_node(
380 ext_grs_graph_t *graph, char *name, ir_op *op, ir_mode *mode, int id)
382 ext_grs_node_t *new_node;
385 printf("module ext/grs: ERROR in function ext_grs_add_node()\n");
386 printf(" Given graph was NULL!\n");
390 printf("module ext/grs: ERROR in function ext_grs_add_node()\n");
391 printf(" Given name was NULL!\n");
395 printf("module ext/grs: ERROR in function ext_grs_add_node()\n");
396 printf(" Given op was NULL!\n");
400 printf("module ext/grs: ERROR in function ext_grs_add_node()\n");
401 printf(" Given mode was NULL!\n");
405 printf("module ext/grs: ERROR in function ext_grs_add_node()\n");
406 printf(" Negative node id was given.\n");
409 if (graph->action->mature) {
410 printf("module ext/grs: ERROR in function ext_grs_add_node()\n");
411 printf(" Given graph belongs to a mature action.\n");
415 new_node = obstack_alloc(&obst, sizeof(*new_node));
416 memset(new_node, 0, sizeof(*new_node));
418 new_node->kind = ext_grs_k_node;
419 new_node->graph = graph;
420 new_node->name = name;
421 new_node->mode = mode;
424 new_node->related_node = NULL;
425 LC_INIT_LIST_HEAD(& new_node->edges[ext_grs_in]);
426 LC_INIT_LIST_HEAD(& new_node->edges[ext_grs_out]);
428 /* add node to the graph */
430 lc_list_add(& new_node->node_list, & graph->nodes);
432 /* add node to the graphs action...? */
433 /* ...this is done by the the mature function when
434 * pseudo nodes and edges are created! */
436 if (graph->kind == ext_grs_k_replacement) {
437 graph->action->max_repl_node_aiid = MAX(id, graph->action->max_repl_node_aiid);
440 assert((graph->kind == ext_grs_k_pattern || graph->kind == ext_grs_k_negative)
441 && "given graph has invalid kind");
442 graph->action->max_node_aiid = MAX(id, graph->action->max_node_aiid);
448 ext_grs_node_t *ext_grs_act_add_related_node(ext_grs_graph_t *graph,
449 char *name, ir_op *op, ir_mode *mode, int id, ext_grs_node_t *positive_node)
451 ext_grs_node_t *added_node = ext_grs_act_add_node(graph, name, op, mode, id);
452 ext_grs_act_relate_neg_node(positive_node, added_node);
456 ext_grs_node_t *ext_grs_act_add_node_to_keep(ext_grs_graph_t *graph,
457 char *name, ir_op *op, ir_mode *mode, int id, ext_grs_node_t *pattern_node)
459 ext_grs_node_t *added_node = ext_grs_act_add_node(graph, name, op, mode, id);
460 ext_grs_act_announce_kept_node(pattern_node, added_node);
465 /** add an edge to a given pattern graph */
466 ext_grs_edge_t *ext_grs_act_add_edge(ext_grs_graph_t *graph,
467 char *name, int pos, ext_grs_node_t *arg, ext_grs_node_t *func, int id)
469 ext_grs_edge_t *new_edge;
472 printf("module ext/grs: ERROR in function ext_grs_add_edge()\n");
473 printf(" Given graph was NULL.\n\n");
477 printf("module ext/grs: ERROR in function ext_grs_add_edge()\n");
478 printf(" Given name was NULL.\n\n");
482 printf("module ext/grs: ERROR in function ext_grs_add_edge()\n");
483 printf(" Given argument node was NULL.\n\n");
487 printf("module ext/grs: ERROR in function ext_grs_add_edge()\n");
488 printf(" Given function node was NULL.\n\n");
492 printf("module ext/grs: ERROR in function ext_grs_add_edge()\n");
493 printf(" Given edge id was negative.\n\n");
496 if (graph->action->mature) {
497 printf("module ext/grs: ERROR in function ext_grs_add_edge()\n");
498 printf(" Tried to add an edge to a graph of a mature action.\n\n");
502 if (func->op == op_Bad) {
503 printf("module ext/grs: WARNING in function ext_grs_add_edge()\n");
504 printf(" Added an incoming edge to a Bad node, this leads\n");
505 printf(" to a malformed graph.\n\n");
509 new_edge = obstack_alloc(&obst, sizeof(*new_edge));
510 memset(new_edge, 0, sizeof(*new_edge));
512 new_edge->kind = ext_grs_k_edge;
513 new_edge->graph = graph;
514 new_edge->name = name;
516 new_edge->func = func;
519 new_edge->related_edge = 0;
521 /* add edge to the graph */
523 lc_list_add(& new_edge->edge_list, & graph->edges);
525 /* add edge to tgt- and src-nodes in and out lists */
526 lc_list_add(&new_edge->list[ext_grs_in], & new_edge->func->edges[ext_grs_in]);
527 lc_list_add(&new_edge->list[ext_grs_out], & new_edge->arg->edges[ext_grs_out]);
529 /* add edge to the graphs action...? */
530 /* ...this is done by the the mature function when
531 * pseudo nodes and edges are created! */
533 if (graph->kind == ext_grs_k_replacement) {
534 graph->action->max_repl_edge_aiid = MAX(id, graph->action->max_repl_edge_aiid);
537 assert((graph->kind == ext_grs_k_pattern || graph->kind == ext_grs_k_negative)
538 && "given graph has invalid kind");
539 graph->action->max_edge_aiid = MAX(id, graph->action->max_edge_aiid);
545 ext_grs_edge_t *ext_grs_act_add_related_edge(ext_grs_graph_t *graph,
546 char *name, int pos, ext_grs_node_t *arg, ext_grs_node_t *func, int id, ext_grs_edge_t *positive_edge)
548 ext_grs_edge_t *added_edge = ext_grs_act_add_edge(graph, name, pos, arg, func, id);
549 ext_grs_act_relate_neg_edge(positive_edge, added_edge);
553 ext_grs_edge_t *ext_grs_act_add_edge_to_keep(ext_grs_graph_t *graph,
554 char *name, int pos, ext_grs_node_t *arg, ext_grs_node_t *func, int id, ext_grs_edge_t *pattern_edge)
556 ext_grs_edge_t *added_edge = ext_grs_act_add_edge(graph, name, pos, arg, func, id);
557 ext_grs_act_announce_kept_edge(pattern_edge, added_edge);
561 /** mature an action, it is not possible to make any
562 * changes to this actions pattern afterwards */
564 int ext_grs_act_mature(ext_grs_action_t *action) {
567 lc_list_t *pos, *pos1;
573 int n_pseudo_nodes = 0;
574 int n_pseudo_edges = 0;
577 if (action->mature) {
578 printf("module ext/grs: ERROR in function ext_grs_act_mature()\n");
579 printf(" given action is already mature!\n");
583 /* ................ 1 ................................................. */
585 /* compute the overall number of real nodes and negative nodes */
586 n_nodes = action->pattern->n_nodes;
587 lc_list_for_each(pos, &action->negatives) {
588 ext_grs_graph_t *neg =
589 lc_list_entry(pos, ext_grs_graph_t, negative_list);
590 n_neg_nodes += neg->n_nodes;
592 /* compute the overall number of real edges and negative edges */
593 n_edges = action->pattern->n_edges;
594 lc_list_for_each(pos, &action->negatives) {
595 ext_grs_graph_t *neg =
596 lc_list_entry(pos, ext_grs_graph_t, negative_list);
597 n_neg_edges += neg->n_edges;
600 /* alloc space for real and negative nodes */
602 obstack_alloc(&obst, (action->max_node_aiid+1) * sizeof(ext_grs_node_t));
603 memset(action->nodes, 0 , (action->max_node_aiid+1) * sizeof(ext_grs_node_t));
604 /* alloc space for real, negative and pseudo edges */
607 (action->max_edge_aiid+1 + n_nodes + n_neg_nodes + n_edges) * sizeof(ext_grs_edge_t));
608 memset(action->edges, 0,
609 (action->max_edge_aiid+1 + n_nodes + n_neg_nodes + n_edges) * sizeof(ext_grs_edge_t));
612 /* ................ 2 ................................................. */
615 ret = import_graph_info(action, action->pattern);
618 lc_list_for_each(pos, &action->negatives) {
620 ext_grs_graph_t *neg =
621 lc_list_entry(pos, ext_grs_graph_t, negative_list);
622 ret = import_graph_info(action, neg);
626 /* ................ 3 ................................................. */
628 /* there's a pseudo edge for each node and a backward pseudo edge
629 * for each real and each negative edge */
630 n_pseudo_edges = n_nodes + n_edges + n_neg_edges;
633 /* setup space for information about homomorphic node matching and about critical
634 * nodes and edges. A node or edge is critical when it multiple matching may be
635 * harmful for parallel rule application */
636 if (action->max_node_aiid >= 0) {
638 obstack_alloc(&obst, (action->max_node_aiid+1) * sizeof(*(action->hom)));
639 action->node_critical = obstack_alloc(&obst,
640 (action->max_node_aiid+1) * sizeof(*(action->node_critical)));
643 action->pattern_node_kept =
644 obstack_alloc(&obst, (action->max_node_aiid+1) * sizeof(*action->pattern_node_kept));
646 for (i=0; i <= action->max_node_aiid; i++) {
648 action->hom[i] = obstack_alloc(
649 &obst, (action->max_node_aiid+1) * sizeof(**(action->hom)));
650 memset(action->hom[i], 0,
651 (action->max_node_aiid+1) * sizeof(*(action->hom[i])));
653 if (!action->nodes[i]) continue;
655 /* by default every node is critical (unless it can be
656 * proofen that it is not) */
657 action->node_critical[i] = 1;
658 /* by default no node is kept */
659 action->pattern_node_kept[i] = -1;
662 if (action->max_edge_aiid >= 0) {
663 action->edge_critical = obstack_alloc(&obst,
664 (action->max_edge_aiid+1) * sizeof(*(action->edge_critical)));
665 action->pattern_edge_kept =
666 obstack_alloc(&obst, (action->max_edge_aiid+1) * sizeof(*action->pattern_edge_kept));
669 for (i=0; i <= action->max_edge_aiid; i++) {
670 /* by default each node is critical (unless it can be
671 * proofen that it is not) */
672 action->edge_critical[i] = 1;
674 if (!action->edges[i]) continue;
676 /* by default no edge is kept */
677 action->pattern_edge_kept[i] = -1;
681 /* .................................... 4 .................................. */
682 set_up_condition_stuff(action);
684 action->n_nodes = n_nodes;
685 action->n_edges = n_edges;
687 action->n_neg_nodes = n_neg_nodes;
688 action->n_neg_edges = n_neg_edges;
690 action->n_pseudo_nodes = n_pseudo_nodes;
691 action->n_pseudo_edges = n_pseudo_edges;
696 /* if the action is of kind test, no replacement information has to be set up */
697 if (action->kind == ext_grs_k_test) {
698 /* set mature flag */
706 /* setup replacement information */
709 if (action->max_repl_node_aiid >= 0) {
710 action->replacement_nodes = obstack_alloc(&obst,
711 (action->max_repl_node_aiid+1) * sizeof(*action->replacement_nodes));
712 memset(action->replacement_nodes, 0,
713 (action->max_repl_node_aiid+1) * sizeof(*action->replacement_nodes));
714 action->replacement_node_kept = obstack_alloc(&obst,
715 (action->max_repl_node_aiid+1) * sizeof(*action->replacement_node_kept));
717 for (i = 0; i <= action->max_repl_node_aiid; i++)
718 /* by default ALL nodea are newly inserted */
719 action->replacement_node_kept[i] = -1;
721 lc_list_for_each(pos1, & action->replacement->nodes) {
723 ext_grs_node_t *node = lc_list_entry(pos1, ext_grs_node_t, node_list);
725 if (action->replacement_nodes[node->aiid] == NULL) {
726 action->replacement_nodes[node->aiid] = node;
729 printf("module ext/grs: ERROR in function ext_grs_act_mature()\n");
730 printf(" Multiply assigned id of a replacement node encountered!\n\n");
734 action->n_replacement_nodes = action->replacement->n_nodes;
737 if (action->max_repl_edge_aiid >= 0) {
738 action->replacement_edges = obstack_alloc(&obst,
739 (action->max_repl_edge_aiid+1) * sizeof(*action->replacement_edges));
740 memset(action->replacement_edges, 0,
741 (action->max_repl_edge_aiid+1) * sizeof(*action->replacement_edges));
742 action->replacement_edge_kept = obstack_alloc(&obst,
743 (action->max_repl_edge_aiid+1) * sizeof(*action->replacement_edge_kept));
745 /* iterate over all replace edges */
746 for (i = 0; i <= action->max_repl_edge_aiid; i++)
747 /* by default ALL nodes are newly inserted */
748 action->replacement_edge_kept[i] = -1;
750 lc_list_for_each(pos, & action->replacement->edges) {
751 ext_grs_edge_t *edge = lc_list_entry(pos, ext_grs_edge_t, edge_list);
753 if (action->replacement_edges[edge->aiid] == NULL) {
754 action->replacement_edges[edge->aiid] = edge;
757 printf("module ext/grs: ERROR in function ext_grs_act_mature()\n");
758 printf(" Multiply assigned id of a replacement edge encountered!\n\n");
762 action->n_replacement_edges = action->replacement->n_edges;
768 /* setup information about the nodes and edges, which have to be kept by
769 * the rewriting step */
771 /* for this reason iterate over all pairs of nodes/edges stored in the ptr
772 * to ptr map representing the association of pattern ans replacement elements */
773 ext_grs_ptr_map_entry_t *entry = lc_pset_first(action->kept_elems);
774 for ( ; entry; entry = lc_pset_next(action->kept_elems) ) {
776 if (entry->kind == ext_grs_k_node) {
778 ext_grs_node_t *n1 = (ext_grs_node_t *) entry->pre;
779 ext_grs_node_t *n2 = (ext_grs_node_t *) entry->img;
781 assert(n1->kind == ext_grs_k_node && n2->kind == ext_grs_k_node);
782 action->pattern_node_kept[n1->aiid] = n2->aiid;
783 action->replacement_node_kept[n2->aiid] = n1->aiid;
786 else if (entry->kind == ext_grs_k_edge) {
788 ext_grs_edge_t *e1 = (ext_grs_edge_t *) entry->pre;
789 ext_grs_edge_t *e2 = (ext_grs_edge_t *) entry->img;
791 assert(e1->kind == ext_grs_k_edge && e2->kind == ext_grs_k_edge);
792 action->pattern_edge_kept[e1->aiid] = e2->aiid;
793 action->replacement_edge_kept[e2->aiid] = e1->aiid;
796 else assert(0 && "found an invalid entry in the ptr to ptr map");
800 /* for all replacement nodes count the number of incoming edges having
801 * no given position and not being associated with a pattern edge and
802 * having no position function. This
803 * number is stored in each replacement nodes and represents the number
804 * of edges to appended to the matched host nodes in array without a
807 for (i = 0; i <= action->max_repl_node_aiid; i++) {
808 ext_grs_node_t *node = action->replacement_nodes[i];
813 node->n_append_edges = 0;
814 lc_list_for_each (pos, & node->edges[ext_grs_in]) {
816 ext_grs_edge_t *in_edge = lc_list_entry(pos, ext_grs_edge_t, list[ext_grs_in]);
817 assert(in_edge->aiid >= 0 && "invalid aiid encountered");
819 if (in_edge->position_func) {
821 if (in_edge->pos != ext_grs_NO_EDGE_POS) {
822 assert(in_edge->pos >= 0 && "bad edge position");
823 printf("module ext/grs: ERROR in function ext_grs_act_mature()\n");
824 printf(" There is a position function associated with an edge,\n");
825 printf(" which has a given postion.\n\n");
828 if (action->replacement_node_kept[in_edge->aiid] >= 0) {
829 printf("module ext/grs: ERROR in function ext_grs_act_mature()\n");
830 printf(" There is a position function associated with an edge,\n");
831 printf(" which is not to be newly inserted but kept.\n\n");
840 in_edge->pos == ext_grs_NO_EDGE_POS &&
841 action->replacement_edge_kept[in_edge->aiid] == -1
844 node->n_append_edges++;
855 /* ensure that there is no edge, which has to be preserved while the rewriting
856 * and is incident to a pattern node, which has to be removed and, if not,
857 * ensure that associated edges are incident to associated nodes */
858 lc_list_for_each(pos, & action->pattern->edges) {
860 ext_grs_edge_t *edge = lc_list_entry(pos, ext_grs_edge_t, edge_list);
863 edge->kind == ext_grs_k_edge &&
864 action->pattern_edge_kept[edge->aiid] > -1
867 if (action->pattern_node_kept[edge->func->aiid] == -1 ||
868 action->pattern_node_kept[edge->arg->aiid] == -1)
870 printf("module ext/grs: ERROR in function ext_grs_act_mature()\n");
871 printf(" Action contains a pattern edge which is announced as to\n");
872 printf(" be kept in rewrite steps, but this edge is incident to\n");
873 printf(" a pattern node which must be deleted.\n\n");
878 ext_grs_edge_t *rpl_edge;
879 ext_grs_node_t *rpl_arg_node, *rpl_func_node;
882 action->pattern_node_kept[edge->func->aiid] > -1 &&
883 action->pattern_node_kept[edge->arg->aiid] > -1 &&
884 "there should be no entry less than -1");
886 rpl_edge = action->replacement_edges[action->pattern_edge_kept[edge->aiid]];
888 action->replacement_nodes[action->pattern_node_kept[edge->func->aiid]];
890 action->replacement_nodes[action->pattern_node_kept[edge->arg->aiid]];
892 if (rpl_edge->func != rpl_func_node || rpl_edge->arg != rpl_arg_node) {
893 printf("module ext/grs: ERROR in function ext_grs_act_mature()\n");
894 printf(" Action contains a pattern edge which is announced as to\n");
895 printf(" be kept in rewrite steps, but at least one of the replacement\n");
896 printf(" nodes incident to the associated replacement edge is not\n");
897 printf(" associated with the respective pattern nodes.\n\n");
908 /* prepare relation between pattern nodes and negative nodes by
909 * initializing with 0 which means that there is no relation yet */
910 action->neg_node_related = obstack_alloc(&obst,
911 (action->max_node_aiid+1) * sizeof(*action->neg_node_related));
912 memset(action->neg_node_related, 0,
913 (action->max_node_aiid+1) * sizeof(*action->neg_node_related));
915 action->neg_edge_related = obstack_alloc(&obst,
916 (action->max_edge_aiid+1) * sizeof(*action->neg_edge_related));
917 memset(action->neg_edge_related, 0,
918 (action->max_edge_aiid+1) * sizeof(*action->neg_edge_related));
922 /* set mature flag */
929 /** get a pattern node by its name */
930 ext_grs_node_t *ext_grs_act_get_node(ext_grs_action_t *action, char *name) {
932 ext_grs_node_t *node;
935 if (action->mature == 0) {
936 printf("module ext/grs: ERROR in function ext_grs_act_get_node()\n");
937 printf(" The given action is NOT mature!\n\n");
941 // Look for the name in the pattern node array
942 for(i = 0; i <= action->max_node_aiid; i++) {
943 node = action->nodes[i];
945 if ( strcmp(name, node->name) == 0 )
949 // Look for the name in the replace node array
950 for(i = 0; i <= action->max_repl_node_aiid; i++) {
951 node = action->replacement_nodes[i];
953 if (strcmp(name, node->name) == 0)
961 /** Same as ext_grs_act_get_node, but compares only the first n bytes of the node name */
962 ext_grs_node_t *ext_grs_act_get_node_n(ext_grs_action_t *action, char *name, int n) {
964 ext_grs_node_t *node;
967 if (action->mature == 0) {
968 printf("module ext/grs: ERROR in function ext_grs_act_get_node()\n");
969 printf(" The given action is NOT mature!\n\n");
973 // Look for the name in the pattern node array
974 for(i = 0; i <= action->max_node_aiid; i++) {
975 node = action->nodes[i];
977 if ( strncmp(name, node->name, n) == 0 )
981 // Look for the name in the replace node array
982 for(i = 0; i <= action->max_repl_node_aiid; i++) {
983 node = action->replacement_nodes[i];
985 if (strncmp(name, node->name, n) == 0)
993 /** Get a pattern node aiid by its name. */
994 int ext_grs_act_get_node_aiid(ext_grs_action_t *action, char *name)
996 ext_grs_node_t *node = ext_grs_act_get_node(action, name);
1003 /** Same as ext_grs_act_get_nodes_aiid, but compares only the first n bytes of the nodes name */
1004 int ext_grs_act_get_node_aiid_n(ext_grs_action_t *action, char *name, int n)
1006 ext_grs_node_t *node = ext_grs_act_get_node_n(action, name, n);
1015 /** get a pattern edge by its name */
1016 ext_grs_edge_t *ext_grs_act_get_edge(ext_grs_action_t *action, char *name) {
1018 ext_grs_edge_t *edge;
1021 if (action->mature == 0) {
1022 printf("module ext/grs: ERROR in function ext_grs_act_get_edge()\n");
1023 printf(" The given action is NOT mature\n\n");
1027 for(i = 0; i < action->n_edges; i++) {
1028 edge = action->edges[i];
1029 if ( strcmp(name, edge->name) == 0 )
1036 /** allows homomorphic matching of two pattern nodes,
1037 * note that these two nodes MUST have the same op and mode
1038 * (including mode ANY) and belong tp the same acion
1039 * @returns zero if fails and nonzero otherwise
1040 * @note the action the given nodes belong to has to be mature */
1041 int ext_grs_act_allow_nodes_hom(ext_grs_node_t *n1, ext_grs_node_t *n2)
1043 ext_grs_action_t *act;
1046 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_node()\n");
1047 printf(" NULL node(s) has/have been given.\n\n");
1051 assert(n1->graph && n2->graph && "every node should belong to a graph");
1052 assert(n1->graph->action && n2->graph->action &&
1053 "every graph should belong to an action");
1054 act = n1->graph->action;
1056 /* check wether the given nodes are not replacement nodes nodes */
1058 n1->graph->kind == ext_grs_k_replacement ||
1059 n2->graph->kind == ext_grs_k_replacement
1062 assert(n1->graph == act->replacement);
1063 assert(n2->graph == act->replacement);
1065 printf("module ext/grs: ERROR in function ext_grs_act_allow_nodes_hom()\n");
1066 printf(" At least one given node belongs to a replacement graph.\n\n");
1070 /* check wether the given nodes belong to the given action */
1071 if (n1->graph->action != n2->graph->action) {
1072 printf("module ext/grs: ERROR in function ext_grs_act_allow_nodes_hom()\n");
1073 printf(" Given nodes belong to different actions.\n\n");
1076 /* action has to be mature */
1077 if (! act->mature) {
1078 printf("module ext/grs: ERROR in function ext_grs_act_allow_nodes_hom()\n");
1079 printf(" Given action is not mature.\n\n");
1082 /* check wether the given nodes have the same firm op and firm mode */
1083 if (n1->op != n2->op || n1->mode != n2->mode) {
1084 printf("module ext/grs: ERROR in function ext_grs_act_allow_nodes_hom()\n");
1085 printf(" Given nodes have different Firm op and/or different Firm mode.\n\n");
1088 /* if the given pattern nodes are BOTH associated with replacement
1089 * nodes, check wether the ops and modes of the replacement nodes are equal */
1090 if (act->pattern_node_kept[n1->aiid] >= 0 && act->pattern_node_kept[n2->aiid] >= 0) {
1092 ext_grs_node_t *rpl_n1, *rpl_n2;
1094 assert(n1->graph->kind != ext_grs_k_negative &&
1095 "a negative node should not be marked as kept");
1096 assert(n2->graph->kind != ext_grs_k_negative &&
1097 "a negative node should not be marked as kept");
1099 rpl_n1 = act->replacement_nodes[act->pattern_node_kept[n1->aiid]];
1100 rpl_n2 = act->replacement_nodes[act->pattern_node_kept[n2->aiid]];
1101 if (rpl_n1->op != rpl_n2->op || rpl_n1->mode != rpl_n2->mode)
1103 printf("module ext/grs: ERROR in function ext_grs_act_allow_nodes_hom()\n");
1104 printf(" Given pattern nodes are assiciated with replacement nodes of\n");
1105 printf(" different op or mode, this may cause undefined behaviour of\n");
1106 printf(" the replacement when the nodes are matched homomorphic.\n\n");
1112 /* allow homomorphic matching of the given node */
1113 act->hom[n1->aiid][n2->aiid] = 1;
1119 int ext_grs_act_announce_kept_node(ext_grs_node_t *n1, ext_grs_node_t *n2)
1121 ext_grs_action_t *act;
1122 ext_grs_ptr_map_entry_t *new_entry = obstack_alloc(&obst, sizeof(*new_entry));
1125 printf("module ext/grs: Internal ERROR in function ext_grs_act_announce_kept_node()\n");
1126 printf(" Failed to allocate a new node pair representative.\n\n");
1131 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_node()\n");
1132 printf(" NULL node(s) has/have been given.\n\n");
1133 obstack_free(&obst, new_entry);
1138 assert(n1->graph->action && n2->graph->action &&
1139 "every graph should belong to an action");
1140 act = n1->graph->action;
1142 /* check wether the given nodes belong to the given action */
1143 if (n1->graph->action != n2->graph->action) {
1144 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_node()\n");
1145 printf(" Given nodes belong to different actions.\n\n");
1146 obstack_free(&obst, new_entry);
1149 /* action must not be mature */
1151 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_node()\n");
1152 printf(" Given action must not be mature.\n\n");
1153 obstack_free(&obst, new_entry);
1156 /* check wether n1 belongs to pattern and n2 to the replacement graph */
1157 if (n1->graph != act->pattern || n2->graph != act->replacement) {
1158 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_node()\n");
1159 printf(" A pattern node and a replacement node must be given.\n\n");
1160 obstack_free(&obst, new_entry);
1164 new_entry->kind = ext_grs_k_node;
1165 new_entry->pre = n1;
1166 new_entry->img = n2;
1171 lc_pset_insert(act->kept_elems, new_entry, LC_HASH_PTR(new_entry));
1173 if (not_injective) {
1174 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_node()\n");
1175 printf(" The given replacement node has already been\n");
1176 printf(" associated with another pattern node.\n\n");
1177 obstack_free(&obst, new_entry);
1181 if (multiple_entry) {
1182 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_node()\n");
1183 printf(" The given pattern node has already been\n");
1184 printf(" associated with another replacement node.\n\n");
1185 obstack_free(&obst, new_entry);
1189 if (already_exists) {
1190 printf("module ext/grs: WARNING in function ext_grs_act_announce_kept_node()\n");
1191 printf(" The given association has already been announced.\n\n");
1192 obstack_free(&obst, new_entry);
1199 int ext_grs_act_announce_kept_edge(ext_grs_edge_t *e1, ext_grs_edge_t *e2)
1201 ext_grs_action_t *act;
1202 ext_grs_ptr_map_entry_t *new_entry = obstack_alloc(&obst, sizeof(*new_entry));
1205 printf("module ext/grs: Internal ERROR in function ext_grs_act_announce_kept_node()\n");
1206 printf(" Failed to allocate a new edge pair representative.\n\n");
1211 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_edge()\n");
1212 printf(" NULL edge(s) has/have been given.\n\n");
1213 obstack_free(&obst, new_entry);
1217 if (!e1->graph || !e2->graph || !e1->graph->action || !e2->graph->action) {
1218 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_edge()\n");
1219 printf(" At least one of the given edges is corrupted.\n\n");
1220 obstack_free(&obst, new_entry);
1224 act = e1->graph->action;
1226 /* check wether the given nodes belong to the given action */
1227 if (e1->graph->action != e2->graph->action) {
1228 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_edge()\n");
1229 printf(" Given edges belong to different actions.\n\n");
1230 obstack_free(&obst, new_entry);
1233 /* action has to be mature */
1235 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_edge()\n");
1236 printf(" Given action must not be mature.\n\n");
1237 obstack_free(&obst, new_entry);
1240 /* check wether n1 belongs to pattern and n2 to the replacement graph */
1241 if (e1->graph != act->pattern || e2->graph != act->replacement) {
1242 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_edge()\n");
1243 printf(" A pattern edge and a replacement edge must be given.\n\n");
1244 obstack_free(&obst, new_entry);
1248 if (e1->pos != e2->pos) {
1249 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_edge()\n");
1250 printf(" The pattern and the replacemnt edge must have the same position OR\n");
1251 printf(" both no position at all.\n\n");
1252 obstack_free(&obst, new_entry);
1256 new_entry->kind = ext_grs_k_edge;
1257 new_entry->pre = e1;
1258 new_entry->img = e2;
1263 lc_pset_insert(act->kept_elems, new_entry, LC_HASH_PTR(new_entry));
1265 if (not_injective) {
1266 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_node()\n");
1267 printf(" The given replacement node has already been\n");
1268 printf(" associated with another pattern node.\n\n");
1269 obstack_free(&obst, new_entry);
1273 if (multiple_entry) {
1274 printf("module ext/grs: ERROR in function ext_grs_act_announce_kept_node()\n");
1275 printf(" The given pattern node has already been\n");
1276 printf(" associated with another replacement node.\n\n");
1277 obstack_free(&obst, new_entry);
1281 if (already_exists) {
1282 printf("module ext/grs: WARNING in function ext_grs_act_announce_kept_node()\n");
1283 printf(" The given association has already been announced.\n\n");
1284 obstack_free(&obst, new_entry);
1291 int ext_grs_act_relate_neg_node(ext_grs_node_t *pat_node, ext_grs_node_t *neg_node) {
1293 if (pat_node->graph->action != neg_node->graph->action) {
1294 printf("module ext/grs: ERROR in function ext_grs_act_relate_neg_node()\n");
1295 printf(" The given nodes do not belong to the same action.\n\n");
1299 if (pat_node->graph->kind != ext_grs_k_pattern) {
1300 printf("module ext/grs: ERROR in function ext_grs_act_relate_neg_node()\n");
1301 printf(" The given pattern node does not belong to a pattern graph.\n\n");
1305 if (neg_node->graph->kind != ext_grs_k_negative) {
1306 printf("module ext/grs: ERROR in function ext_grs_act_relate_neg_node()\n");
1307 printf(" The given negative node does not belong to a negative pattern graph.\n\n");
1311 neg_node->related_node = pat_node;
1315 int ext_grs_act_relate_neg_edge(ext_grs_edge_t *pat_edge, ext_grs_edge_t *neg_edge) {
1317 if (pat_edge->graph->action != neg_edge->graph->action) {
1318 printf("module ext/grs: ERROR in function ext_grs_act_relate_neg_edge()\n");
1319 printf(" The given edges do not belong to the same action.\n\n");
1323 if (pat_edge->graph->kind != ext_grs_k_pattern) {
1324 printf("module ext/grs: ERROR in function ext_grs_act_relate_neg_edge()\n");
1325 printf(" The given pattern edge does not belong to a pattern graph.\n\n");
1329 if (neg_edge->graph->kind != ext_grs_k_negative) {
1330 printf("module ext/grs: ERROR in function ext_grs_act_relate_neg_edge()\n");
1331 printf(" The given negative edge does not belong to a negative pattern graph.\n\n");
1335 neg_edge->related_edge = pat_edge;
1341 int ext_grs_act_register_condition(
1342 ext_grs_condition_func_t func,
1343 ext_grs_graph_t *graph,
1344 int n_nodes, ext_grs_node_t **nodes,
1345 int n_edges, ext_grs_edge_t **edges)
1348 ext_grs_cond_descr_t *cond_descr;
1349 ext_grs_node_t **nodes_copied = obstack_alloc(&obst, n_nodes * sizeof(*nodes_copied));
1350 ext_grs_edge_t **edges_copied = obstack_alloc(&obst, n_edges * sizeof(*edges_copied));
1353 printf("module ext/grs: ERROR in function ext_grs_act_register_condition()\n");
1354 printf(" The given condition function was NULL.\n\n");
1359 printf("module ext/grs: ERROR in function ext_grs_act_register_condition()\n");
1360 printf(" The given (pattern or negative graph) was NULL.\n\n");
1364 if (graph->action->mature) {
1365 printf("module ext/grs: ERROR in function ext_grs_act_register_condition()\n");
1366 printf(" The given action is already mature, no condition registered.\n\n");
1370 /* check whether the given nodes and edges are really nodes and edges, AND check
1371 * whether these nodes and edges all belong to the given action */
1372 for (i = 0; i < n_nodes; i++) {
1375 printf("module ext/grs: ERROR in function ext_grs_act_register_condition()\n");
1376 printf(" A given node was NULL.\n\n");
1379 if (nodes[i]->kind != ext_grs_k_node) {
1380 printf("module ext/grs: ERROR in function ext_grs_act_register_condition()\n");
1381 printf(" A given node was not a valid node.\n\n");
1384 if (nodes[i]->graph->action != graph->action) {
1385 printf("module ext/grs: ERROR in function ext_grs_act_register_condition()\n");
1386 printf(" A given node belongs to an action different from the one of the given\n");
1387 printf(" (pattern or negative) graph.\n\n");
1391 nodes_copied[i] = nodes[i];
1393 for (i = 0; i < n_edges; i++) {
1396 printf("module ext/grs: ERROR in function ext_grs_act_register_condition()\n");
1397 printf(" A given edge was NULL.\n\n");
1400 if (edges[i]->kind != ext_grs_k_edge) {
1401 printf("module ext/grs: ERROR in function ext_grs_act_register_condition()\n");
1402 printf(" A given edge was not a valid edge.\n\n");
1405 if (edges[i]->graph->action != graph->action) {
1406 printf("module ext/grs: ERROR in function ext_grs_act_register_condition()\n");
1407 printf(" A given edge belongs to an action different from one of the given\n");
1408 printf(" (pattern or negative) graph.\n\n");
1412 edges_copied[i] = edges[i];
1415 /* allocate space for a condition descriptor */
1416 cond_descr = obstack_alloc(&obst, sizeof(*cond_descr));
1417 memset(cond_descr, 0, sizeof(cond_descr));
1419 /* init the condition descriptor */
1420 cond_descr->graph = graph;
1421 cond_descr->condition = func;
1423 cond_descr->n_nodes = n_nodes;
1424 cond_descr->nodes = nodes_copied;
1425 cond_descr->n_edges = n_edges;
1426 cond_descr->edges = edges_copied;
1428 /* add the condition descriptor to the list */
1429 lc_list_add(&cond_descr->condition_list, & graph->action->listed_conditions);
1430 /* increment the number of conditions */
1431 graph->n_conditions++;
1432 graph->action->n_conditions++; // AS
1437 int ext_grs_act_register_eval(ext_grs_action_t *action,
1438 ext_grs_eval_in_func_t in_func, ext_grs_eval_out_func_t out_func)
1440 ext_grs_eval_descr_t *eval_descr;
1443 printf("module ext/grs: ERROR in function ext_grs_act_register_eval()\n");
1444 printf(" The given eval-in function function was NULL.\n\n");
1448 printf("module ext/grs: ERROR in function ext_grs_act_register_eval()\n");
1449 printf(" The given eval-out function function was NULL.\n\n");
1452 if (action->mature) {
1453 printf("module ext/grs: ERROR in function ext_grs_act_register_eval_out_func()\n");
1454 printf(" The given action is already mature, no eval function registered.\n\n");
1458 eval_descr = obstack_alloc(&obst, sizeof(*eval_descr));
1459 memset(eval_descr, 0, sizeof(*eval_descr));
1460 eval_descr->eval_in = in_func;
1461 eval_descr->eval_out = out_func;
1462 eval_descr->data = NULL;
1463 lc_list_add_tail(& eval_descr->eval_list, & action->listed_evals);
1469 int ext_grs_act_set_op_condition(
1470 ext_grs_node_t *node, ext_grs_op_condition_func_t func)
1473 printf("module ext/grs: ERROR in function ext_grs_act_set_op_condition()\n");
1474 printf(" The given node was NULL.\n\n");
1478 printf("module ext/grs: ERROR in function ext_grs_act_set_op_condition()\n");
1479 printf(" The given op condition function was NULL.\n\n");
1483 node->op_condition = func;
1487 int ext_grs_act_set_mode_condition(
1488 ext_grs_node_t *node, ext_grs_mode_condition_func_t func)
1491 printf("module ext/grs: ERROR in function ext_grs_act_set_mode_condition()\n");
1492 printf(" The given node was NULL.\n\n");
1496 printf("module ext/grs: ERROR in function ext_grs_act_set_mode_condition()\n");
1497 printf(" The given mode condition function was NULL.\n\n");
1501 node->mode_condition = func;
1505 int ext_grs_act_set_pos_func(ext_grs_edge_t *edge, ext_grs_edge_pos_func_t func)
1508 printf("module ext/grs: ERROR in function ext_grs_act_set_pos_func()\n");
1509 printf(" The given edge was NULL.\n\n");
1513 printf("module ext/grs: ERROR in function ext_grs_act_set_pos_func()\n");
1514 printf(" The given position function was NULL.\n\n");
1517 assert(edge->graph && "every edge should have a graph");
1518 if (edge->graph->kind != ext_grs_k_replacement) {
1519 printf("module ext/grs: ERROR in function ext_grs_act_set_pos_func()\n");
1520 printf(" The given edge belongs to a graph, which is not a replacement graph.\n\n");
1523 assert(edge->graph->action && "every graph should have an action");
1524 if (edge->graph->action->mature) {
1525 printf("module ext/grs: ERROR in function ext_grs_act_set_pos_func()\n");
1526 printf(" The given edge belongs to an action, which is already mature.\n\n");
1530 edge->position_func = func;
1535 /* Initilize the action part of the exr/grs module of the libfirm.
1536 * This is an internal function. */
1537 void _ext_grs_act_init() {
1538 /* init obstack if necesarry */
1539 if (obst_init == 0) {
1540 obstack_init(&obst);
1545 /* Finalize the action part of the exr/grs module of the libfirm.
1546 * This is an internal function */
1547 void _ext_grs_act_finalize() {
1549 /* finalize the action obstack */
1550 obstack_free(&obst, NULL);
1551 obstack_finish(&obst);