summaryrefslogtreecommitdiffhomepage
path: root/ir/be/bepeephole.c
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2014-09-09 17:46:13 +0200
committerMatthias Braun <matze@braunis.de>2014-09-09 17:52:48 +0200
commit7412848afb2d6cb453cb9e015566dafc2bf155d4 (patch)
tree34f291d1e8f6fb5871c7276560e3d96a7e50b740 /ir/be/bepeephole.c
parentadccf2fbca3a3c1f4d3fbe56df06c8546cd3be03 (diff)
bepeephole: check assigned entities in be_can_move_down()
This fixes a subtle bug where the delay slot filler would move a spill/reload across a MemPerm although they both share a spillslot.
Diffstat (limited to 'ir/be/bepeephole.c')
-rw-r--r--ir/be/bepeephole.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/ir/be/bepeephole.c b/ir/be/bepeephole.c
index c230be7..295942c 100644
--- a/ir/be/bepeephole.c
+++ b/ir/be/bepeephole.c
@@ -214,6 +214,8 @@ bool be_can_move_down(ir_heights_t *heights, const ir_node *node,
assert(get_nodes_block(node) == get_nodes_block(before));
assert(sched_get_time_step(node) < sched_get_time_step(before));
+ const ir_entity *const entity = arch_get_frame_entity(node);
+
ir_node *schedpoint = sched_next(node);
while (schedpoint != before) {
/* schedpoint must not use our computed values */
@@ -237,6 +239,25 @@ bool be_can_move_down(ir_heights_t *heights, const ir_node *node,
}
}
+ /* schedpoint must not overwrite our entity... TODO: we lack a good
+ * API to query all entities involved with an isntruction, this is
+ * kinda preliminary but enough for the sparc backend. */
+ if (entity != NULL) {
+ const ir_entity *const schedpoint_entity
+ = arch_get_frame_entity(schedpoint);
+ if (schedpoint_entity == entity)
+ return false;
+ if (be_is_MemPerm(schedpoint)) {
+ int arity = be_get_MemPerm_entity_arity(schedpoint);
+ for (int i = 0; i < arity; ++i) {
+ if (be_get_MemPerm_out_entity(schedpoint, i) == entity)
+ return false;
+ if (be_get_MemPerm_in_entity(schedpoint, i) == entity)
+ return false;
+ }
+ }
+ }
+
schedpoint = sched_next(schedpoint);
}
return true;