libfirminclude_HEADERS = \
absgraph.h \
analyze_irg_args.h \
- archop.h \
be.h \
callgraph.h \
cdep.h \
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * @file
- * @brief Architecture depended IR operations
- * @version $Id$
- */
-#ifndef FIRM_ARCH_ARCHOP_H
-#define FIRM_ARCH_ARCHOP_H
-
-#include "firm_types.h"
-
-/**
- * Mask defining which architecture depend
- * operations are supported.
- */
-typedef enum _arch_ops_mask {
- ARCH_OPS_NONE = 0, /**< no additional Operations */
- ARCH_OPS_MINMAX = 1 /**< use the Min/Max Operation */
-} arch_ops_mask;
-
-typedef struct _arch_ops_info {
- arch_ops_mask enabled_ops; /**< a mask of enabled IR-opcodes */
- unsigned minmax_handle_NaN:1; /**< if set, Min(a,a) == a, else unknown */
-} arch_ops_info;
-
-extern ir_op *op_Min, *op_Max;
-
-ir_op *get_op_Min(void);
-ir_op *get_op_Max(void);
-
-/** construct a Min: Min(a,b) = a < b ? a : b */
-ir_node *
-new_rd_Min(dbg_info *db, ir_graph *irg, ir_node *block,
- ir_node *op1, ir_node *op2, ir_mode *mode);
-
-/** construct a Max: Max(a,b) = a > b ? a : b */
-ir_node *
-new_rd_Max(dbg_info *db, ir_graph *irg, ir_node *block,
- ir_node *op1, ir_node *op2, ir_mode *mode);
-
-ir_node *
-new_r_Min(ir_graph *irg, ir_node *block,
- ir_node *op1, ir_node *op2, ir_mode *mode);
-
-ir_node *
-new_r_Max(ir_graph *irg, ir_node *block,
- ir_node *op1, ir_node *op2, ir_mode *mode);
-
-ir_node *
-new_Min(ir_node *op1, ir_node *op2, ir_mode *mode);
-
-ir_node *
-new_Max(ir_node *op1, ir_node *op2, ir_mode *mode);
-
-/**
- * Create Min and Mux from Mux nodes
- */
-ir_node *arch_transform_node_Mux(ir_node *mux);
-
-/**
- * initialize the ops.
- */
-void firm_archops_init(const arch_ops_info *info);
-
-#endif
#include <stdio.h>
#include "irarch.h"
-#include "archop.h"
#include "lowering.h"
typedef enum {
/** If set, the target architecture use an immediate floating point mode. */
unsigned has_imm_fp_mode:1;
- /** Additional opcodes settings. */
- const arch_ops_info *arch_op_settings;
-
/** Settings for architecture dependent optimizations. */
const ir_settings_arch_dep_t *dep_param;
#include "irgwalk.h" /* Support to walk ir */
#include "irarch.h" /* architecture dependent optimizations */
-#include "archop.h" /* architecture dependent opcodes */
#include "firmstat.h" /* statistics */
*/
ident_if_t *id_if;
- /**
- * The architecture dependent opcode settings.
- * If not set, no architecture dependent operations will be used.
- */
- const arch_ops_info *arch_op_settings;
-
/**
* The default calling convention.
*/
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * @file
- * @brief architecture dependent IR operations
- * @version $Id$
- */
-#include "config.h"
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "irprog_t.h"
-#include "irgraph_t.h"
-#include "irnode_t.h"
-#include "irmode_t.h"
-#include "ircons_t.h"
-#include "iropt_t.h"
-#include "firm_common_t.h"
-#include "irvrfy_t.h"
-#include "iropt_dbg.h"
-#include "archop.h"
-#include "irop.h"
-#include "error.h"
-
-/* when we need verifying */
-#ifdef NDEBUG
-# define IRN_VRFY_IRG(res, irg)
-#else
-# define IRN_VRFY_IRG(res, irg) irn_vrfy_irg(res, irg)
-#endif
-
-/** current settings */
-static arch_ops_info settings;
-
-/** default settings */
-static const arch_ops_info default_settings = {
- ARCH_OPS_NONE,
- 0
-};
-
-/*
- * construct a Min: Min(a,b) = a < b ? a : b
- */
-ir_node *
-new_rd_Min(dbg_info *db, ir_graph *irg, ir_node *block,
- ir_node *op1, ir_node *op2, ir_mode *mode)
-{
- ir_node *in[2];
- ir_node *res;
-
- if (! op_Min) {
- panic("cannot create Min node, not allowed");
- }
-
- in[0] = op1;
- in[1] = op2;
- res = new_ir_node(db, irg, block, op_Min, mode, 2, in);
- res = optimize_node(res);
- IRN_VRFY_IRG(res, irg);
- return res;
-}
-
-/*
- * construct a Max: Max(a,b) = a > b ? a : b
- */
-ir_node *
-new_rd_Max(dbg_info *db, ir_graph *irg, ir_node *block,
- ir_node *op1, ir_node *op2, ir_mode *mode)
-{
- ir_node *in[2];
- ir_node *res;
-
- if (! op_Max) {
- panic("cannot create Max node, not allowed");
- }
-
- in[0] = op1;
- in[1] = op2;
- res = new_ir_node(db, irg, block, op_Max, mode, 2, in);
- res = optimize_node(res);
- IRN_VRFY_IRG(res, irg);
- return res;
-}
-
-ir_node *
-new_r_Min(ir_graph *irg, ir_node *block,
- ir_node *op1, ir_node *op2, ir_mode *mode) {
- return new_rd_Min(NULL, irg, block, op1, op2, mode);
-}
-
-ir_node *
-new_r_Max(ir_graph *irg, ir_node *block,
- ir_node *op1, ir_node *op2, ir_mode *mode) {
- return new_rd_Max(NULL, irg, block, op1, op2, mode);
-}
-
-ir_node *
-new_d_Min(dbg_info *db, ir_node *op1, ir_node *op2, ir_mode *mode) {
- return new_rd_Min(db, current_ir_graph, current_ir_graph->current_block,
- op1, op2, mode);
-}
-
-ir_node *
-new_d_Max(dbg_info *db, ir_node *op1, ir_node *op2, ir_mode *mode) {
- return new_rd_Max(db, current_ir_graph, current_ir_graph->current_block,
- op1, op2, mode);
-}
-
-ir_node *
-new_Min(ir_node *op1, ir_node *op2, ir_mode *mode) {
- return new_d_Min(NULL, op1, op2, mode);
-}
-
-ir_node *
-new_Max(ir_node *op1, ir_node *op2, ir_mode *mode) {
- return new_d_Max(NULL, op1, op2, mode);
-}
-
-/* optimizations */
-
-/**
- * return the value of a Min
- */
-static tarval *computed_value_Min(const ir_node *n) {
- ir_node *a = get_binop_left(n);
- ir_node *b = get_binop_right(n);
-
- tarval *ta = value_of(a);
- tarval *tb = value_of(b);
-
- if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
- pn_Cmp res = tarval_cmp(ta, tb);
-
- /* beware: there might be Unordered tarvals here, in that
- * case let the backend decide, do NOT optimize */
- if (res == pn_Cmp_Lt)
- return ta;
- if (res == pn_Cmp_Gt || res == pn_Cmp_Eq)
- return tb;
- }
- return tarval_bad;
-}
-
-/**
- * return the value of a Max
- */
-static tarval *computed_value_Max(const ir_node *n) {
- ir_node *a = get_binop_left(n);
- ir_node *b = get_binop_right(n);
-
- tarval *tb = value_of(b);
- tarval *ta = value_of(a);
-
- if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
- pn_Cmp res = tarval_cmp(ta, tb);
-
- /* beware: there might be Unordered tarvals here, in that
- * case let the backend decide, do NOT optimize */
- if (res == pn_Cmp_Gt)
- return ta;
- if (res == pn_Cmp_Lt || res == pn_Cmp_Eq)
- return tb;
- }
- return tarval_bad;
-}
-
-/**
- * Returns an equivalent node for a Min/Max node.
- * We do not allow Exceptions in our Min/Max, so there will be always
- * an result.
- * The problem is Min(NaN, NaN) == NaN ???.
- */
-static ir_node *equivalent_node_MinMax(ir_node *n)
-{
- ir_node *a, *b;
- ir_mode *mode;
- tarval *tv;
-
- if (settings.minmax_handle_NaN == 0 && mode_is_float(get_irn_mode(n)))
- return n;
-
- a = get_binop_left(n);
- b = get_binop_right(n);
-
- if (a == b) {
- DBG_OPT_ALGSIM0(n, a, FS_OPT_MIN_MAX_EQ);
- return a;
- }
-
- mode = get_irn_mode(n);
- tv = n->op == op_Max ? get_mode_min(mode) : get_mode_max(mode);
-
- if (value_of(b) == tv) {
- DBG_OPT_ALGSIM0(n, a, FS_OPT_MIN_MAX_EQ);
- return a;
- }
- if (value_of(a) == tv) {
- DBG_OPT_ALGSIM0(n, b, FS_OPT_MIN_MAX_EQ);
- return b;
- }
-
- return n;
-}
-
-#define equivalent_node_Min equivalent_node_MinMax
-#define equivalent_node_Max equivalent_node_MinMax
-
-/*
- * Create Min and Max from Mux nodes
- */
-ir_node *arch_transform_node_Mux(ir_node *n)
-{
- if (settings.enabled_ops & ARCH_OPS_MINMAX) {
- ir_node *oldn = n, *cmp, *proj = get_Mux_sel(n);
- long proj_nr;
-
- if (get_irn_op(proj) != op_Proj)
- return n;
-
- cmp = get_Proj_pred(proj);
- if (is_Cmp(cmp)) {
- ir_node *a = get_Cmp_left(cmp);
- ir_node *b = get_Cmp_right(cmp);
- ir_node *t = get_Mux_true(n);
- ir_node *f = get_Mux_false(n);
-
- proj_nr = get_Proj_proj(proj);
-
- if (proj_nr == pn_Cmp_Lt || proj_nr == pn_Cmp_Le) {
- if (a == t && b == f) {
- /* a </<= b ? a : b ==> Min(a,b) */
- n = new_rd_Min(get_irn_dbg_info(n),
- current_ir_graph,
- get_nodes_block(n),
- a, b,
- get_irn_mode(n));
-
- DBG_OPT_ALGSIM1(oldn, cmp, proj, n, FS_OPT_MUX_TO_MIN);
- return n;
- }
- else if (a == f && b == t) {
- /* a </<= b ? b : a ==> Max(a,b) */
- n = new_rd_Max(get_irn_dbg_info(n),
- current_ir_graph,
- get_nodes_block(n),
- a, b,
- get_irn_mode(n));
-
- DBG_OPT_ALGSIM1(oldn, cmp, proj, n, FS_OPT_MUX_TO_MAX);
- return n;
- }
- }
- else if (proj_nr == pn_Cmp_Gt || proj_nr == pn_Cmp_Ge) {
- if (a == t && b == f) {
- /* a >/>= b ? a : b ==> Max(a,b) */
- n = new_rd_Max(get_irn_dbg_info(n),
- current_ir_graph,
- get_nodes_block(n),
- a, b,
- get_irn_mode(n));
-
- DBG_OPT_ALGSIM1(oldn, cmp, proj, n, FS_OPT_MUX_TO_MAX);
- return n;
- }
- else if (a == f && b == t) {
- /* a >/>= b ? b : a ==> Min(a,b) */
- n = new_rd_Min(get_irn_dbg_info(n),
- current_ir_graph,
- get_nodes_block(n),
- a, b,
- get_irn_mode(n));
-
- DBG_OPT_ALGSIM1(oldn, cmp, proj, n, FS_OPT_MUX_TO_MIN);
- return n;
- }
- }
- }
- }
- return n;
-}
-
-/**
- * verify a MinMax node
- */
-static int verify_node_MinMax(ir_node *n, ir_graph *irg) {
- ir_mode *mymode = get_irn_mode(n);
- ir_mode *op1mode = get_irn_mode(get_binop_left(n));
- ir_mode *op2mode = get_irn_mode(get_binop_right(n));
- (void) irg;
-
- ASSERT_AND_RET(
- /* MinMax: BB x numP x numP --> numP */
- op1mode == mymode &&
- op2mode == mymode &&
- mode_is_data(mymode),
- "Min or Max node", 0
- );
- return 1;
-}
-
-/*
- * initialize the ops.
- */
-void firm_archops_init(const arch_ops_info *info)
-{
- ir_op_ops ops;
-
- if (! info)
- info = &default_settings;
-
- memcpy(&settings, info, sizeof(settings));
-
- if (info->enabled_ops & ARCH_OPS_MINMAX) {
- memset(&ops, 0, sizeof(ops));
-
- op_Min->ops.computed_value = computed_value_Min;
- op_Min->ops.equivalent_node = equivalent_node_Min;
- op_Min->ops.verify_node = verify_node_MinMax;
-
- op_Max->ops.computed_value = computed_value_Max;
- op_Max->ops.equivalent_node = equivalent_node_Max;
- op_Max->ops.verify_node = verify_node_MinMax;
- }
-}
#include "bearch_TEMPLATE_t.h"
#include "TEMPLATE_nodes_attr.h"
-#include "archop.h"
#include "TEMPLATE_transform.h"
#include "TEMPLATE_new_nodes.h"
#include "TEMPLATE_map_regs.h"
0, /* no dword lowering */
0, /* no inline assembly */
0, /* no immediate floating point mode. */
- NULL, /* no additional opcodes */
NULL, /* will be set later */
NULL, /* no creator function */
NULL, /* context for create_intrinsic_fkt */
#include "bearch_arm_t.h"
#include "arm_nodes_attr.h"
-#include "archop.h"
#include "arm_transform.h"
#include "arm_optimize.h"
#include "arm_new_nodes.h"
1, /* need dword lowering */
0, /* don't support inline assembler yet */
0, /* no immediate floating point mode. */
- NULL, /* no additional opcodes */
NULL, /* will be set later */
NULL, /* but yet no creator function */
NULL, /* context for create_intrinsic_fkt */
0, /* need dword lowering */
0, /* don't support inline assembler yet */
0, /* no immediate floating point mode. */
- NULL, /* no additional opcodes */
NULL, /* will be set later */
NULL, /* but yet no creator function */
NULL, /* context for create_intrinsic_fkt */
1, /* allow Mulhs */
1, /* allow Mulus */
- 32 /* Mulh allowed up to 32 bit */
+ 32, /* Mulh allowed up to 32 bit */
};
static backend_params p = {
1, /* need dword lowering */
1, /* support inline assembly */
0, /* no immediate floating point mode. */
- NULL, /* no additional opcodes */
NULL, /* will be set later */
ia32_create_intrinsic_fkt,
&intrinsic_env, /* context for ia32_create_intrinsic_fkt */
#include "irprintf.h"
#include "debug.h"
#include "irdom.h"
-#include "archop.h"
#include "error.h"
#include "array_t.h"
#include "height.h"
1, /* need dword lowering */
0, /* don't support inline assembler yet */
0, /* no immediate floating point mode. */
- NULL, /* no additional opcodes */
NULL, /* will be set later */
NULL, /* but yet no creator function */
NULL, /* context for create_intrinsic_fkt */
#include "bearch_mips_t.h"
#include "mips_nodes_attr.h"
-#include "archop.h"
#include "mips_transform.h"
#include "mips_new_nodes.h"
#include "mips_map_regs.h"
1, /* need dword lowering */
0, /* don't support inline assembler yet */
0, /* no immediate floating point mode. */
- NULL, /* no additional opcodes */
NULL, /* will be set later */
NULL, /* but yet no creator function */
NULL, /* context for create_intrinsic_fkt */
#include "bearch_ppc32_t.h"
#include "ppc32_nodes_attr.h"
-#include "archop.h"
#include "ppc32_transform.h"
#include "ppc32_new_nodes.h"
#include "ppc32_map_regs.h"
arch_dep_init(arch_dep_default_factory);
arch_dep_set_opts(0);
- firm_archops_init(def_params.arch_op_settings);
-
#ifdef DEBUG_libfirm
/* integrated debugger extension */
firm_init_debugger();
#include "irhooks.h"
#include "irarch.h"
#include "hashptr.h"
-#include "archop.h"
#include "opt_confirms.h"
#include "opt_polymorphy.h"
#include "irtools.h"
}
}
}
- return arch_transform_node_Mux(n);
+
+ return n;
} /* transform_node_Mux */
/**
shiftop_tp_s = new_type_method(IDENT("shiftop_s_intrinsic"), 3, 2);
set_method_param_type(shiftop_tp_s, 0, tp_u);
set_method_param_type(shiftop_tp_s, 1, tp_s);
- /* beware: shift count is always mode_Iu */
set_method_param_type(shiftop_tp_s, 2, tp_u);
set_method_res_type(shiftop_tp_s, 0, tp_u);
set_method_res_type(shiftop_tp_s, 1, tp_s);
#include <assert.h>
#include "iroptimize.h"
-#include "archop.h"
#include "irflag.h"
#include "ircons.h"
#include "list.h"
if (is_tarval(pred->type.tv) && tarval_is_all_one(pred->type.tv))
return 0;
break;
- case iro_Min:
- case iro_Max:
- /* all inputs are followers */
- return 1;
default:
assert(!"opcode not implemented yet");
break;
node->type = pred->type;
} /* compute_Confirm */
-/**
- * (Re-)compute the type for a Max.
- *
- * @param node the node
- */
-static void compute_Max(node_t *node) {
- ir_node *op = node->node;
- node_t *l = get_irn_node(get_binop_left(op));
- node_t *r = get_irn_node(get_binop_right(op));
- lattice_elem_t a = l->type;
- lattice_elem_t b = r->type;
-
- if (a.tv == tarval_top || b.tv == tarval_top) {
- node->type.tv = tarval_top;
- } else if (is_con(a) && is_con(b)) {
- /* both nodes are constants, we can probably do something */
- if (a.tv == b.tv) {
- /* this case handles SymConsts as well */
- node->type = a;
- } else {
- ir_mode *mode = get_irn_mode(op);
- tarval *tv_min = get_mode_min(mode);
-
- if (a.tv == tv_min)
- node->type = b;
- else if (b.tv == tv_min)
- node->type = a;
- else if (is_tarval(a.tv) && is_tarval(b.tv)) {
- if (tarval_cmp(a.tv, b.tv) & pn_Cmp_Gt)
- node->type.tv = a.tv;
- else
- node->type.tv = b.tv;
- } else {
- node->type.tv = tarval_bad;
- }
- }
- } else if (r->part == l->part) {
- /* both nodes congruent, we can probably do something */
- node->type = a;
- } else {
- node->type.tv = tarval_bottom;
- }
-} /* compute_Max */
-
-/**
- * (Re-)compute the type for a Min.
- *
- * @param node the node
- */
-static void compute_Min(node_t *node) {
- ir_node *op = node->node;
- node_t *l = get_irn_node(get_binop_left(op));
- node_t *r = get_irn_node(get_binop_right(op));
- lattice_elem_t a = l->type;
- lattice_elem_t b = r->type;
-
- if (a.tv == tarval_top || b.tv == tarval_top) {
- node->type.tv = tarval_top;
- } else if (is_con(a) && is_con(b)) {
- /* both nodes are constants, we can probably do something */
- if (a.tv == b.tv) {
- /* this case handles SymConsts as well */
- node->type = a;
- } else {
- ir_mode *mode = get_irn_mode(op);
- tarval *tv_max = get_mode_max(mode);
-
- if (a.tv == tv_max)
- node->type = b;
- else if (b.tv == tv_max)
- node->type = a;
- else if (is_tarval(a.tv) && is_tarval(b.tv)) {
- if (tarval_cmp(a.tv, b.tv) & pn_Cmp_Gt)
- node->type.tv = a.tv;
- else
- node->type.tv = b.tv;
- } else {
- node->type.tv = tarval_bad;
- }
- }
- } else if (r->part == l->part) {
- /* both nodes congruent, we can probably do something */
- node->type = a;
- } else {
- node->type.tv = tarval_bottom;
- }
-} /* compute_Min */
-
/**
* (Re-)compute the type for a given node.
*
return node;
} /* identity_Mux */
-/**
- * Calculates the Identity for Min nodes.
- */
-static node_t *identity_Min(node_t *node) {
- ir_node *op = node->node;
- node_t *a = get_irn_node(get_binop_left(op));
- node_t *b = get_irn_node(get_binop_right(op));
- ir_mode *mode = get_irn_mode(op);
- tarval *tv_max;
-
- if (a->part == b->part) {
- /* leader of multiple predecessors */
- return a;
- }
-
- /* works even with NaN */
- tv_max = get_mode_max(mode);
- if (a->type.tv == tv_max)
- return b;
- if (b->type.tv == tv_max)
- return a;
- return node;
-} /* identity_Min */
-
-/**
- * Calculates the Identity for Max nodes.
- */
-static node_t *identity_Max(node_t *node) {
- ir_node *op = node->node;
- node_t *a = get_irn_node(get_binop_left(op));
- node_t *b = get_irn_node(get_binop_right(op));
- ir_mode *mode = get_irn_mode(op);
- tarval *tv_min;
-
- if (a->part == b->part) {
- /* leader of multiple predecessors */
- return a;
- }
-
- /* works even with NaN */
- tv_min = get_mode_min(mode);
- if (a->type.tv == tv_min)
- return b;
- if (b->type.tv == tv_min)
- return a;
- return node;
-} /* identity_Max */
-
/**
* Calculates the Identity for nodes.
*/
return identity_Confirm(node);
case iro_Mux:
return identity_Mux(node);
- case iro_Min:
- return identity_Min(node);
- case iro_Max:
- return identity_Max(node);
default:
return node;
}
SET(Return);
SET(End);
SET(Call);
-
- if (op_Max != NULL)
- SET(Max);
- if (op_Min != NULL)
- SET(Min);
} /* set_compute_functions */
/**