cleanup backend: make pre_spill_prepare_constraint independent of chordal allocator...
[libfirm] / ir / be / bearch_t.h
index bbdd35c..e7c0320 100644 (file)
@@ -32,6 +32,7 @@
 #include "beilpsched.h"
 #include "bemachine.h"
 #include "beirg.h"
+#include "beinfo.h"
 #include "beabi.h"
 #include "raw_bitset.h"
 
@@ -43,22 +44,21 @@ struct arch_register_t {
        const arch_register_class_t *reg_class;   /**< The class the register belongs to. */
        unsigned                    index;        /**< The index of the register in the class. */
        arch_register_type_t        type;         /**< The type of the register. */
-       void                        *data;        /**< Custom data. */
 };
 
-static INLINE const arch_register_class_t *
+static inline const arch_register_class_t *
 _arch_register_get_class(const arch_register_t *reg)
 {
        return reg->reg_class;
 }
 
-static INLINE
+static inline
 unsigned _arch_register_get_index(const arch_register_t *reg)
 {
        return reg->index;
 }
 
-static INLINE
+static inline
 const char *_arch_register_get_name(const arch_register_t *reg)
 {
        return reg->name;
@@ -106,7 +106,7 @@ struct arch_register_class_t {
 /** return the register class flags */
 #define arch_register_class_flags(cls) ((cls)->flags)
 
-static INLINE const arch_register_t *
+static inline const arch_register_t *
 _arch_register_for_index(const arch_register_class_t *cls, unsigned idx)
 {
        assert(idx < cls->n_regs);
@@ -140,7 +140,7 @@ struct arch_register_req_t {
                                                 (must_be_different) */
 };
 
-static INLINE int reg_reqs_equal(const arch_register_req_t *req1,
+static inline int reg_reqs_equal(const arch_register_req_t *req1,
                                  const arch_register_req_t *req2)
 {
        if (req1 == req2)
@@ -185,32 +185,12 @@ struct arch_irn_ops_t {
         * Get the register requirements for a given operand.
         * @param self The self pointer.
         * @param irn The node.
-        * @param pos The operand's position
-        *        (-1 for the result of the node, 0..n for the input operands).
+        * @param pos The operand's position (0..n for the input operands).
         * @return    The register requirements for the selected operand.
         *            The pointer returned is never NULL.
         */
        const arch_register_req_t *(*get_irn_reg_req)(const ir_node *irn, int pos);
 
-       /**
-        * Set the register for an output operand.
-        * @param irn The node.
-        * @param reg The register allocated to that operand.
-        * @note      If the operand is not a register operand,
-        *            the call is ignored.
-        */
-       void (*set_irn_reg)(ir_node *irn, const arch_register_t *reg);
-
-       /**
-        * Get the register allocated for an output operand.
-        * @param irn The node.
-        * @return    The register allocated at that operand. NULL, if
-        *            the operand was no register operand or
-        *            @c arch_register_invalid, if no register has yet been
-        *            allocated for this node.
-        */
-       const arch_register_t *(*get_irn_reg)(const ir_node *irn);
-
        /**
         * Classify the node.
         * @param irn The node.
@@ -218,14 +198,6 @@ struct arch_irn_ops_t {
         */
        arch_irn_class_t (*classify)(const ir_node *irn);
 
-       /**
-        * Get the flags of a node.
-        * @param self The irn ops themselves.
-        * @param irn The node.
-        * @return A set of flags.
-        */
-       arch_irn_flags_t (*get_flags)(const ir_node *irn);
-
        /**
         * Get the entity on the stack frame this node depends on.
         * @param self The this pointer.
@@ -342,11 +314,6 @@ struct arch_code_generator_if_t {
         */
        void (*spill)(void *self, be_irg_t *birg);
 
-       /**
-        * Called before scheduling.
-        */
-       void (*before_sched)(void *self);
-
        /**
         * Called before register allocation.
         */
@@ -389,7 +356,6 @@ do { \
 
 #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_sched(cg)    _arch_cg_call(cg, before_sched)
 #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)
@@ -406,24 +372,6 @@ struct arch_code_generator_t {
        const arch_code_generator_if_t *impl;
 };
 
-/**
- * ISA base class.
- */
-struct arch_isa_t {
-       const arch_isa_if_t   *impl;
-       const arch_register_t *sp;        /** The stack pointer register. */
-       const arch_register_t *bp;        /** The base pointer register. */
-       int                    stack_dir; /** -1 for decreasing, 1 for increasing. */
-       int                    stack_alignment; /** 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 */
-};
-
-#define arch_isa_stack_dir(isa)  ((isa)->stack_dir)
-#define arch_isa_sp(isa)         ((isa)->sp)
-#define arch_isa_bp(isa)         ((isa)->bp)
-
 /**
  * Architecture interface.
  */
@@ -431,16 +379,21 @@ struct arch_isa_if_t {
        /**
         * Initialize the isa interface.
         * @param file_handle  the file handle to write the output to
-        * @param main_env     the be main environment
         * @return a new isa instance
         */
-       void *(*init)(FILE *file_handle);
+       arch_env_t *(*init)(FILE *file_handle);
 
        /**
         * Free the isa instance.
         */
        void (*done)(void *self);
 
+       /**
+        * Called directly after initialization. Backend should handle all
+        * intrinsics here.
+        */
+       void (*handle_intrinsics)(void);
+
        /**
         * Get the the number of register classes in the isa.
         * @return The number of register classes.
@@ -540,31 +493,80 @@ struct arch_isa_if_t {
         * @return A flexible array ARR_F containing all desired irgs in the desired order.
         */
        ir_graph **(*get_backend_irg_list)(const void *self, ir_graph ***irgs);
+
+       /**
+        * mark node as rematerialized
+        */
+       void (*mark_remat)(const void *self, ir_node *node);
+
+       /**
+        * parse an assembler constraint part and set flags according to its nature
+        * advances the *c pointer to point to the last parsed character (so if you
+        * parse a single character don't advance c)
+        */
+       asm_constraint_flags_t (*parse_asm_constraint)(const void *self, const char **c);
+
+       /**
+        * returns true if the string is a valid clobbered (register) in this
+        * backend
+        */
+       int (*is_valid_clobber)(const void *self, const char *clobber);
 };
 
-#define arch_isa_get_n_reg_class(isa)                  ((isa)->impl->get_n_reg_class(isa))
-#define arch_isa_get_reg_class(isa,i)                  ((isa)->impl->get_reg_class(isa, i))
-#define arch_isa_get_call_abi(isa,tp,abi)              ((isa)->impl->get_call_abi((isa), (tp), (abi)))
-#define arch_isa_get_reg_class_for_mode(isa,mode)      ((isa)->impl->get_reg_class_for_mode((isa), (mode)))
-#define arch_isa_make_code_generator(isa,irg)          ((isa)->impl->make_code_generator((isa), (irg)))
-#define arch_isa_get_reg_class_alignment(isa, cls)     ((isa)->impl->get_reg_class_alignment((isa), (cls)))
-#define arch_isa_get_allowed_execution_units(isa, irn) ((isa)->impl->get_allowed_execution_units((isa), (irn)))
-#define arch_isa_get_machine(isa)                      ((isa)->impl->get_machine((isa)))
-#define arch_isa_get_backend_irg_list(isa, irgs)       ((isa)->impl->get_backend_irg_list((isa), (irgs)))
+#define arch_env_done(env)                             ((env)->impl->done(env))
+#define arch_env_handle_intrinsics(env)                \
+       do { if((env)->impl->handle_intrinsics != NULL) (env)->impl->handle_intrinsics(); } while(0)
+#define arch_env_get_n_reg_class(env)                  ((env)->impl->get_n_reg_class(env))
+#define arch_env_get_reg_class(env,i)                  ((env)->impl->get_reg_class(env, i))
+#define arch_env_get_reg_class_for_mode(env,mode)      ((env)->impl->get_reg_class_for_mode((env), (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((env), (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((env), (irn)))
+#define arch_env_get_machine(env)                      ((env)->impl->get_machine(env))
+#define arch_env_get_backend_irg_list(env,irgs)        ((env)->impl->get_backend_irg_list((env), (irgs)))
+#define arch_env_parse_asm_constraint(env,c)           ((env)->impl->parse_asm_constraint((env), (c))
+#define arch_env_is_valid_clobber(env,clobber)         ((env)->impl->is_valid_clobber((env), (clobber))
+#define arch_env_mark_remat(env,node) \
+       do { if ((env)->impl->mark_remat != NULL) (env)->impl->mark_remat((env), (node)); } while(0)
 
 /**
- * Environment for the architecture infrastructure.
- * Keep this everywhere you're going.
+ * ISA base class.
  */
 struct arch_env_t {
-       arch_isa_t *isa;                  /**< The isa about which everything is. */
+       const arch_isa_if_t   *impl;
+       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_dir;        /** -1 for decreasing, 1 for increasing. */
+       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 */
 };
 
-/**
- * Get the isa of an arch environment.
- * @param env The environment.
- * @return The isa with which the env was initialized with.
- */
-#define arch_env_get_isa(env)   ((env)->isa)
+static inline unsigned arch_irn_get_n_outs(const ir_node *node)
+{
+       backend_info_t *info = be_get_info(node);
+       return ARR_LEN(info->out_infos);
+}
+
+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_register_req_out(node);
+       return
+               req->cls == cls &&
+               !(req->type & arch_register_req_type_ignore);
+}
+
+static inline bool arch_irn_is_ignore(const ir_node *irn)
+{
+       const arch_register_req_t *req = arch_get_register_req_out(irn);
+       return !!(req->type & arch_register_req_type_ignore);
+}
 
-#endif /* FIRM_BE_BEARCH_T_H */
+#endif