Commit 218f0c5c authored by Manuel Mohr's avatar Manuel Mohr
Browse files

Added option to prevent creation of misaligned loads/stores during CopyB lowering.

parent 7886f0c7
...@@ -48,9 +48,10 @@ ...@@ -48,9 +48,10 @@
* that it is still considered 'small'. * that it is still considered 'small'.
* @param min_large_size The minimum number of bytes for a CopyB node so * @param min_large_size The minimum number of bytes for a CopyB node so
* that it is regarded as 'large'. * that it is regarded as 'large'.
* @param allow_misalignments Backend can handle misaligned loads and stores.
*/ */
FIRM_API void lower_CopyB(ir_graph *irg, unsigned max_small_size, FIRM_API void lower_CopyB(ir_graph *irg, unsigned max_small_size,
unsigned min_large_size); unsigned min_large_size, int allow_misalignments);
/** /**
* Lowers all Switches (Cond nodes with non-boolean mode) depending on spare_size. * Lowers all Switches (Cond nodes with non-boolean mode) depending on spare_size.
......
...@@ -481,7 +481,7 @@ static void amd64_lower_for_target(void) ...@@ -481,7 +481,7 @@ static void amd64_lower_for_target(void)
* CopyBs into memcpy calls, because we cannot handle CopyB nodes * CopyBs into memcpy calls, because we cannot handle CopyB nodes
* during code generation yet. * during code generation yet.
* TODO: Adapt this once custom CopyB handling is implemented. */ * TODO: Adapt this once custom CopyB handling is implemented. */
lower_CopyB(irg, 64, 65); lower_CopyB(irg, 64, 65, true);
} }
} }
......
...@@ -548,7 +548,7 @@ static void arm_lower_for_target(void) ...@@ -548,7 +548,7 @@ static void arm_lower_for_target(void)
/* Turn all small CopyBs into loads/stores and all bigger CopyBs into /* Turn all small CopyBs into loads/stores and all bigger CopyBs into
* memcpy calls. * memcpy calls.
* TODO: These constants need arm-specific tuning. */ * TODO: These constants need arm-specific tuning. */
lower_CopyB(irg, 31, 32); lower_CopyB(irg, 31, 32, false);
} }
} }
......
...@@ -2070,7 +2070,7 @@ static void ia32_lower_for_target(void) ...@@ -2070,7 +2070,7 @@ static void ia32_lower_for_target(void)
/* Turn all small CopyBs into loads/stores, keep medium-sized CopyBs, /* Turn all small CopyBs into loads/stores, keep medium-sized CopyBs,
* so we can generate rep movs later, and turn all big CopyBs into * so we can generate rep movs later, and turn all big CopyBs into
* memcpy calls. */ * memcpy calls. */
lower_CopyB(irg, 64, 8193); lower_CopyB(irg, 64, 8193, true);
} }
} }
......
...@@ -444,7 +444,7 @@ static void sparc_lower_for_target(void) ...@@ -444,7 +444,7 @@ static void sparc_lower_for_target(void)
ir_graph *irg = get_irp_irg(i); ir_graph *irg = get_irp_irg(i);
/* Turn all small CopyBs into loads/stores and all bigger CopyBs into /* Turn all small CopyBs into loads/stores and all bigger CopyBs into
* memcpy calls. */ * memcpy calls. */
lower_CopyB(irg, 31, 32); lower_CopyB(irg, 31, 32, false);
} }
} }
......
...@@ -86,6 +86,8 @@ static unsigned max_small_size; /**< The maximum size of a CopyB node ...@@ -86,6 +86,8 @@ static unsigned max_small_size; /**< The maximum size of a CopyB node
static unsigned min_large_size; /**< The minimum size of a CopyB node static unsigned min_large_size; /**< The minimum size of a CopyB node
so that it is regarded as 'large'. */ so that it is regarded as 'large'. */
static unsigned native_mode_bytes; /**< The size of the native mode in bytes. */ static unsigned native_mode_bytes; /**< The size of the native mode in bytes. */
static int allow_misalignments; /**< Whether backend can handle misaligned
loads and stores. */
typedef struct walk_env { typedef struct walk_env {
struct obstack obst; /**< the obstack where data is allocated struct obstack obst; /**< the obstack where data is allocated
...@@ -112,27 +114,17 @@ static ir_mode *get_ir_mode(unsigned mode_bytes) ...@@ -112,27 +114,17 @@ static ir_mode *get_ir_mode(unsigned mode_bytes)
static void lower_small_copyb_node(ir_node *irn) static void lower_small_copyb_node(ir_node *irn)
{ {
ir_graph *irg = get_irn_irg(irn); ir_graph *irg = get_irn_irg(irn);
unsigned mode_bytes = native_mode_bytes; ir_node *block = get_nodes_block(irn);
unsigned size; ir_type *tp = get_CopyB_type(irn);
unsigned offset; ir_node *addr_src = get_CopyB_src(irn);
ir_node *addr_dst = get_CopyB_dst(irn);
ir_node *mem = get_CopyB_mem(irn);
ir_mode *addr_mode = get_irn_mode(addr_src);
unsigned mode_bytes = allow_misalignments ? native_mode_bytes : tp->align;
unsigned size = get_type_size_bytes(tp);
unsigned offset = 0;
ir_mode *mode; ir_mode *mode;
ir_mode *addr_mode;
ir_node *mem;
ir_node *addr_src;
ir_node *addr_dst;
ir_node *block;
ir_type *tp;
addr_src = get_CopyB_src(irn);
addr_dst = get_CopyB_dst(irn);
mem = get_CopyB_mem(irn);
addr_mode = get_irn_mode(addr_src);
block = get_nodes_block(irn);
tp = get_CopyB_type(irn);
size = get_type_size_bytes(tp);
offset = 0;
while (offset < size) { while (offset < size) {
mode = get_ir_mode(mode_bytes); mode = get_ir_mode(mode_bytes);
for (; offset + mode_bytes <= size; offset += mode_bytes) { for (; offset + mode_bytes <= size; offset += mode_bytes) {
...@@ -280,7 +272,8 @@ static void find_copyb_nodes(ir_node *irn, void *ctx) ...@@ -280,7 +272,8 @@ static void find_copyb_nodes(ir_node *irn, void *ctx)
list_add_tail(&entry->list, &env->list); list_add_tail(&entry->list, &env->list);
} }
void lower_CopyB(ir_graph *irg, unsigned max_small_sz, unsigned min_large_sz) void lower_CopyB(ir_graph *irg, unsigned max_small_sz, unsigned min_large_sz,
int allow_misaligns)
{ {
const backend_params *bparams = be_get_backend_param(); const backend_params *bparams = be_get_backend_param();
walk_env_t env; walk_env_t env;
...@@ -288,9 +281,10 @@ void lower_CopyB(ir_graph *irg, unsigned max_small_sz, unsigned min_large_sz) ...@@ -288,9 +281,10 @@ void lower_CopyB(ir_graph *irg, unsigned max_small_sz, unsigned min_large_sz)
assert(max_small_sz < min_large_sz && "CopyB size ranges must not overlap"); assert(max_small_sz < min_large_sz && "CopyB size ranges must not overlap");
max_small_size = max_small_sz; max_small_size = max_small_sz;
min_large_size = min_large_sz; min_large_size = min_large_sz;
native_mode_bytes = bparams->machine_size / 8; native_mode_bytes = bparams->machine_size / 8;
allow_misalignments = allow_misaligns;
obstack_init(&env.obst); obstack_init(&env.obst);
INIT_LIST_HEAD(&env.list); INIT_LIST_HEAD(&env.list);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment