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 @@
* that it is still considered 'small'.
* @param min_large_size The minimum number of bytes for a CopyB node so
* 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,
unsigned min_large_size);
unsigned min_large_size, int allow_misalignments);
/**
* Lowers all Switches (Cond nodes with non-boolean mode) depending on spare_size.
......
......@@ -481,7 +481,7 @@ static void amd64_lower_for_target(void)
* CopyBs into memcpy calls, because we cannot handle CopyB nodes
* during code generation yet.
* 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)
/* Turn all small CopyBs into loads/stores and all bigger CopyBs into
* memcpy calls.
* 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)
/* Turn all small CopyBs into loads/stores, keep medium-sized CopyBs,
* so we can generate rep movs later, and turn all big CopyBs into
* memcpy calls. */
lower_CopyB(irg, 64, 8193);
lower_CopyB(irg, 64, 8193, true);
}
}
......
......@@ -444,7 +444,7 @@ static void sparc_lower_for_target(void)
ir_graph *irg = get_irp_irg(i);
/* Turn all small CopyBs into loads/stores and all bigger CopyBs into
* 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
static unsigned min_large_size; /**< The minimum size of a CopyB node
so that it is regarded as 'large'. */
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 {
struct obstack obst; /**< the obstack where data is allocated
......@@ -112,27 +114,17 @@ static ir_mode *get_ir_mode(unsigned mode_bytes)
static void lower_small_copyb_node(ir_node *irn)
{
ir_graph *irg = get_irn_irg(irn);
unsigned mode_bytes = native_mode_bytes;
unsigned size;
unsigned offset;
ir_node *block = get_nodes_block(irn);
ir_type *tp = get_CopyB_type(irn);
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 *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) {
mode = get_ir_mode(mode_bytes);
for (; offset + mode_bytes <= size; offset += mode_bytes) {
......@@ -280,7 +272,8 @@ static void find_copyb_nodes(ir_node *irn, void *ctx)
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();
walk_env_t env;
......@@ -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");
max_small_size = max_small_sz;
min_large_size = min_large_sz;
native_mode_bytes = bparams->machine_size / 8;
max_small_size = max_small_sz;
min_large_size = min_large_sz;
native_mode_bytes = bparams->machine_size / 8;
allow_misalignments = allow_misaligns;
obstack_init(&env.obst);
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