X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbearch.h;h=bf222581c7af0fff967fc05029b80bf862b9c499;hb=e0e9e9ace61d3ec46e4d09c7ab2c6947b17b2778;hp=8694dc5b3e6eba6b7899b91501f7163ccbc6c11e;hpb=f6750fd8b384d9795d13ab2985b4a4a631a31e7e;p=libfirm diff --git a/ir/be/bearch.h b/ir/be/bearch.h index 8694dc5b3..bf222581c 100644 --- a/ir/be/bearch.h +++ b/ir/be/bearch.h @@ -78,13 +78,15 @@ typedef enum arch_register_req_type_t { extern const arch_register_req_t *arch_no_register_req; /** - * Format a register requirements information into a string. - * @param buf The string where to put it to. - * @param len The size of @p buf. + * Print information about a register requirement in human readable form + * @param F output stream/file * @param req The requirements structure to format. - * @return A pointer to buf. */ -extern char *arch_register_req_format(char *buf, size_t len, const arch_register_req_t *req, const ir_node *node); +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); /** * Node classification. Mainly used for statistics. @@ -120,7 +122,6 @@ void arch_perform_memory_operand(ir_node *irn, ir_node *spill, unsign * operand was no register operand. */ const arch_register_req_t *arch_get_register_req(const ir_node *irn, int pos); -const arch_register_req_t *arch_get_register_req_out(const ir_node *irn); /** * Put all registers which shall not be ignored by the register @@ -217,8 +218,9 @@ void be_register_isa_if(const char *name, const arch_isa_if_t *isa); struct arch_register_t { const char *name; /**< The name of the register. */ 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. */ + unsigned index; /**< The index of the register in the class. */ + arch_register_type_t type; /**< The type of the register. */ + const arch_register_req_t *single_req; }; static inline const arch_register_class_t * @@ -239,9 +241,9 @@ const char *_arch_register_get_name(const arch_register_t *reg) return reg->name; } -#define arch_register_get_class(reg) _arch_register_get_class(reg) -#define arch_register_get_index(reg) _arch_register_get_index(reg) -#define arch_register_get_name(reg) _arch_register_get_name(reg) +#define arch_register_get_class(reg) _arch_register_get_class(reg) +#define arch_register_get_index(reg) _arch_register_get_index(reg) +#define arch_register_get_name(reg) _arch_register_get_name(reg) /** * Convenience macro to check for register type. @@ -257,13 +259,14 @@ const char *_arch_register_get_name(const arch_register_t *reg) * Like general purpose or floating point. */ struct arch_register_class_t { - unsigned index; /**< index of this register class */ - const char *name; /**< The name of the register class.*/ - unsigned n_regs; /**< Number of registers in this - class. */ - ir_mode *mode; /**< The mode of the register class.*/ - const arch_register_t *regs; /**< The array of registers. */ - arch_register_class_flags_t flags; /**< register class flags. */ + unsigned index; /**< index of this register class */ + const char *name; /**< The name of the register class.*/ + unsigned n_regs; /**< Number of registers in this + class. */ + ir_mode *mode; /**< The mode of the register class.*/ + const arch_register_t *regs; /**< The array of registers. */ + arch_register_class_flags_t flags; /**< register class flags. */ + const arch_register_req_t *class_req; }; /** return the number of registers in this register class */ @@ -365,16 +368,6 @@ struct arch_irn_ops_t { */ const arch_register_req_t *(*get_irn_reg_req_in)(const ir_node *irn, int pos); - /** - * Get the register requirements for values produced by a node - * @param irn The node. - * @param pos The operand's position (0 for most nodes, - * 0..n for mode_T nodes) - * @return The register requirements for the selected operand. - * The pointer returned is never NULL. - */ - const arch_register_req_t *(*get_irn_reg_req_out)(const ir_node *irn, int pos); - /** * Classify the node. * @param irn The node. @@ -574,14 +567,14 @@ struct arch_isa_if_t { * Get the the number of register classes in the isa. * @return The number of register classes. */ - unsigned (*get_n_reg_class)(const void *self); + unsigned (*get_n_reg_class)(void); /** * Get the i-th register class. * @param i The number of the register class. * @return The register class. */ - const arch_register_class_t *(*get_reg_class)(const void *self, unsigned i); + const arch_register_class_t *(*get_reg_class)(unsigned i); /** * Get the register class which shall be used to store a value of a given mode. @@ -589,7 +582,7 @@ struct arch_isa_if_t { * @param mode The mode in question. * @return A register class which can hold values of the given mode. */ - const arch_register_class_t *(*get_reg_class_for_mode)(const void *self, const ir_mode *mode); + const arch_register_class_t *(*get_reg_class_for_mode)(const ir_mode *mode); /** * Get the ABI restrictions for procedure calls. @@ -629,7 +622,7 @@ struct arch_isa_if_t { * @param cls The register class. * @return The alignment in bytes. */ - int (*get_reg_class_alignment)(const void *self, const arch_register_class_t *cls); + int (*get_reg_class_alignment)(const arch_register_class_t *cls); /** * A "static" function, returns the frontend settings @@ -652,7 +645,7 @@ struct arch_isa_if_t { * NULL * }; */ - const be_execution_unit_t ***(*get_allowed_execution_units)(const void *self, const ir_node *irn); + const be_execution_unit_t ***(*get_allowed_execution_units)(const ir_node *irn); /** * Return the abstract machine for this isa. @@ -673,41 +666,41 @@ struct arch_isa_if_t { /** * mark node as rematerialized */ - void (*mark_remat)(const void *self, ir_node *node); + void (*mark_remat)(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); + asm_constraint_flags_t (*parse_asm_constraint)(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); + int (*is_valid_clobber)(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))) +#define arch_env_get_n_reg_class(env) ((env)->impl->get_n_reg_class()) +#define arch_env_get_reg_class(env,i) ((env)->impl->get_reg_class(i)) +#define arch_env_get_reg_class_for_mode(env,mode) ((env)->impl->get_reg_class_for_mode((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_reg_class_alignment(env,cls) ((env)->impl->get_reg_class_alignment((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_allowed_execution_units(env,irn) ((env)->impl->get_allowed_execution_units((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_parse_asm_constraint(env,c) ((env)->impl->parse_asm_constraint((c)) +#define arch_env_is_valid_clobber(env,clobber) ((env)->impl->is_valid_clobber((clobber)) #define arch_env_mark_remat(env,node) \ - do { if ((env)->impl->mark_remat != NULL) (env)->impl->mark_remat((env), (node)); } while(0) + do { if ((env)->impl->mark_remat != NULL) (env)->impl->mark_remat((node)); } while(0) /** * ISA base class. @@ -727,16 +720,38 @@ struct arch_env_t { static inline unsigned arch_irn_get_n_outs(const ir_node *node) { backend_info_t *info = be_get_info(node); + if (info->out_infos == NULL) + return 0; + 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) +static inline const arch_irn_ops_t *get_irn_ops_simple(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); + const ir_op *ops = get_irn_op(node); + const arch_irn_ops_t *be_ops = get_op_ops(ops)->be_ops; + assert(!is_Proj(node)); + return be_ops; +} + +static inline const arch_register_req_t *arch_get_register_req_out( + const ir_node *irn) +{ + int pos = 0; + backend_info_t *info; + + if (is_Proj(irn)) { + pos = get_Proj_proj(irn); + irn = get_Proj_pred(irn); + } else if (get_irn_mode(irn) == mode_T) { + /* TODO: find out who does this and fix the caller! */ + return arch_no_register_req; + } + info = be_get_info(irn); + if (info->out_infos == NULL) + return arch_no_register_req; + + return info->out_infos[pos].req; } static inline bool arch_irn_is_ignore(const ir_node *irn) @@ -745,12 +760,13 @@ static inline bool arch_irn_is_ignore(const ir_node *irn) return !!(req->type & arch_register_req_type_ignore); } -static inline const arch_irn_ops_t *get_irn_ops_simple(const ir_node *node) +static inline bool arch_irn_consider_in_reg_alloc( + const arch_register_class_t *cls, const ir_node *node) { - const ir_op *ops = get_irn_op(node); - const arch_irn_ops_t *be_ops = get_op_ops(ops)->be_ops; - assert(!is_Proj(node)); - return be_ops; + const arch_register_req_t *req = arch_get_register_req_out(node); + return + req->cls == cls && + !(req->type & arch_register_req_type_ignore); } /** @@ -769,8 +785,18 @@ static inline const arch_register_req_t *arch_get_in_register_req( static inline const arch_register_req_t *arch_get_out_register_req( const ir_node *node, int pos) { - const arch_irn_ops_t *ops = get_irn_ops_simple(node); - return ops->get_irn_reg_req_out(node, pos); + const backend_info_t *info = be_get_info(node); + if (info->out_infos == NULL) + return arch_no_register_req; + return info->out_infos[pos].req; +} + +static inline void arch_set_out_register_req(ir_node *node, int pos, + const arch_register_req_t *req) +{ + backend_info_t *info = be_get_info(node); + assert(pos < (int) arch_irn_get_n_outs(node)); + info->out_infos[pos].req = req; } -#endif /* FIRM_BE_BEARCH_H */ +#endif