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 Change the calling conventions of "local" methods
23 * @author Michael Beck
30 #include "iroptimize.h"
36 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
39 * Copy the calling conventions from the entities to the call type.
41 static void update_calls(ir_node *call, void *env) {
44 ir_node *ptr = get_Call_ptr(call);
46 if (is_SymConst(ptr)) {
47 ir_entity *ent = get_SymConst_entity(ptr);
48 ir_type *mtp = get_entity_type(ent);
49 ir_type *ctp = get_Call_type(call);
50 unsigned cc = get_method_calling_convention(mtp);
52 if (cc != get_method_calling_convention(ctp)) {
53 set_method_calling_convention(ctp, cc);
54 DB((dbg, LEVEL_1, "changed calling convention of calll to %+F\n", ent));
61 * Change the calling conventions for all local methods.
63 * @param cc new calling convention
65 void opt_change_calling_conventions(unsigned cc) {
69 FIRM_DBG_REGISTER(dbg, "firm.opt.cc");
71 assure_irp_globals_address_taken_computed();
73 /* first step: change the calling conventions of the local non-escaped entities */
74 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
75 ir_graph *irg = get_irp_irg(i);
76 ir_entity *ent = get_irg_entity(irg);
77 ir_address_taken_state state = get_entity_address_taken(ent);
79 if (get_entity_visibility(ent) == visibility_local &&
80 state == ir_address_not_taken) {
81 ir_type *mtp = get_entity_type(ent);
83 unsigned new_cc, old_cc = get_method_calling_convention(mtp) & ~cc_bits;
85 new_cc = old_cc | (cc & cc_bits);
87 if (new_cc != old_cc) {
88 set_method_calling_convention(mtp, new_cc);
90 DB((dbg, LEVEL_1, "changed calling convention of %+F\n", ent));
96 all_irg_walk(NULL, update_calls, NULL);