forgot 2 files
[libfirm] / ir / be / beinfo.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @author      Matthias Braun
23  * @version     $Id$
24  */
25 #include "config.h"
26
27 #include "beinfo.h"
28 #include "bearch_t.h"
29 #include "irgwalk.h"
30 #include "irnode_t.h"
31 #include "error.h"
32
33 static copy_attr_func  old_phi_copy_attr;
34
35 void be_info_new_node(ir_node *node)
36 {
37         if (is_Anchor(node))
38                 return;
39
40         struct obstack *obst  = get_irg_obstack(current_ir_graph);
41         backend_info_t *info  = obstack_alloc(obst, sizeof(*info));
42         sched_info_t   *sinfo = &info->sched_info;
43
44         memset(info, 0, sizeof(*info));
45
46         sinfo->idx  = get_irn_idx(node);
47         INIT_LIST_HEAD(&sinfo->list);
48
49         if (is_Phi(node)) {
50                 info->out_infos = NEW_ARR_D(reg_out_info_t, obst, 1);
51                 memset(info->out_infos, 0, 1 * sizeof(info->out_infos[0]));
52         }
53         assert(node->backend_info == NULL);
54         node->backend_info = info;
55 }
56
57 static void new_Phi_copy_attr(const ir_node *old_node, ir_node *new_node)
58 {
59         struct obstack *obst  = get_irg_obstack(get_irn_irg(new_node));
60         backend_info_t *old_info = be_get_info(old_node);
61         backend_info_t *new_info = be_get_info(new_node);
62
63         old_phi_copy_attr(old_node, new_node);
64         new_info->out_infos = DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
65 }
66
67 int be_info_equal(const ir_node *node1, const ir_node *node2)
68 {
69         backend_info_t *info1 = be_get_info(node1);
70         backend_info_t *info2 = be_get_info(node2);
71         int             len   = ARR_LEN(info1->out_infos);
72         int             i;
73
74         if (ARR_LEN(info2->out_infos) != len)
75                 return 0;
76
77         for (i = 0; i < len; ++i) {
78                 const reg_out_info_t *out1 = &info1->out_infos[i];
79                 const reg_out_info_t *out2 = &info2->out_infos[i];
80                 if (out1->reg != out2->reg)
81                         return 0;
82                 if (!reg_reqs_equal(out1->req, out2->req))
83                         return 0;
84         }
85
86         /* TODO: in reqs */
87
88         return 1;
89 }
90
91 static void init_walker(ir_node *node, void *data)
92 {
93         (void) data;
94         be_info_new_node(node);
95 }
96
97 static int initialized = 0;
98
99 void be_info_init(void)
100 {
101         if (initialized == 1)
102                 panic("double initialization of be_info");
103
104         old_phi_copy_attr = op_Phi->ops.copy_attr;
105         op_Phi->ops.copy_attr = new_Phi_copy_attr;
106         initialized = 1;
107 }
108
109 void be_info_init_irg(ir_graph *irg)
110 {
111         irg_walk_anchors(irg, init_walker, NULL, NULL);
112 }
113
114 void be_info_free(void)
115 {
116         if (!initialized)
117                 panic("be_info_free called without prior init");
118
119         assert(op_Phi->ops.copy_attr == new_Phi_copy_attr);
120         op_Phi->ops.copy_attr = old_phi_copy_attr;
121         initialized = 0;
122 }
123
124 int be_info_initialized(const ir_graph *irg)
125 {
126         (void) irg;
127         return initialized;
128 }