bescripts: Copy all common node attributes into the constructor variants.
[libfirm] / ir / be / bearch.h
index 62326be..02daa70 100644 (file)
 #include <stdbool.h>
 
 #include "firm_types.h"
-#include "bitset.h"
-#include "obst.h"
 #include "raw_bitset.h"
-#include "irop_t.h"
 
 #include "be_types.h"
 #include "beinfo.h"
 #include "be.h"
-#include "beirg.h"
-#include "error.h"
 
 /**
  * this constant is returned by the get_sp_bias functions if the stack
@@ -59,16 +54,13 @@ typedef enum arch_register_type_t {
        arch_register_type_none         = 0,
        /** Do not consider this register when allocating. */
        arch_register_type_ignore       = 1U << 0,
-       /** The emitter can choose an arbitrary register. The register fulfills any
-        * register constraints as long as the register class matches */
-       arch_register_type_joker        = 1U << 1,
        /** This is just a virtual register. Virtual registers fulfill any register
         * constraints as long as the register class matches. It is a allowed to
         * have multiple definitions for the same virtual register at a point */
-       arch_register_type_virtual      = 1U << 2,
+       arch_register_type_virtual      = 1U << 1,
        /** The register represents a state that should be handled by bestate
         * code */
-       arch_register_type_state        = 1U << 3,
+       arch_register_type_state        = 1U << 2,
 } arch_register_type_t;
 ENUM_BITSET(arch_register_type_t)
 
@@ -97,15 +89,8 @@ typedef enum arch_register_req_type_t {
 } arch_register_req_type_t;
 ENUM_BITSET(arch_register_req_type_t)
 
-extern const arch_register_req_t *arch_no_register_req;
-
-/**
- * Print information about a register requirement in human readable form
- * @param F   output stream/file
- * @param req The requirements structure to format.
- */
-void arch_dump_register_req(FILE *F, const arch_register_req_t *req,
-                            const ir_node *node);
+extern arch_register_req_t const arch_no_requirement;
+#define arch_no_register_req (&arch_no_requirement)
 
 void arch_dump_register_reqs(FILE *F, const ir_node *node);
 void arch_dump_reqs_and_registers(FILE *F, const ir_node *node);
@@ -116,9 +101,6 @@ ir_entity *arch_get_frame_entity(const ir_node *irn);
 int        arch_get_sp_bias(ir_node *irn);
 
 int             arch_get_op_estimated_cost(const ir_node *irn);
-arch_inverse_t *arch_get_inverse(const ir_node *irn, int i,
-                                 arch_inverse_t *inverse,
-                                 struct obstack *obstack);
 int             arch_possible_memory_operand(const ir_node *irn,
                                              unsigned int i);
 void            arch_perform_memory_operand(ir_node *irn, ir_node *spill,
@@ -137,9 +119,9 @@ void arch_set_irn_register(ir_node *irn, const arch_register_t *reg);
 /**
  * Set the register for a certain output operand.
  */
-void arch_set_irn_register_out(ir_node *irn, int pos, const arch_register_t *r);
+void arch_set_irn_register_out(ir_node *irn, unsigned pos, const arch_register_t *r);
 
-const arch_register_t *arch_get_irn_register_out(const ir_node *irn, int pos);
+const arch_register_t *arch_get_irn_register_out(const ir_node *irn, unsigned pos);
 const arch_register_t *arch_get_irn_register_in(const ir_node *irn, int pos);
 
 /**
@@ -149,8 +131,6 @@ static inline const arch_register_req_t *arch_get_irn_register_req_in(
                const ir_node *node, int pos)
 {
        const backend_info_t *info = be_get_info(node);
-       if (info->in_reqs == NULL)
-               return arch_no_register_req;
        return info->in_reqs[pos];
 }
 
@@ -158,19 +138,17 @@ static inline const arch_register_req_t *arch_get_irn_register_req_in(
  * Get register constraint for a produced result (the @p pos result)
  */
 static inline const arch_register_req_t *arch_get_irn_register_req_out(
-               const ir_node *node, int pos)
+               const ir_node *node, unsigned pos)
 {
        const backend_info_t *info = be_get_info(node);
-       if (info->out_infos == NULL)
-               return arch_no_register_req;
        return info->out_infos[pos].req;
 }
 
