};
typedef struct {
- arch_get_irn_ops_t *get_irn_ops;
arch_irn_ops_t irn_ops;
const arch_env_t *arch_env;
pmap *phi_attrs;
#include <string.h>
#include "bearch_t.h"
+#include "benode_t.h"
#include "ircons_t.h"
#include "irnode_t.h"
#include "xmalloc.h"
return env;
}
-arch_env_t *arch_env_push_irn_handler(arch_env_t *env,
- arch_get_irn_ops_t *handler)
+void arch_env_set_irn_handler(arch_env_t *env, arch_get_irn_ops_t *handler)
{
- assert(env->handlers_tos < ARCH_MAX_HANDLERS);
- env->handlers[env->handlers_tos++] = handler;
- return env;
-}
-
-arch_get_irn_ops_t *arch_env_pop_irn_handler(arch_env_t *env)
-{
- assert(env->handlers_tos > 0 && env->handlers_tos <= ARCH_MAX_HANDLERS);
- return env->handlers[--env->handlers_tos];
+ env->arch_handler = handler;
}
static const arch_irn_ops_t *fallback_irn_ops = NULL;
static INLINE const arch_irn_ops_t *
get_irn_ops(const arch_env_t *env, const ir_node *irn)
{
-#if 1
- int i;
-
- for(i = env->handlers_tos - 1; i >= 0; --i) {
- arch_get_irn_ops_t *get_irn_ops = env->handlers[i];
- const arch_irn_ops_t *ops = get_irn_ops(irn);
+ const arch_irn_ops_t *ops = be_node_get_irn_ops(irn);
- if(ops)
- return ops;
- }
-#else
- if (is_Phi(irn) && !mode_is_datab(get_irn_mode(irn))) {
- const phi_handler_t *h;
- return &h->irn_ops;
- }
- if (is_Proj(irn)) {
- irn = get_Proj_pred(irn);
- if (is_Proj(irn)) {
- assert(get_irn_mode(irn) == mode_T);
- irn = get_Proj_pred(irn);
- }
- }
- if (is_be_node(irn))
- return &be_node_irn_ops;
+ if (ops)
+ return ops;
+ ops = env->arch_handler(irn);
-#endif
- return fallback_irn_ops;
+ return ops != NULL ? ops : fallback_irn_ops;
}
const arch_irn_ops_t *arch_get_irn_ops(const arch_env_t *env, const ir_node *irn) {
FILE *file_handle, be_main_env_t *main_env);
/**
- * Add a node handler to the environment.
+ * Set the architectural node handler to the environment.
* @param env The environment.
- * @param handler A node handler.
+ * @param handler The node handler for the selected architecture.
* @return The environment itself.
*/
-extern arch_env_t *arch_env_push_irn_handler(arch_env_t *env, arch_get_irn_ops_t *handler);
-
-/**
- * Remove a node handler from the handler stack.
- * @param env The architecture environment.
- * @return The popped handler.
- */
-extern arch_get_irn_ops_t *arch_env_pop_irn_handler(arch_env_t *env);
+extern void arch_env_set_irn_handler(arch_env_t *env, arch_get_irn_ops_t *handler);
/**
* Register an instruction set architecture
#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_MAX_HANDLERS 8
-
/**
* Environment for the architecture infrastructure.
* Keep this everywhere you're going.
*/
struct arch_env_t {
- arch_isa_t *isa; /**< The isa about which everything is. */
-
- arch_get_irn_ops_t *handlers[ARCH_MAX_HANDLERS]; /**< The handlers are organized as
- a stack. */
+ arch_isa_t *isa; /**< The isa about which everything is. */
- int handlers_tos; /**< The stack pointer of the handler
- stack. */
+ arch_get_irn_ops_t *arch_handler; /**< The get_irn_ops handler for the selected architecture. */
};
/**
/* Register the irn handler of the architecture */
handler = arch_isa_get_irn_handler(env->arch_env.isa);
- if (handler != NULL)
- arch_env_push_irn_handler(&env->arch_env, handler);
+ arch_env_set_irn_handler(&env->arch_env, handler);
- /*
- * Register the node handler of the back end infrastructure.
- * This irn handler takes care of the platform independent
- * spill, reload and perm nodes.
- */
- arch_env_push_irn_handler(&env->arch_env, be_node_get_irn_ops);
be_phi_handler_new(env);
- arch_env_push_irn_handler(&env->arch_env, env->phi_handler.get_irn_ops);
be_dbg_open();
return env;
&be_node_irn_ops_if
};
+/* * irn handler for common be nodes and Phi's. */
const void *be_node_get_irn_ops(const ir_node *irn)
{
+ if (is_Phi(irn)) {
+ if (mode_is_datab(get_irn_mode(irn)))
+ return &curr_phi_handler->irn_ops;
+ return NULL;
+ }
+
if (is_Proj(irn)) {
irn = get_Proj_pred(irn);
if (is_Proj(irn)) {
arch_irn_flags_t flags;
} phi_attr_t;
-#define get_phi_handler_from_handler(h) container_of(h, phi_handler_t, irn_handler)
#define get_phi_handler_from_ops(h) container_of(h, phi_handler_t, irn_ops)
-static
-const void *phi_get_irn_ops(const ir_node *irn)
-{
- if (!is_Phi(irn) || !mode_is_datab(get_irn_mode(irn)))
- return NULL;
-
- return &curr_phi_handler->irn_ops;
-}
-
static INLINE
phi_attr_t *get_Phi_attr(const phi_handler_t *handler, const ir_node *phi)
{
void be_phi_handler_new(be_main_env_t *env)
{
phi_handler_t *h = &env->phi_handler;
- h->get_irn_ops = phi_get_irn_ops;
h->irn_ops.impl = &phi_irn_ops;
h->arch_env = &env->arch_env;
h->phi_attrs = pmap_create();
arch_irn_flags_t flags);
/**
- * irn handler for common be nodes.
+ * irn handler for common be nodes and Phi's.
*/
const void *be_node_get_irn_ops(const ir_node *irn);