remove ilp scheduler; simplify listsched interface
[libfirm] / ir / be / bearch.h
index bfa1de8..81c4830 100644 (file)
@@ -84,12 +84,14 @@ typedef enum arch_register_req_type_t {
        arch_register_req_type_should_be_same    = 1U << 2,
        /** The register must be unequal from some other at the node. */
        arch_register_req_type_must_be_different = 1U << 3,
+       /** The registernumber should be aligned (in case of multiregister values)*/
+       arch_register_req_type_aligned           = 1U << 4,
        /** ignore while allocating registers */
-       arch_register_req_type_ignore            = 1U << 4,
+       arch_register_req_type_ignore            = 1U << 5,
        /** the output produces a new value for the stack pointer
         * (this is not really a constraint but a marker to guide the stackpointer
         * rewiring logic) */
-       arch_register_req_type_produces_sp       = 1U << 5,
+       arch_register_req_type_produces_sp       = 1U << 6,
 } arch_register_req_type_t;
 
 extern const arch_register_req_t *arch_no_register_req;
@@ -246,26 +248,22 @@ struct arch_register_t {
        const arch_register_req_t   *single_req;
 };
 
-static inline const arch_register_class_t *_arch_register_get_class(
+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)
+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)
+static inline const char *arch_register_get_name(const arch_register_t *reg)
 {
        return reg->name;
 }
 
-#define arch_register_get_class(reg)        _arch_register_get_class(reg)
-#define arch_register_get_index(reg)        _arch_register_get_index(reg)
-#define arch_register_get_name(reg)         _arch_register_get_name(reg)
-
 /**
  * Convenience macro to check for register type.
  * @param req   A pointer to register.
@@ -305,15 +303,13 @@ struct arch_register_class_t {
 /** return the register class flags */
 #define arch_register_class_flags(cls) ((cls)->flags)
 
