2 * This file is part of libFirm.
3 * Copyright (C) 2012 University of Karlsruhe.
8 * @brief Some machine dependent optimizations.
10 * @author Sebastian Hack
12 #ifndef FIRM_IR_IRARCH_H
13 #define FIRM_IR_IRARCH_H
15 #include "firm_types.h"
19 * @addtogroup iroptimize
24 * The Multiplication replacement can consist of the following instructions.
26 typedef enum insn_kind {
27 LEA, /**< the LEA instruction */
28 SHIFT, /**< the SHIFT instruction */
29 SUB, /**< the SUB instruction */
30 ADD, /**< the ADD instruction */
31 ZERO, /**< creates a ZERO constant */
32 MUL, /**< the original MUL instruction */
33 ROOT /**< the ROOT value that is multiplied */
37 * A Callback for evaluating the costs of an instruction.
39 * @param kind the instruction
40 * @param mode the mode of the instruction
41 * @param tv for MUL instruction, the multiplication constant
43 * @return the costs of this instruction
45 typedef int (*evaluate_costs_func)(insn_kind kind, const ir_mode *mode, ir_tarval *tv);
48 * A parameter structure that drives the machine dependent Firm
51 typedef struct ir_settings_arch_dep_t {
52 /* Mul optimization */
53 unsigned also_use_subs : 1; /**< Use also Subs when resolving Muls to shifts */
54 unsigned maximum_shifts; /**< The maximum number of shifts that shall be inserted for a mul. */
55 unsigned highest_shift_amount; /**< The highest shift amount you want to
56 tolerate. Muls which would require a higher
57 shift constant are left. */
58 evaluate_costs_func evaluate; /**< Evaluate the costs of a generated instruction. */
60 /* Div/Mod optimization */
61 unsigned allow_mulhs : 1; /**< Use the Mulhs operation for division by constant */
62 unsigned allow_mulhu : 1; /**< Use the Mulhu operation for division by constant */
63 unsigned max_bits_for_mulh; /**< Maximum number of bits the Mulh operation can take.
64 Modes with higher amount of bits will use Mulh */
65 } ir_settings_arch_dep_t;
68 * A factory function, that provides architecture parameters for
69 * machine dependent optimizations.
71 typedef const ir_settings_arch_dep_t *(*arch_dep_params_factory_t)(void);
76 typedef enum arch_dep_opts_t {
78 arch_dep_mul_to_shift = 1u << 0, /**< optimize Mul into Shift/Add/Sub */
79 arch_dep_div_by_const = 1u << 1, /**< optimize Div into Shift/Add/Mulh */
80 arch_dep_mod_by_const = 1u << 2 /**< optimize Mod into Shift/Add/Mulh */
82 ENUM_BITSET(arch_dep_opts_t)
85 * Sets the optimizations that shall be applied.
86 * @param opts An optimization bit mask.
88 FIRM_API void arch_dep_set_opts(arch_dep_opts_t opts);
91 * Replaces Muls with Lea/Shifts/Add/Subs if these
92 * have smaller costs than the original multiplication.
94 * @param irn The Firm node to inspect.
95 * @return A replacement expression for irn.
97 FIRM_API ir_node *arch_dep_replace_mul_with_shifts(ir_node *irn);
100 * Replaces Divs with Shifts and Add/Subs and Mulh.
101 * This function is driven by the 3 parameters:
104 * - max_bits_for_mulh
106 * If irn is a Div with a Const, the constant is inspected if it meets the
107 * requirements of the variables stated above. If a Shl/Add/Sub/Mulh
108 * sequence can be generated that meets these requirements, this expression
109 * is returned. In each other case irn is returned unmodified.
111 * @param irn The Firm node to inspect.
112 * @return A replacement expression for irn.
114 FIRM_API ir_node *arch_dep_replace_div_by_const(ir_node *irn);
117 * Replaces Mods with Shifts and Add/Subs and Mulh.
118 * This function is driven by the 3 parameters:
121 * - max_bits_for_mulh
123 * If irn is a Mod with a Const, the constant is inspected if it meets the
124 * requirements of the variables stated above. If a Shl/Add/Sub/Mulh
125 * sequence can be generated that meets these requirements, this expression
126 * is returned. In each other case irn is returned unmodified.
128 * @param irn The Firm node to inspect.
129 * @return A replacement expression for irn.
131 FIRM_API ir_node *arch_dep_replace_mod_by_const(ir_node *irn);