X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbearch.h;h=0ab8097d1ee4b6307f07e5944decb173ef44f6f2;hb=f804d333c7b5459c3c1a6bfc188ecdc54346be73;hp=c1501e14bb1eda37eb4db4b7469458f182b703a1;hpb=bdf3df765e0e63a604e9ec8b91f997c8c98b2959;p=libfirm diff --git a/ir/be/bearch.h b/ir/be/bearch.h index c1501e14b..0ab8097d1 100644 --- a/ir/be/bearch.h +++ b/ir/be/bearch.h @@ -1,7 +1,10 @@ #ifndef _FIRM_BEARCH_H #define _FIRM_BEARCH_H -#include "firm_config.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef WITH_LIBCORE #include @@ -21,11 +24,10 @@ typedef struct _arch_register_class_t arch_register_class_t; typedef struct _arch_register_t arch_register_t; -typedef struct _arch_enum_t arch_enum_t; -typedef struct _arch_enum_member_t arch_enum_member_t; typedef struct _arch_isa_if_t arch_isa_if_t; typedef struct _arch_isa_t arch_isa_t; typedef struct _arch_env_t arch_env_t; +typedef struct _arch_irn_ops_if_t arch_irn_ops_if_t; typedef struct _arch_irn_ops_t arch_irn_ops_t; typedef struct _arch_irn_handler_t arch_irn_handler_t; typedef struct _arch_code_generator_t arch_code_generator_t; @@ -35,7 +37,6 @@ struct _be_node_factory_t; typedef enum _arch_register_type_t { arch_register_type_none = 0, - arch_register_type_write_invariant, arch_register_type_caller_saved, /**< The register must be saved by the caller upon a function call. It thus can be overwritten in the called function. */ @@ -44,6 +45,15 @@ typedef enum _arch_register_type_t { arch_register_type_ignore /**< Do not consider this register when allocating. */ } arch_register_type_t; +/** + * Convenience macro to check for register type. + * @param req A pointer to register. + * @param kind The kind of type to check for (see arch_register_type_t). + * @return 1, If register is of given kind, 0 if not. + */ +#define arch_register_type_is(reg, kind) \ + ((reg)->type == arch_register_type_ ## kind) + /** * A register. */ @@ -100,40 +110,6 @@ _arch_register_for_index(const arch_register_class_t *cls, int idx) #define arch_register_for_index(cls, idx) \ _arch_register_for_index(cls, idx) -/** - * Get the register set for a register class. - * @param cls The register class. - * @return The set containing all registers in the class. - */ -#define arch_get_register_set_for_class(cls) ((cls)->set) - -/** - * An immediate. - */ -struct _arch_immediate_t { - const char *name; /**< The name of the immediate. */ - ir_mode *mode; /**< The mode of the immediate. */ -}; - -/** - * The member of an enum. - */ -struct _arch_enum_member_t { - arch_enum_t *enm; /**< The enum, this member belongs to. */ -}; - -/** - * An enumeration operand type. - * - * Enumeration operand types can be used to describe the variants - * of an instruction, like giving the cases for a compare (gt, lt, - * eq, ...) some other special attributes of an instruction. - */ -struct _arch_enum_t { - int n_members; /**< The number of members in this enum. */ - arch_enum_member_t *members[1]; /**< The array of members. */ -}; - typedef enum _arch_operand_type_t { arch_operand_type_invalid, arch_operand_type_memory, @@ -163,17 +139,23 @@ typedef enum _arch_register_req_type_t { } arch_register_req_type_t; -#define arch_register_req_is_constr(x) \ - ((x)->type & (arch_register_req_type_pair + arch_register_req_type_limited - 1) != 0) +/** + * Convenience macro to check for set constraints. + * @param req A pointer to register requirements. + * @param kind The kind of constraint to check for (see arch_register_req_type_t). + * @return 1, If the kind of constraint is present, 0 if not. + */ +#define arch_register_req_is(req, kind) \ + (((req)->type & (arch_register_req_type_ ## kind)) != 0) /** * Expresses requirements to register allocation for an operand. */ typedef struct _arch_register_req_t { arch_register_req_type_t type; /**< The type of the constraint. */ - const arch_register_class_t *cls; /**< The register class this - constraint belongs to. */ - int (*limited)(const ir_node *irn, int pos, bitset_t *bs); + const arch_register_class_t *cls; /**< The register class this constraint belongs to. */ + + void (*limited)(void *limited_env, bitset_t *bs); /**< In case of the 'limited' constraint, this function must put all allowable @@ -181,15 +163,16 @@ typedef struct _arch_register_req_t { return the number of registers in the bitset. */ - int pos; /**< In case of the equal constraint, - this gives the position of the - operand to which the register of - this should be equal to. Same for - unequal. */ + void *limited_env; /**< This is passed to limited. */ + + ir_node *other; /**< In case of "should be equal" + or should be different, this gives + the node to whose register this + one's should be the same/different. */ } arch_register_req_t; /** - * Certain node classes which are relevent for the register allocator. + * Certain node classes which are relevant for the register allocator. */ typedef enum _arch_irn_class_t { arch_irn_class_normal, @@ -197,18 +180,20 @@ typedef enum _arch_irn_class_t { arch_irn_class_reload, arch_irn_class_copy, arch_irn_class_perm, - arch_irn_class_branch + arch_irn_class_branch, + arch_irn_class_call } arch_irn_class_t; /** * Some flags describing a node in more detail. */ typedef enum _arch_irn_flags_t { - arch_irn_flags_spillable = 1, - arch_irn_flags_rematerializable = 2 + arch_irn_flags_dont_spill = 1, /**< This must not be spilled. */ + arch_irn_flags_rematerializable = 2, /**< This should be replicated instead of spilled/reloaded. */ + arch_irn_flags_ignore = 4, /**< Do not consider the node during register allocation. */ } arch_irn_flags_t; -struct _arch_irn_ops_t { +struct _arch_irn_ops_if_t { /** * Get the register requirements for a given operand. @@ -220,7 +205,7 @@ struct _arch_irn_ops_t { * @return The register requirements for the selected operand. * The pointer returned is never NULL. */ - const arch_register_req_t *(*get_irn_reg_req)(const arch_irn_ops_t *self, + const arch_register_req_t *(*get_irn_reg_req)(const void *self, arch_register_req_t *req, const ir_node *irn, int pos); /** @@ -230,7 +215,7 @@ struct _arch_irn_ops_t { * @note If the operand is not a register operand, * the call is ignored. */ - void (*set_irn_reg)(const arch_irn_ops_t *self, ir_node *irn, const arch_register_t *reg); + void (*set_irn_reg)(const void *self, ir_node *irn, const arch_register_t *reg); /** * Get the register allocated for an output operand. @@ -240,14 +225,14 @@ struct _arch_irn_ops_t { * @c arch_register_invalid, if no register has yet been * allocated for this node. */ - const arch_register_t *(*get_irn_reg)(const arch_irn_ops_t *self, const ir_node *irn); + const arch_register_t *(*get_irn_reg)(const void *self, const ir_node *irn); /** * Classify the node. * @param irn The node. * @return A classification. */ - arch_irn_class_t (*classify)(const arch_irn_ops_t *self, const ir_node *irn); + arch_irn_class_t (*classify)(const void *self, const ir_node *irn); /** * Get the flags of a node. @@ -255,10 +240,17 @@ struct _arch_irn_ops_t { * @param irn The node. * @return A set of flags. */ - arch_irn_flags_t (*get_flags)(const arch_irn_ops_t *self, const ir_node *irn); + arch_irn_flags_t (*get_flags)(const void *self, const ir_node *irn); }; +/** + * irn_ops base class. + */ +struct _arch_irn_ops_t { + const arch_irn_ops_if_t *impl; +}; + /** * Get the register requirements for a node. * @param env The architecture environment. @@ -291,15 +283,13 @@ extern int arch_is_register_operand(const arch_env_t *env, * @param env The environment. * @param irn The node. * @param pos The postition of the node's operand. - * @param cls The register class. * @param bs The bitset all allocatable registers shall be put into. * Note, that you can also pass NULL here. If you don't, * make sure, the bitset is as large as the register class * has registers. * @return The amount of registers allocatable for that operand. */ -extern int arch_get_allocatable_regs(const arch_env_t *env, const ir_node *irn, - int pos, const arch_register_class_t *cls, bitset_t *bs); +extern int arch_get_allocatable_regs(const arch_env_t *env, const ir_node *irn, int pos, bitset_t *bs); /** * Check, if a register is assignable to an operand of a node. @@ -358,9 +348,15 @@ extern arch_irn_class_t arch_irn_classify(const arch_env_t *env, const ir_node * */ extern arch_irn_flags_t arch_irn_get_flags(const arch_env_t *env, const ir_node *irn); +#define arch_irn_is_ignore(env, irn) 0 + // ((arch_irn_get_flags(env, irn) & arch_irn_flags_ignore) != 0) + #define arch_irn_has_reg_class(env, irn, pos, cls) \ ((cls) == arch_get_irn_reg_class(env, irn, pos)) +#define arch_irn_consider_in_reg_alloc(env, cls, irn) \ + (arch_irn_has_reg_class(env, irn, -1, cls) && !arch_irn_is_ignore(env, irn)) + /** * Somebody who can be asked about nodes. */ @@ -372,7 +368,7 @@ struct _arch_irn_handler_t { * @param irn Some node. * @return Operations for that irn. */ - const arch_irn_ops_t *(*get_irn_ops)(const arch_irn_handler_t *handler, + const void *(*get_irn_ops)(const arch_irn_handler_t *handler, const ir_node *irn); }; @@ -407,6 +403,30 @@ struct _arch_code_generator_if_t { */ void (*before_ra)(void *self); + /** + * Called after register allocation to lower Spills to Stores + * @param self The code generator + * @param spill The spill node to lower + * @return The new backend node which substitutes the spill + */ + ir_node *(*lower_spill)(void *self, ir_node *spill); + + /** + * Called after register allocation to lower Reloads to Loads + * @param self The code generator + * @param reload The reload node to lower + * @return The new backend node which substitutes the reload + */ + ir_node *(*lower_reload)(void *self, ir_node *reload); + + /** + * Called in lowering (e.g. alloca lowering) to set the + * correct stack register. + * @param self The code generator + * @return The stack register for the current irg + */ + const arch_register_t *(*get_stack_register)(void *self); + /** * Called after everything happened. * The code generator must also be de-allocated here. @@ -485,7 +505,7 @@ struct _arch_isa_if_t { * @param self The this pointer. * @return Some code generator interface. */ - const arch_code_generator_if_t *(*get_code_generator)(void *self); + const arch_code_generator_if_t *(*get_code_generator_if)(void *self); /** * Get the list scheduler to use. @@ -493,6 +513,15 @@ struct _arch_isa_if_t { * @return The list scheduler selector. */ const list_sched_selector_t *(*get_list_sched_selector)(const void *self); + + /** + * Take a proj from a call, set the correct register and projnum for this proj + * @param self The isa object. + * @param proj The proj + * @param is_keep Non-zero if proj is a Keep argument + * @return The backend proj number assigned to this proj + */ + long (*handle_call_proj)(const void *self, ir_node *proj, int is_keep); }; #define arch_isa_get_n_reg_class(isa) ((isa)->impl->get_n_reg_class(isa))