-static inline const arch_register_t *_arch_register_for_index(
+static inline const arch_register_t *arch_register_for_index(
                const arch_register_class_t *cls, unsigned idx)
 {
        assert(idx < cls->n_regs);
        return &cls->regs[idx];
 }
 
-#define arch_register_for_index(cls, idx)   _arch_register_for_index(cls, idx)
-
 /**
  * Convenience macro to check for set constraints.
  * @param req   A pointer to register requirements.
@@ -337,6 +333,8 @@ struct arch_register_req_t {
        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 int reg_reqs_equal(const arch_register_req_t *req1,
@@ -379,16 +377,6 @@ struct arch_inverse_t {
 
 struct arch_irn_ops_t {
 
-       /**
-        * Get the register requirements for a given operand.
-        * @param irn The node.
-        * @param pos The operand's position
-        * @return    The register requirements for the selected operand.
-        *            The pointer returned is never NULL.
-        */
-       const arch_register_req_t *(*get_irn_reg_req_in)(const ir_node *irn,
-                                                        int pos);
-
        /**
         * Classify the node.
         * @param irn The node.
@@ -470,96 +458,6 @@ struct arch_irn_ops_t {
                                       unsigned int i);
 };
 
-/**
- * The code generator interface.
- */
-struct arch_code_generator_if_t {
-       /**
-        * Initialize the code generator.
-        * @param irg  A graph
-        * @return     A newly created code generator.
-        */
-       void *(*init)(ir_graph *irg);
-
-       /**
-        * return node used as base in pic code addresses
-        */
-       ir_node* (*get_pic_base)(void *self);
-
-       /**
-        * Called before abi introduce.
-        */
-       void (*before_abi)(void *self);
-
-       /**
-        * Called, when the graph is being normalized.
-        */
-       void (*prepare_graph)(void *self);
-
-       /**
-        * Backend may provide an own spiller.
-        * This spiller needs to spill all register classes.
-        */
-       void (*spill)(void *self, ir_graph *irg);
-
-       /**
-        * Called before register allocation.
-        */
-       void (*before_ra)(void *self);
-
-       /**
-        * Called after register allocation.
-        */
-       void (*after_ra)(void *self);
-
-       /**
-        * Called directly before done is called. This should be the last place
-        * where the irg is modified.
-        */
-       void (*finish)(void *self);
-
-       /**
-        * Called after everything happened. This call should emit the final
-        * assembly code but avoid changing the irg.
-        * The code generator must also be de-allocated here.
-        */
-       void (*done)(void *self);
-};
-
-/**
- * helper macro: call function func from the code generator
- * if it's implemented.
- */
-#define _arch_cg_call(cg, func) \
-do { \
-       if((cg)->impl->func) \
-               (cg)->impl->func(cg); \
-} while(0)
-
-#define _arch_cg_call_env(cg, env, func) \
-do { \
-       if((cg)->impl->func) \
-               (cg)->impl->func(cg, env); \
-} while(0)
-
-#define arch_code_generator_before_abi(cg)      _arch_cg_call(cg, before_abi)
-#define arch_code_generator_prepare_graph(cg)   _arch_cg_call(cg, prepare_graph)
-#define arch_code_generator_before_ra(cg)       _arch_cg_call(cg, before_ra)
-#define arch_code_generator_after_ra(cg)        _arch_cg_call(cg, after_ra)
-#define arch_code_generator_finish(cg)          _arch_cg_call(cg, finish)
-#define arch_code_generator_done(cg)            _arch_cg_call(cg, done)
-#define arch_code_generator_spill(cg, irg)      _arch_cg_call_env(cg, irg, spill)
-#define arch_code_generator_has_spiller(cg)     ((cg)->impl->spill != NULL)
-#define arch_code_generator_get_pic_base(cg)    \
-       ((cg)->impl->get_pic_base != NULL ? (cg)->impl->get_pic_base(cg) : NULL)
-
-/**
- * Code generator base class.
- */
-struct arch_code_generator_t {
-       const arch_code_generator_if_t *impl;
-};
-
 /**
  * Architecture interface.
  */
@@ -613,31 +511,6 @@ struct arch_isa_if_t {
        void (*get_call_abi)(const void *self, ir_type *call_type,
                             be_abi_call_t *abi);
 
-       /**
-        * Get the code generator interface.
-        * @param self The this pointer.
-        * @return     Some code generator interface.
-        */
-       const arch_code_generator_if_t *(*get_code_generator_if)(void *self);
-
-       /**
-        * Get the list scheduler to use. There is already a selector given, the
-        * backend is free to modify and/or ignore it.
-        *
-        * @param self     The isa object.
-        * @param selector The selector given by options.
-        * @return         The list scheduler selector.
-        */
-       const list_sched_selector_t *(*get_list_sched_selector)(const void *self,
-                       list_sched_selector_t *selector);
-
-       /**
-        * Get the ILP scheduler to use.
-        * @param self  The isa object.
-        * @return      The ILP scheduler selector
-        */
-       const ilp_sched_selector_t *(*get_ilp_sched_selector)(const void *self);
-
        /**
         * Get the necessary alignment for storing a register of given class.
         * @param self  The isa object.
@@ -652,30 +525,6 @@ struct arch_isa_if_t {
         */
        const backend_params *(*get_params)(void);
 
-       /**
-        * Returns an 2-dim array of execution units, @p irn can be executed on.
-        * The first dimension is the type, the second the allowed units of this
-        * type.
-        * Each dimension is a NULL terminated list.
-        * @param self  The isa object.
-        * @param irn   The node.
-        * @return An array of allowed execution units.
-        *         exec_unit = {
-        *                       { unit1_of_tp1, ..., unitX1_of_tp1, NULL },
-        *                       ...,
-        *                       { unit1_of_tpY, ..., unitXn_of_tpY, NULL },
-        *                       NULL
-        *                     };
-        */
-       const be_execution_unit_t ***(*get_allowed_execution_units)(
-                       const ir_node *irn);
-
-       /**
-        * Return the abstract machine for this isa.
-        * @param self  The isa object.
-        */
-       const be_machine_t *(*get_machine)(const void *self);
-
        /**
         * Return an ordered list of irgs where code should be generated for.
         * If NULL is returned, all irg will be taken into account and they will be
@@ -705,6 +554,51 @@ struct arch_isa_if_t {
         * backend
         */
        int (*is_valid_clobber)(const char *clobber);
+
+       /**
+        * Initialize the code generator.
+        * @param irg  A graph
+        * @return     A newly created code generator.
+        */
+       void (*init_graph)(ir_graph *irg);
+
+       /**
+        * return node used as base in pic code addresses
+        */
+       ir_node* (*get_pic_base)(ir_graph *irg);
+
+       /**
+        * Called before abi introduce.
+        */
+       void (*before_abi)(ir_graph *irg);
+
+       /**
+        * Called, when the graph is being normalized.
+        */
+       void (*prepare_graph)(ir_graph *irg);
+
+       /**
+        * Called before register allocation.
+        */
+       void (*before_ra)(ir_graph *irg);
+
+       /**
+        * Called after register allocation.
+        */
+       void (*after_ra)(ir_graph *irg);
+
+       /**
+        * Called directly before done is called. This should be the last place
+        * where the irg is modified.
+        */
+       void (*finish)(ir_graph *irg);
+
+       /**
+        * Called after everything happened. This call should emit the final
+        * assembly code but avoid changing the irg.
+        * The code generator must also be de-allocated here.
+        */
+       void (*emit)(ir_graph *irg);
 };
 
 #define arch_env_done(env)                             ((env)->impl->done(env))
@@ -714,9 +608,6 @@ struct arch_isa_if_t {
 #define arch_env_get_reg_class(env,i)                  ((env)->impl->get_reg_class(i))
 #define arch_env_get_reg_class_for_mode(env,mode)      ((env)->impl->get_reg_class_for_mode((mode)))
 #define arch_env_get_call_abi(env,tp,abi)              ((env)->impl->get_call_abi((env), (tp), (abi)))
-#define arch_env_get_code_generator_if(env)            ((env)->impl->get_code_generator_if((env)))
-#define arch_env_get_list_sched_selector(env,selector) ((env)->impl->get_list_sched_selector((env), (selector)))
-#define arch_env_get_ilp_sched_selector(env)           ((env)->impl->get_ilp_sched_selector(env))
 #define arch_env_get_reg_class_alignment(env,cls)      ((env)->impl->get_reg_class_alignment((cls)))
 #define arch_env_get_params(env)                       ((env)->impl->get_params())
 #define arch_env_get_allowed_execution_units(env,irn)  ((env)->impl->get_allowed_execution_units((irn)))
@@ -808,8 +699,10 @@ static inline bool arch_irn_consider_in_reg_alloc(
 static inline const arch_register_req_t *arch_get_in_register_req(
                const ir_node *node, int pos)
 {
-       const arch_irn_ops_t *ops = get_irn_ops_simple(node);
-       return ops->get_irn_reg_req_in(node, 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];
 }
 
 /**
@@ -832,4 +725,52 @@ static inline void arch_set_out_register_req(ir_node *node, int pos,
        info->out_infos[pos].req = req;
 }
 
+static inline void arch_set_in_register_reqs(ir_node *node,
+                                            const arch_register_req_t **in_reqs)
+{
+       backend_info_t *info = be_get_info(node);
+       info->in_reqs = in_reqs;
+}
+
+static inline const arch_register_req_t **arch_get_in_register_reqs(
+               const ir_node *node)
+{
+       backend_info_t *info = be_get_info(node);
+       return info->in_reqs;
+}
+
+/**
+ * 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_register_req_out(value);                      \
+                       if (req_->cls != cls)                                          \
+                               continue;                                                  \
+                       code                                                           \
+               }                                                                  \
+       } else {                                                               \
+               const arch_register_req_t *req_ = arch_get_register_req_out(node); \
+               value = node;                                                      \
+               if (req_->cls == cls) {                                            \
+                       code                                                           \
+               }                                                                  \
+       }                                                                      \
+       } while (0)
+
+#define be_foreach_definition(node, cls, value, code)                      \
+       be_foreach_definition_(node, cls, value,                               \
+               if (req_->type & arch_register_req_type_ignore)                    \
+                       continue;                                                      \
+               code                                                               \
+       )
+
 #endif