2 * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief Lower small CopyB nodes into a series of Load/store
23 * @author Michael Beck
37 typedef struct copyb_env {
38 ir_node *next; /**< link to the next one */
42 typedef struct walker_env {
43 struct obstack obst; /**< temporary space */
45 ir_node *list; /**< list of CopyB nodes. */
49 * Build a graph that copies an entity of type tp from src to tgt
51 static ir_node *build_copy_graph(dbg_info *dbg, ir_node *blk, ir_node *mem, ir_node *src, ir_node *tgt, ir_type *tp) {
54 if (is_Array_type(tp)) {
57 for (i = 0, n = get_compound_n_members(tp); i < n; ++i) {
58 ir_entity *ent = get_compound_member(tp, i);
59 ir_node *s = new_d_simpleSel(dbg, mem, src, ent);
60 ir_node *d = new_d_simpleSel(dbg, mem, tgt, ent);
61 ir_type *ent_tp = get_entity_type(ent);
63 if (is_atomic_type(ent_tp)) {
64 ir_mode *mode = get_type_mode(ent_tp);
65 ir_node *irn = new_rd_Load(dbg, current_ir_graph, blk, mem, s, mode);
66 ir_node *res = new_r_Proj(current_ir_graph, blk, irn, mode, pn_Load_res);
68 mem = new_r_Proj(current_ir_graph, blk, irn, mode_M, pn_Load_M);
69 irn = new_rd_Store(dbg, current_ir_graph, blk, mem, d, res);
70 mem = new_r_Proj(current_ir_graph, blk, irn, mode_M, pn_Store_M);
72 mem = build_copy_graph(dbg, blk, mem, s, d, ent_tp);
80 * Walker: lower small CopyB nodes.
82 static void lower_copyb_nodes(ir_node *irn, void *ctx) {
85 walker_env *env = ctx;
90 tp = get_CopyB_type(irn);
91 if (get_type_state(tp) != layout_fixed)
94 size = get_type_size_bytes(tp);
95 if (size > env->max_size)
98 /* for now, we can only handle Struct's */
99 if (is_Struct_type(tp)) {
100 irn = build_copy_graph(get_irn_dbg_info(irn), get_nodes_block(irn), get_CopyB_mem(irn), get_CopyB_src(irn), get_CopyB_dst(irn), tp);
105 * Lower CopyB nodes of size smaller that max_size into Loads/Stores
107 void lower_CopyB(int max_size) {
111 obstack_init(&env.obst);
112 env.max_size = max_size;
114 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
115 irg_walk_graph(get_irp_irg(i), firm_clear_link, lower_copyb_nodes, NULL);