X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbearch.c;h=0989ab8f2c48ee019174d94f980e92ab61902b47;hb=8c2710b8f28f31447e12055651725a7cf53714bc;hp=7082648ab86ce8b4154dd1ca8047832266605bb2;hpb=5530877cfe293d952cef32d005c457409f2a2150;p=libfirm diff --git a/ir/be/bearch.c b/ir/be/bearch.c index 7082648ab..0989ab8f2 100644 --- a/ir/be/bearch.c +++ b/ir/be/bearch.c @@ -1,20 +1,6 @@ /* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. - * * This file is part of libFirm. - * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file LICENSE.GPL included in the - * packaging of this file. - * - * Licensees holding valid libFirm Professional Edition licenses may use - * this file in accordance with the libFirm Commercial License. - * Agreement provided with the Software. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. + * Copyright (C) 2012 University of Karlsruhe. */ /** @@ -39,7 +25,7 @@ #include "irprintf.h" -static const arch_register_req_t no_requirement = { +arch_register_req_t const arch_no_requirement = { arch_register_req_type_none, NULL, NULL, @@ -47,20 +33,6 @@ static const arch_register_req_t no_requirement = { 0, 0 }; -const arch_register_req_t *arch_no_register_req = &no_requirement; - -static reg_out_info_t dummy_info = { - NULL, - &no_requirement -}; - -/* Initialize the architecture environment struct. */ -arch_env_t *arch_env_init(const arch_isa_if_t *isa_if, be_main_env_t *main_env) -{ - arch_env_t *arch_env = isa_if->init(main_env); - arch_env->main_env = main_env; - return arch_env; -} /** * Get the isa responsible for a node. @@ -69,16 +41,13 @@ arch_env_t *arch_env_init(const arch_isa_if_t *isa_if, be_main_env_t *main_env) */ static const arch_irn_ops_t *get_irn_ops(const ir_node *irn) { - const ir_op *ops; - const arch_irn_ops_t *be_ops; - if (is_Proj(irn)) { irn = get_Proj_pred(irn); assert(!is_Proj(irn)); } - ops = get_irn_op(irn); - be_ops = get_op_ops(ops)->be_ops; + ir_op *ops = get_irn_op(irn); + const arch_irn_ops_t *be_ops = get_op_ops(ops)->be_ops; return be_ops; } @@ -101,17 +70,6 @@ int arch_get_sp_bias(ir_node *irn) return ops->get_sp_bias(irn); } -arch_inverse_t *arch_get_inverse(const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obstack) -{ - const arch_irn_ops_t *ops = get_irn_ops(irn); - - if (ops->get_inverse) { - return ops->get_inverse(irn, i, inverse, obstack); - } else { - return NULL; - } -} - int arch_possible_memory_operand(const ir_node *irn, unsigned int i) { const arch_irn_ops_t *ops = get_irn_ops(irn); @@ -145,32 +103,10 @@ int arch_get_op_estimated_cost(const ir_node *irn) } } -static reg_out_info_t *get_out_info(const ir_node *node) -{ - size_t pos = 0; - const backend_info_t *info; - assert(get_irn_mode(node) != mode_T); - if (is_Proj(node)) { - pos = get_Proj_proj(node); - node = get_Proj_pred(node); - } - - info = be_get_info(node); - /* We have a problem with the switch-node where there can be arbitrary - * Proj-numbers, so we can't easily allocate an array big-enough to hold - * all of them. So until we rewrite Switch-nodes we need this special case - */ - if (info->out_infos == NULL) - return &dummy_info; - assert(pos < ARR_LEN(info->out_infos)); - return &info->out_infos[pos]; -} - -static reg_out_info_t *get_out_info_n(const ir_node *node, int pos) +static reg_out_info_t *get_out_info_n(const ir_node *node, unsigned pos) { const backend_info_t *info = be_get_info(node); - assert(!is_Proj(node)); - assert(pos >= 0 && pos < (int)ARR_LEN(info->out_infos)); + assert(pos < (unsigned)ARR_LEN(info->out_infos)); return &info->out_infos[pos]; } @@ -181,7 +117,8 @@ const arch_register_t *arch_get_irn_register(const ir_node *node) return out->reg; } -const arch_register_t *arch_get_irn_register_out(const ir_node *node, int pos) +const arch_register_t *arch_get_irn_register_out(const ir_node *node, + unsigned pos) { const reg_out_info_t *out = get_out_info_n(node, pos); return out->reg; @@ -193,7 +130,7 @@ const arch_register_t *arch_get_irn_register_in(const ir_node *node, int pos) return arch_get_irn_register(op); } -void arch_set_irn_register_out(ir_node *node, int pos, +void arch_set_irn_register_out(ir_node *node, unsigned pos, const arch_register_t *reg) { reg_out_info_t *out = get_out_info_n(node, pos); @@ -206,58 +143,37 @@ void arch_set_irn_register(ir_node *node, const arch_register_t *reg) out->reg = reg; } -const arch_register_req_t *arch_get_irn_register_req(const ir_node *node) -{ - reg_out_info_t *out = get_out_info(node); - return out->req; -} - -arch_irn_flags_t arch_get_irn_flags(const ir_node *node) -{ - backend_info_t *info; - if (is_Proj(node)) - return arch_irn_flags_not_scheduled; - - info = be_get_info(node); - return info->flags; -} - void arch_set_irn_flags(ir_node *node, arch_irn_flags_t flags) { - backend_info_t *info; - - /* setting flags is only supported for instructions currently. - * (mainly because we found no use for it yet and saved the space for - * be_infos for them */ - assert(!is_Proj(node)); - info = be_get_info(node); + backend_info_t *const info = be_get_info(node); info->flags = flags; } void arch_add_irn_flags(ir_node *node, arch_irn_flags_t flags) { - backend_info_t *info; - assert(!is_Proj(node)); - info = be_get_info(node); + backend_info_t *const info = be_get_info(node); info->flags |= flags; } bool arch_reg_is_allocatable(const arch_register_req_t *req, const arch_register_t *reg) { - if (reg->type & arch_register_type_joker) - return true; - if (req->type == arch_register_req_type_none) + assert(req->type != arch_register_req_type_none); + if (req->cls != reg->reg_class) return false; - if (req->type & arch_register_req_type_limited) { - if (arch_register_get_class(reg) != req->cls) - return false; - return rbitset_is_set(req->limited, arch_register_get_index(reg)); - } - return req->cls == arch_register_get_class(reg); + if (reg->type & arch_register_type_virtual) + return true; + if (arch_register_req_is(req, limited)) + return rbitset_is_set(req->limited, reg->index); + return true; } -void arch_dump_register_req(FILE *F, const arch_register_req_t *req, +/** + * Print information about a register requirement in human readable form + * @param F output stream/file + * @param req The requirements structure to format. + */ +static void arch_dump_register_req(FILE *F, const arch_register_req_t *req, const ir_node *node) { if (req == NULL || req->type == arch_register_req_type_none) { @@ -287,7 +203,7 @@ void arch_dump_register_req(FILE *F, const arch_register_req_t *req, fprintf(F, " same as"); for (i = 0; 1U << i <= other; ++i) { if (other & (1U << i)) { - ir_fprintf(F, " %+F", get_irn_n(skip_Proj_const(node), i)); + ir_fprintf(F, " #%d (%+F)", i, get_irn_n(skip_Proj_const(node), i)); } } } @@ -299,7 +215,7 @@ void arch_dump_register_req(FILE *F, const arch_register_req_t *req, fprintf(F, " different from"); for (i = 0; 1U << i <= other; ++i) { if (other & (1U << i)) { - ir_fprintf(F, " %+F", get_irn_n(skip_Proj_const(node), i)); + ir_fprintf(F, " #%d (%+F)", i, get_irn_n(skip_Proj_const(node), i)); } } } @@ -320,32 +236,30 @@ void arch_dump_register_req(FILE *F, const arch_register_req_t *req, void arch_dump_reqs_and_registers(FILE *F, const ir_node *node) { - int n_ins = get_irn_arity(node); - int n_outs = arch_get_irn_n_outs(node); - arch_irn_flags_t flags = arch_get_irn_flags(node); - int i; + backend_info_t *const info = be_get_info(node); + int const n_ins = get_irn_arity(node); + /* don't fail on invalid graphs */ + if (!info || (!info->in_reqs && n_ins != 0) || !info->out_infos) { + fprintf(F, "invalid register requirements!!!\n"); + return; + } - for (i = 0; i < n_ins; ++i) { + for (int i = 0; i < n_ins; ++i) { const arch_register_req_t *req = arch_get_irn_register_req_in(node, i); fprintf(F, "inreq #%d = ", i); arch_dump_register_req(F, req, node); fputs("\n", F); } - for (i = 0; i < n_outs; ++i) { - const arch_register_req_t *req = arch_get_irn_register_req_out(node, i); - fprintf(F, "outreq #%d = ", i); + be_foreach_out(node, o) { + const arch_register_req_t *req = arch_get_irn_register_req_out(node, o); + fprintf(F, "outreq #%u = ", o); arch_dump_register_req(F, req, node); - fputs("\n", F); - } - for (i = 0; i < n_outs; ++i) { - const arch_register_t *reg = arch_get_irn_register_out(node, i); - const arch_register_req_t *req = arch_get_irn_register_req_out(node, i); - if (req->cls == NULL) - continue; - fprintf(F, "reg #%d = %s\n", i, reg != NULL ? reg->name : "n/a"); + const arch_register_t *reg = arch_get_irn_register_out(node, o); + fprintf(F, " [%s]\n", reg != NULL ? reg->name : "n/a"); } fprintf(F, "flags ="); + arch_irn_flags_t flags = arch_get_irn_flags(node); if (flags == arch_irn_flags_none) { fprintf(F, " none"); } else { @@ -365,5 +279,5 @@ void arch_dump_reqs_and_registers(FILE *F, const ir_node *node) fprintf(F, " not_scheduled"); } } - fprintf(F, " (%d)\n", (int)flags); + fprintf(F, " (0x%x)\n", (unsigned)flags); }