-static inline void arch_set_irn_register_req_out(ir_node *node, int pos,
+static inline void arch_set_irn_register_req_out(ir_node *node, unsigned pos,
                const arch_register_req_t *req)
 {
        backend_info_t *info = be_get_info(node);
-       assert(pos < (int)ARR_LEN(info->out_infos));
+       assert(pos < (unsigned)ARR_LEN(info->out_infos));
        info->out_infos[pos].req = req;
 }
 
@@ -188,14 +166,37 @@ static inline const arch_register_req_t **arch_get_irn_register_reqs_in(
        return info->in_reqs;
 }
 
-const arch_register_req_t *arch_get_irn_register_req(const ir_node *node);
+static inline 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);
+       assert(pos < ARR_LEN(info->out_infos));
+       return &info->out_infos[pos];
+}
+
+static inline 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;
+}
 
 /**
  * Get the flags of a node.
  * @param irn The node.
  * @return The flags.
  */
-arch_irn_flags_t arch_get_irn_flags(const ir_node *irn);
+static inline arch_irn_flags_t arch_get_irn_flags(const ir_node *node)
+{
+       backend_info_t const *const info = be_get_info(node);
+       return info->flags;
+}
 
 void arch_set_irn_flags(ir_node *node, arch_irn_flags_t flags);
 void arch_add_irn_flags(ir_node *node, arch_irn_flags_t flags);
@@ -204,18 +205,12 @@ void arch_add_irn_flags(ir_node *node, arch_irn_flags_t flags);
 
 static inline unsigned arch_get_irn_n_outs(const ir_node *node)
 {
-       backend_info_t *info = be_get_info(node);
-       if (info->out_infos == NULL)
-               return 0;
-
+       backend_info_t *const info = be_get_info(node);
        return (unsigned)ARR_LEN(info->out_infos);
 }
 
-/**
- * Start codegeneration
- */
-arch_env_t *arch_env_begin_codegeneration(const arch_isa_if_t *isa,
-                                          be_main_env_t *main_env);
+#define be_foreach_out(node, i) \
+       for (unsigned i = 0, i##__n = arch_get_irn_n_outs(node); i != i##__n; ++i)
 
 /**
  * Register an instruction set architecture
@@ -230,29 +225,15 @@ struct arch_register_t {
        const arch_register_class_t *reg_class;    /**< The class of the register */
        unsigned short               index;        /**< The index of the register in
                                                        the class. */
-       unsigned short               global_index; /** The global index this register
-                                                                                              in the architecture. */
+       unsigned short               global_index; /**< The global index this
+                                                                                                   register in the architecture. */
        arch_register_type_t         type;         /**< The type of the register. */
        /** register constraint allowing just this register */
        const arch_register_req_t   *single_req;
+       /** register number in dwarf debugging format */
+       unsigned short               dwarf_number;
 };
 
-static inline const arch_register_class_t *arch_register_get_class(
-               const arch_register_t *reg)
-{
-       return reg->reg_class;
-}
-
-static inline unsigned arch_register_get_index(const arch_register_t *reg)
-{
-       return reg->index;
-}
-
-static inline const char *arch_register_get_name(const arch_register_t *reg)
-{
-       return reg->name;
-}
-
 /**
  * A class of registers.
  * Like general purpose or floating point.
@@ -307,14 +288,16 @@ struct arch_register_req_t {
        arch_register_req_type_t     type; /**< The type of the constraint. */
        const arch_register_class_t *cls;  /**< The register class this constraint
                                                belongs to. */
