diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2024-04-20 12:26:52 +0200 |
---|---|---|
committer | Marc Poulhiès <poulhies@adacore.com> | 2024-06-21 10:34:22 +0200 |
commit | 9aa8324e8a2c992593591d965b3e2d527ed891d3 (patch) | |
tree | 9a372d6c8200ea62ae235defdfec84e3f327ea2e /gcc/ada/gcc-interface | |
parent | 4e128544abc14871388ca194e61d6c482d3a11a6 (diff) | |
download | gcc-9aa8324e8a2c992593591d965b3e2d527ed891d3.zip gcc-9aa8324e8a2c992593591d965b3e2d527ed891d3.tar.gz gcc-9aa8324e8a2c992593591d965b3e2d527ed891d3.tar.bz2 |
ada: Implement fast modulo reduction for nonbinary modular multiplication
This adds the missing guard to prevent the reduction from being used when
the target does not provide or cannot synthesize a high-part multiply.
gcc/ada/
* gcc-interface/trans.cc (gnat_to_gnu) <N_Op_Mod>: Fix formatting.
* gcc-interface/utils2.cc: Include optabs-query.h.
(fast_modulo_reduction): Call can_mult_highpart_p on the TYPE_MODE
before generating a high-part multiply. Fix formatting.
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r-- | gcc/ada/gcc-interface/trans.cc | 2 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils2.cc | 12 |
2 files changed, 8 insertions, 6 deletions
diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc index 7c52826..83ed17b 100644 --- a/gcc/ada/gcc-interface/trans.cc +++ b/gcc/ada/gcc-interface/trans.cc @@ -7323,7 +7323,7 @@ gnat_to_gnu (Node_Id gnat_node) pair in the needed precision up to the word size. But not when optimizing for size, because it will be longer than a div+mul+sub sequence. */ - else if (!optimize_size + else if (!optimize_size && (code == FLOOR_MOD_EXPR || code == TRUNC_MOD_EXPR) && TYPE_UNSIGNED (gnu_type) && TYPE_PRECISION (gnu_type) <= BITS_PER_WORD diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc index a37eccc..d101d77 100644 --- a/gcc/ada/gcc-interface/utils2.cc +++ b/gcc/ada/gcc-interface/utils2.cc @@ -35,6 +35,7 @@ #include "builtins.h" #include "expmed.h" #include "fold-const.h" +#include "optabs-query.h" #include "stor-layout.h" #include "stringpool.h" #include "varasm.h" @@ -558,11 +559,11 @@ fast_modulo_reduction (tree op, tree modulus, unsigned int precision) op / d = (op * multiplier) >> shifter - But choose_multiplier provides a slightly different interface: + But choose_multiplier provides a slightly different interface: - op / d = (op h* multiplier) >> reduced_shifter + op / d = (op h* multiplier) >> reduced_shifter - that makes things easier by using a high-part multiplication. */ + that makes things easier by using a high-part multiplication. */ mh = choose_multiplier (d, type_precision, precision, &ml, &post_shift); /* If the suggested multiplier is more than TYPE_PRECISION bits, we can @@ -577,8 +578,9 @@ fast_modulo_reduction (tree op, tree modulus, unsigned int precision) pre_shift = 0; /* If the suggested multiplier is still more than TYPE_PRECISION bits, - try again with a larger type up to the word size. */ - if (mh != 0) + or the TYPE_MODE does not have a high-part multiply, try again with + a larger type up to the word size. */ + if (mh != 0 || !can_mult_highpart_p (TYPE_MODE (type), true)) { if (type_precision < BITS_PER_WORD) { |