bearch: Add and use be_foreach_value().
[libfirm] / ir / be / bearch.h
index c030d94..9d48a27 100644 (file)
@@ -92,14 +92,6 @@ ENUM_BITSET(arch_register_req_type_t)
 extern arch_register_req_t const arch_no_requirement;
 #define arch_no_register_req (&arch_no_requirement)
 
-/**
- * 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);
-
 void arch_dump_register_reqs(FILE *F, const ir_node *node);
 void arch_dump_reqs_and_registers(FILE *F, const ir_node *node);
 
@@ -202,11 +194,7 @@ static inline const arch_register_req_t *arch_get_irn_register_req(const ir_node
  */
 static inline arch_irn_flags_t arch_get_irn_flags(const ir_node *node)
 {
-       backend_info_t *info;
-       if (is_Proj(node))
-               return arch_irn_flags_not_scheduled;
-
-       info = be_get_info(node);
+       backend_info_t const *const info = be_get_info(node);
        return info->flags;
 }
 
@@ -217,13 +205,13 @@ 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);
 }
 
+#define be_foreach_out(node, i) \
+       for (unsigned i = 0, i##__n = arch_get_irn_n_outs(node); i != i##__n; ++i)
+
 /**
  * Start codegeneration
  */
@@ -570,50 +558,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, ccls, value, code)                    \
-       do {                                                                   \
-       if (get_irn_mode(node) == mode_T) {                                    \
-               foreach_out_edge(node, edge_) {                                    \
-                       ir_node                   *const value = get_edge_src_irn(edge_); \
-                       arch_register_req_t const *const req_  = arch_get_irn_register_req(value); \
-                       if (req_->cls != ccls)                                         \
-                               continue;                                                  \
-                       code                                                           \
-               }                                                                  \
-       } else {                                                               \
-               arch_register_req_t const *const req_  = arch_get_irn_register_req(node); \
-               ir_node                   *const value = node; \
-               if (req_->cls == ccls) {                                           \
-                       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, ccls, value, code)                     \
-       be_foreach_definition_(node, ccls, 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)
 {