-       const unsigned *limited;            /**< allowed register bitset */
-       unsigned other_same;                /**< Bitmask of ins which should use the
-                                                same register (should_be_same). */
-       unsigned other_different;           /**< Bitmask of ins which shall use a
-                                                different register
-                                                (must_be_different) */
-       unsigned char width;                /**< specifies how many sequential
-                                                registers are required */
+       const unsigned *limited;           /**< allowed register bitset
+                                               (in case of wide-values this is
+                                                only about the first register) */
+       unsigned other_same;               /**< Bitmask of ins which should use the
+                                               same register (should_be_same). */
+       unsigned other_different;          /**< Bitmask of ins which shall use a
+                                               different register
+                                               (must_be_different) */
+       unsigned char width;               /**< specifies how many sequential
+                                               registers are required */
 };
 
 static inline bool reg_reqs_equal(const arch_register_req_t *req1,
@@ -339,18 +322,6 @@ static inline bool reg_reqs_equal(const arch_register_req_t *req1,
        return true;
 }
 
-/**
- * An inverse operation returned by the backend
- */
-struct arch_inverse_t {
-       int      n;       /**< count of nodes returned in nodes array */
-       int      costs;   /**< costs of this remat */
-
-       /** nodes for this inverse operation. shall be in schedule order.
-        * last element is the target value */
-       ir_node  **nodes;
-};
-
 struct arch_irn_ops_t {
 
        /**
@@ -381,22 +352,6 @@ struct arch_irn_ops_t {
         */
        int (*get_sp_bias)(const ir_node *irn);
 
-       /**
-        * Returns an inverse operation which yields the i-th argument
-        * of the given node as result.
-        *
-        * @param irn       The original operation
-        * @param i         Index of the argument we want the inverse operation to
-        *                  yield
-        * @param inverse   struct to be filled with the resulting inverse op
-        * @param obstack   The obstack to use for allocation of the returned nodes
-        *                  array
-        * @return          The inverse operation or NULL if operation invertible
-        */
-       arch_inverse_t *(*get_inverse)(const ir_node *irn, int i,
-                                      arch_inverse_t *inverse,
-                                      struct obstack *obstack);
-
        /**
         * Get the estimated cycle count for @p irn.
         *
@@ -437,6 +392,11 @@ struct arch_isa_if_t {
         */
        void (*init)(void);
 
+       /**
+        * Fress resources allocated by this isa interface.
+        */
+       void (*finish)(void);
+
        /**
         * Returns the frontend settings needed for this backend.
         */
@@ -465,7 +425,7 @@ struct arch_isa_if_t {
         * Start codegeneration
         * @return a new isa instance
         */
-       arch_env_t *(*begin_codegeneration)(const be_main_env_t *env);
+       arch_env_t *(*begin_codegeneration)(void);
 
        /**
         * Free the isa instance.
@@ -547,7 +507,7 @@ struct arch_isa_if_t {
         * Called directly before done is called. This should be the last place
         * where the irg is modified.
         */
-       void (*finish)(ir_graph *irg);
+       void (*finish_graph)(ir_graph *irg);
 
        /**
         * Called after everything happened. This call should emit the final
@@ -560,9 +520,6 @@ struct arch_isa_if_t {
 #define arch_env_handle_intrinsics(env)                \
        do { if((env)->impl->handle_intrinsics != NULL) (env)->impl->handle_intrinsics(); } while(0)
 #define arch_env_get_call_abi(env,tp,abi)              ((env)->impl->get_call_abi((tp), (abi)))
-#define arch_env_get_params(env)                       ((env)->impl->get_params())
-#define arch_env_parse_asm_constraint(env,c)           ((env)->impl->parse_asm_constraint((c))
-#define arch_env_is_valid_clobber(env,clobber)         ((env)->impl->is_valid_clobber((clobber))
 #define arch_env_mark_remat(env,node) \
        do { if ((env)->impl->mark_remat != NULL) (env)->impl->mark_remat((node)); } while(0)
 
@@ -580,10 +537,7 @@ struct arch_env_t {
        const arch_register_class_t *register_classes; /**< register classes */
        const arch_register_t *sp;               /**< The stack pointer register. */
        const arch_register_t *bp;               /**< The base pointer register. */
-       const arch_register_class_t *link_class; /**< The static link pointer
-                                                     register class. */
        int                    stack_alignment;  /**< power of 2 stack alignment */
-       const be_main_env_t   *main_env;         /**< the be main environment */
        int                    spill_cost;       /**< cost for a be_Spill node */
        int                    reload_cost;      /**< cost for a be_Reload node */
        bool                   custom_abi : 1;   /**< backend does all abi handling
@@ -594,52 +548,66 @@ struct arch_env_t {
 static inline bool arch_irn_is_ignore(const ir_node *irn)
 {
        const arch_register_req_t *req = arch_get_irn_register_req(irn);
-       return req->type & arch_register_req_type_ignore;
+       return arch_register_req_is(req, ignore);
 }
 
 static inline bool arch_irn_consider_in_reg_alloc(
                const arch_register_class_t *cls, const ir_node *node)
 {
        const arch_register_req_t *req = arch_get_irn_register_req(node);
-       return
-               req->cls == cls &&
-               !(req->type & arch_register_req_type_ignore);
+       return req->cls == cls && !arch_register_req_is(req, ignore);
 }
 
+#define be_foreach_value(node, value, code) \
+       do { \
+               if (get_irn_mode(node) == mode_T) { \
+                       foreach_out_edge(node, node##__edge) { \
+                               ir_node *const value = get_edge_src_irn(node##__edge); \
+                               if (!is_Proj(value)) \
+                                       continue; \
+                               code \
+                       } \
+               } else { \
+                       ir_node *const value = node; \
+                       code \
+               } \
+       } while (0)
+
 /**
  * Iterate over all values defined by an instruction.
  * Only looks at values in a certain register class where the requirements
  * are not marked as ignore.
  * Executes @p code for each definition.
  */
-#define be_foreach_definition_(node, cls, value, code)                     \
-       do {                                                                   \
-       if (get_irn_mode(node) == mode_T) {                                    \
-               const ir_edge_t *edge_;                                            \
-               foreach_out_edge(node, edge_) {                                    \
-                       const arch_register_req_t *req_;                               \
-                       value = get_edge_src_irn(edge_);                               \
-                       req_  = arch_get_irn_register_req(value);                      \
-                       if (req_->cls != cls)                                          \
-                               continue;                                                  \
-                       code                                                           \
-               }                                                                  \
-       } else {                                                               \
-               const arch_register_req_t *req_ = arch_get_irn_register_req(node); \
-               value = node;                                                      \
-               if (req_->cls == cls) {                                            \
-                       code                                                           \
-               }                                                                  \
-       }                                                                      \
-       } while (0)
+#define be_foreach_definition_(node, ccls, value, req, code) \
+       be_foreach_value(node, value, \
+               arch_register_req_t const *const req = arch_get_irn_register_req(value); \
+               if (req->cls != ccls) \
+                       continue; \
+               code \
+       )
 
-#define be_foreach_definition(node, cls, value, code)                      \
-       be_foreach_definition_(node, cls, value,                               \
-               if (req_->type & arch_register_req_type_ignore)                    \
-                       continue;                                                      \
-               code                                                               \
+#define be_foreach_definition(node, ccls, value, req, code) \
+       be_foreach_definition_(node, ccls, value, req, \
+               if (arch_register_req_is(req, ignore)) \
+                       continue; \
+               code \
        )
 
+#define be_foreach_use(node, ccls, in_req, value, value_req, code)           \
+       do {                                                                     \
+       for (int i_ = 0, n_ = get_irn_arity(node); i_ < n_; ++i_) {              \
+               const arch_register_req_t *in_req = arch_get_irn_register_req_in(node, i_); \
+               if (in_req->cls != ccls)                                             \
+                       continue;                                                        \
+               ir_node                   *value     = get_irn_n(node, i_);              \
+               const arch_register_req_t *value_req = arch_get_irn_register_req(value); \
+               if (value_req->type & arch_register_req_type_ignore)                 \
+                       continue;                                                        \
+               code                                                                 \
+       }                                                                        \
+       } while (0)
+
 static inline const arch_register_class_t *arch_get_irn_reg_class(
                const ir_node *node)
 {