Skip to content

Commit

Permalink
Optimize bin32(a+b) & constBin32 if a and b are bigInteger
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasMertes committed Jan 12, 2024
1 parent 1229c34 commit 7940f0c
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 27 deletions.
34 changes: 21 additions & 13 deletions lib/comp/big_act.s7i
Original file line number Diff line number Diff line change
Expand Up @@ -1721,27 +1721,35 @@ const proc: process (BIG_ODD, in reference: function,
end func;


const proc: optimize_big_mod_dividend (in reference: dividend,
in bigInteger: divisor, inout expr_type: c_expr) is func

local
var addSubBigListType: addSubParamList is addSubBigListType.value;
begin
if evaluate_const_expr >= 2 then
generateAddSubParamList(addSubParamList, dividend);
evaluateConstants(addSubParamList);
c_expr.expr &:= "(";
optimizeAddSubList(addSubParamList, divisor, c_expr);
c_expr.expr &:= ")";
else
c_expr.expr &:= "bigLowerBits64(";
getAnyParamToExpr(dividend, c_expr);
c_expr.expr &:= ")";
end if;
end func;


const proc: optimize_big_ord_of_big_mod (in reference: param1,
in reference: dividend, in bigInteger: divisor,
inout expr_type: c_expr) is func

local
var addSubBigListType: addSubParamList is addSubBigListType.value;
begin
if divisor > 0_ and log2(divisor) <= 63_ and
2_ ** ord(log2(divisor)) = divisor then
c_expr.expr &:= "(intType)(";
if evaluate_const_expr >= 2 then
generateAddSubParamList(addSubParamList, dividend);
evaluateConstants(addSubParamList);
c_expr.expr &:= "(";
optimizeAddSubList(addSubParamList, divisor, c_expr);
c_expr.expr &:= ")";
else
c_expr.expr &:= "bigLowerBits64(";
getAnyParamToExpr(dividend, c_expr);
c_expr.expr &:= ")";
end if;
optimize_big_mod_dividend(dividend, divisor, c_expr);
c_expr.expr &:= "&";
c_expr.expr &:= integerLiteral(ord(pred(divisor)));
c_expr.expr &:= ")";
Expand Down
27 changes: 13 additions & 14 deletions lib/comp/bin_act.s7i
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,18 @@ const proc: process_const_bin_and (in reference: bits1, in integer: bits2,
elsif modDividendOptimization then
incr(countOptimizations);
c_expr.expr &:= "(";
optimize_mod_dividend(bits1, c_expr);
if isActionExpression(bits1, "BIN_BINARY") then
if bits2 > 0 and (bits2 = integer.last or
2 ** log2(succ(bits2)) = succ(bits2)) then
optimize_big_mod_dividend(getActionParameter(bits1, 1),
succ(bigInteger(bits2)), c_expr);
else
optimize_big_mod_dividend(getActionParameter(bits1, 1),
succ(bigInteger(bin64(-1))), c_expr);
end if;
else
optimize_mod_dividend(bits1, c_expr);
end if;
c_expr.expr &:= ")";
if bits2 <> ord(~bin64(0)) then
c_expr.expr &:= " & ";
Expand Down Expand Up @@ -139,22 +150,10 @@ const proc: optimize_bin_binary_of_big_mod (in reference: param1,
in reference: dividend, in bigInteger: divisor,
inout expr_type: c_expr) is func

local
var addSubBigListType: addSubParamList is addSubBigListType.value;
begin
if divisor > 0_ and log2(divisor) <= 64_ and
2_ ** ord(log2(divisor)) = divisor then
if evaluate_const_expr >= 2 then
generateAddSubParamList(addSubParamList, dividend);
evaluateConstants(addSubParamList);
c_expr.expr &:= "(";
optimizeAddSubList(addSubParamList, divisor, c_expr);
c_expr.expr &:= ")";
else
c_expr.expr &:= "bigLowerBits64(";
getAnyParamToExpr(dividend, c_expr);
c_expr.expr &:= ")";
end if;
optimize_big_mod_dividend(dividend, divisor, c_expr);
if log2(divisor) < 64_ then
c_expr.expr &:= "&";
c_expr.expr &:= integerLiteral(ord(pred(divisor)));
Expand Down
96 changes: 96 additions & 0 deletions prg/chkbin.sd7
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,102 @@ const proc: checkAnd is func
okay := FALSE;
end if;

if bin64(1234567890123456789 + intExpr(7890123456789012345 )) & bin64( integer.first) <>
bin64( 0) or
bin64(1234567890123456789 + intExpr(7890123456789012345 )) & bin64(-6148914691236517206) <>
bin64( 3071501306289463434) or
bin64(1234567890123456789 + intExpr(7890123456789012345 )) & bin64( -1) <>
bin64( 9124691346912469134) or
bin64(1234567890123456789 + intExpr(7890123456789012345 )) & bin64( 1125899906842623) <>
bin64( 398501859844238) or
bin64(1234567890123456789 + intExpr(7890123456789012345 )) & bin64( 1152921504606846975) <>
bin64( 1054240814664540302) or
bin64(1234567890123456789 + intExpr(7890123456789012345 )) & bin64( 3074457345618258602) <>
bin64( 3071501306289463434) or
bin64(1234567890123456789 + intExpr(7890123456789012345 )) & bin64( integer.last) <>
bin64( 9124691346912469134) or
bin64(1234567890123456789_ + bigintExpr(8765432109876543210_)) & bin64( integer.first) <>
bin64( integer.first) or
bin64(1234567890123456789_ + bigintExpr(8765432109876543210_)) & bin64(-6148914691236517206) <>
bin64(-8466166963815404886) or
bin64(1234567890123456789_ + bigintExpr(8765432109876543210_)) & bin64( -1) <>
bin64(-8446744073709551617) or
bin64(1234567890123456789_ + bigintExpr(8765432109876543210_)) & bin64( 1125899906842623) <>
bin64( 882927330656255) or
bin64(1234567890123456789_ + bigintExpr(8765432109876543210_)) & bin64( 1152921504606846975) <>
bin64( 776627963145224191) or
bin64(1234567890123456789_ + bigintExpr(8765432109876543210_)) & bin64( 3074457345618258602) <>
bin64( 757205073039370922) or
bin64(1234567890123456789_ + bigintExpr(8765432109876543210_)) & bin64( integer.last) <>
bin64 ( 776627963145224191) then
writeln(" ***** Bin64 & operator does not work correctly. (5)");
okay := FALSE;
end if;

if bin64( intExpr(1234567890123456789 ) + 7890123456789012345 ) & bin64( integer.first) <>
bin64( 0) or
bin64( intExpr(1234567890123456789 ) + 7890123456789012345 ) & bin64(-6148914691236517206) <>
bin64( 3071501306289463434) or
bin64( intExpr(1234567890123456789 ) + 7890123456789012345 ) & bin64( -1) <>
bin64( 9124691346912469134) or
bin64( intExpr(1234567890123456789 ) + 7890123456789012345 ) & bin64( 1125899906842623) <>
bin64( 398501859844238) or
bin64( intExpr(1234567890123456789 ) + 7890123456789012345 ) & bin64( 1152921504606846975) <>
bin64( 1054240814664540302) or
bin64( intExpr(1234567890123456789 ) + 7890123456789012345 ) & bin64( 3074457345618258602) <>
bin64( 3071501306289463434) or
bin64( intExpr(1234567890123456789 ) + 7890123456789012345 ) & bin64( integer.last) <>
bin64( 9124691346912469134) or
bin64(bigintExpr(1234567890123456789_) + 8765432109876543210_) & bin64( integer.first) <>
bin64( integer.first) or
bin64(bigintExpr(1234567890123456789_) + 8765432109876543210_) & bin64(-6148914691236517206) <>
bin64(-8466166963815404886) or
bin64(bigintExpr(1234567890123456789_) + 8765432109876543210_) & bin64( -1) <>
bin64(-8446744073709551617) or
bin64(bigintExpr(1234567890123456789_) + 8765432109876543210_) & bin64( 1125899906842623) <>
bin64( 882927330656255) or
bin64(bigintExpr(1234567890123456789_) + 8765432109876543210_) & bin64( 1152921504606846975) <>
bin64( 776627963145224191) or
bin64(bigintExpr(1234567890123456789_) + 8765432109876543210_) & bin64( 3074457345618258602) <>
bin64( 757205073039370922) or
bin64(bigintExpr(1234567890123456789_) + 8765432109876543210_) & bin64( integer.last) <>
bin64( 776627963145224191) then
writeln(" ***** Bin64 & operator does not work correctly. (6)");
okay := FALSE;
end if;

if bin64( intExpr(1234567890123456789 ) + intExpr(7890123456789012345 )) & bin64( integer.first) <>
bin64( 0) or
bin64( intExpr(1234567890123456789 ) + intExpr(7890123456789012345 )) & bin64(-6148914691236517206) <>
bin64( 3071501306289463434) or
bin64( intExpr(1234567890123456789 ) + intExpr(7890123456789012345 )) & bin64( -1) <>
bin64( 9124691346912469134) or
bin64( intExpr(1234567890123456789 ) + intExpr(7890123456789012345 )) & bin64( 1125899906842623) <>
bin64( 398501859844238) or
bin64( intExpr(1234567890123456789 ) + intExpr(7890123456789012345 )) & bin64( 1152921504606846975) <>
bin64( 1054240814664540302) or
bin64( intExpr(1234567890123456789 ) + intExpr(7890123456789012345 )) & bin64( 3074457345618258602) <>
bin64( 3071501306289463434) or
bin64( intExpr(1234567890123456789 ) + intExpr(7890123456789012345 )) & bin64( integer.last) <>
bin64( 9124691346912469134) or
bin64(bigintExpr(1234567890123456789_) + bigintExpr(8765432109876543210_)) & bin64( integer.first) <>
bin64( integer.first) or
bin64(bigintExpr(1234567890123456789_) + bigintExpr(8765432109876543210_)) & bin64(-6148914691236517206) <>
bin64(-8466166963815404886) or
bin64(bigintExpr(1234567890123456789_) + bigintExpr(8765432109876543210_)) & bin64( -1) <>
bin64(-8446744073709551617) or
bin64(bigintExpr(1234567890123456789_) + bigintExpr(8765432109876543210_)) & bin64( 1125899906842623) <>
bin64( 882927330656255) or
bin64(bigintExpr(1234567890123456789_) + bigintExpr(8765432109876543210_)) & bin64( 1152921504606846975) <>
bin64( 776627963145224191) or
bin64(bigintExpr(1234567890123456789_) + bigintExpr(8765432109876543210_)) & bin64( 3074457345618258602) <>
bin64( 757205073039370922) or
bin64(bigintExpr(1234567890123456789_) + bigintExpr(8765432109876543210_)) & bin64( integer.last) <>
bin64( 776627963145224191) then
writeln(" ***** Bin64 & operator does not work correctly. (7)");
okay := FALSE;
end if;

aBin64 := bin64( 3689348814741910323 ); aBin64 &:= bin64( 3074457345618258602 ); ok := ok and aBin64 = bin64(2459565876494606882 );
aBin64 := bin64(14757395258967641292_); aBin64 &:= bin64(12297829382473034410_); ok := ok and aBin64 = bin64(9838263505978427528_);
if not ok then
Expand Down

0 comments on commit 7940f0c

Please sign in to comment.