summaryrefslogtreecommitdiffhomepage
path: root/ir/be/betranshlp.c
diff options
context:
space:
mode:
authorChristoph Mallon <mallon@cs.uni-saarland.de>2015-04-17 07:21:37 +0200
committerChristoph Mallon <mallon@cs.uni-saarland.de>2015-04-19 09:07:15 +0200
commitb772ac487d1c0d3692a74de1741b0d3a4a30e675 (patch)
tree9510cb88e27a3ed5216744ed5c1b71206674c304 /ir/be/betranshlp.c
parentbe10d1427a708d860b85f1abf03b3d1e8f530bad (diff)
be: Factorise code to skip down converions while transforming.
Diffstat (limited to 'ir/be/betranshlp.c')
-rw-r--r--ir/be/betranshlp.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/ir/be/betranshlp.c b/ir/be/betranshlp.c
index f41514d..6760c43 100644
--- a/ir/be/betranshlp.c
+++ b/ir/be/betranshlp.c
@@ -823,3 +823,30 @@ uint32_t be_get_tv_bits32(ir_tarval *const tv, unsigned const offset)
val |= (uint32_t)get_tarval_sub_bits(tv, offset + 3) << 24;
return val;
}
+
+static bool mode_needs_gp_reg(ir_mode *const mode)
+{
+ return get_mode_arithmetic(mode) == irma_twos_complement;
+}
+
+ir_node *be_skip_downconv(ir_node *node, bool const single_user)
+{
+ assert(mode_needs_gp_reg(get_irn_mode(node)));
+ for (;;) {
+ if (single_user && get_irn_n_edges(node) > 1) {
+ /* we only want to skip the conv when we're the only user
+ * (because this test is used in the context of address-mode selection
+ * and we don't want to use address mode for multiple users) */
+ break;
+ } else if (is_Conv(node)) {
+ ir_node *const op = get_Conv_op(node);
+ ir_mode *const src_mode = get_irn_mode(op);
+ if (!mode_needs_gp_reg(src_mode) || get_mode_size_bits(get_irn_mode(node)) > get_mode_size_bits(src_mode))
+ break;
+ node = op;
+ } else {
+ break;
+ }
+ }
+ return node;
+}