cleanup backend: make pre_spill_prepare_constraint independent of chordal allocator...
[libfirm] / ir / be / bearch_t.h
index 1e7c93b..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)
@@ -413,7 +379,6 @@ 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
         */
        arch_env_t *(*init)(FILE *file_handle);
@@ -423,6 +388,12 @@ struct arch_isa_if_t {
         */
        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.
@@ -522,9 +493,29 @@ 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_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)))
@@ -537,23 +528,45 @@ struct arch_isa_if_t {
 #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)
 
 /**
  * ISA base class.
  */
 struct arch_env_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 */
+       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 */
 };
 
-#define arch_env_stack_dir(env)  ((env)->stack_dir)
-#define arch_env_sp(env)         ((env)->sp)
-#define arch_env_bp(env)         ((env)->bp)
+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