1 /***************************************************************************\
2 |* Function Parser for C++ v4.3 *|
3 |*-------------------------------------------------------------------------*|
4 |* Function optimizer *|
5 |*-------------------------------------------------------------------------*|
6 |* Copyright: Joel Yliluoma *|
8 |* This library is distributed under the terms of the *|
9 |* GNU Lesser General Public License version 3. *|
10 |* (See lgpl.txt and gpl.txt for the license text.) *|
11 \***************************************************************************/
14 This file contains generated code (from the optimizer sources) and is
15 not intended to be modified by hand. If you want to modify the optimizer,
16 download the development version of the library.
19 #include "fpconfig.hh"
20 #ifdef FP_SUPPORT_OPTIMIZER
32 #define tV3 "dup(%u) "
35 #define tS3 "%d, cost "
36 #define tR3 "immed "<<
37 #define tQ3 mFuncParsers
38 #define tP3 "PUSH ";xE3(
41 #define tM3 FPHASH_CONST
42 #define tL3 cache_needed[
44 #define tJ3 ::cout<<"Applying "
45 #define tI3 ||tree.tU3
46 #define tH3 HANDLE_UNARY_CONST_FUNC
70 #define eT3 info.SaveMatchedParamIndex(
100 #define cZ3 result))lA2
107 #define cS3 ),has_max(
111 #define cO3 GetParamCount(nQ
112 #define cN3 GetParamCount();
142 #define yT3 p2 eT ifp2
145 #define yQ3 switch(tX
153 #define yI3 default_function_handling
155 #define yG3 ;sim.Push(
158 #define yD3 [funcno].
159 #define yC3 :start_at()
160 #define yB3 Rehash(tT yA
162 #define y93 IsLogicalValue nW1
163 #define y83 (tree))e5
164 #define y73 stack[stack yA3-
166 #define y53 tmp yC 0))
167 #define y43 ));tmp tU
168 #define y33 ,(long tG1
169 #define y23 );tmp2 yC
171 #define y03 1),eS1(1))
172 #define xZ3 constvalue
178 #define xT3 switch(lF3.first iY2
183 #define xO3 =y6 a));if(
204 #define x33 .n_int_sqrt
208 #define nZ3 tmp yA tree
216 #define nR3 eS1(2)));
228 #define nF3 iC2 size()
240 #define n33 ))break;eS1
244 #define lZ3 cLog2by);
245 #define lY3 sqrt_cost
246 #define lX3 const int
247 #define lW3 mul_count
248 #define lV3 maxValue1
249 #define lU3 minValue1
250 #define lT3 maxValue0
251 #define lS3 minValue0
252 #define lR3 ValueType
253 #define lQ3 >(eS1(1),
257 #define lM3 nF1);}if(
258 #define lL3 yE cAdd);
261 #define lI3 lV1=r.specs;if(r.found){
262 #define lH3 ,lV1,info
263 #define lG3 a;if(&t91
264 #define lF3 parampair
265 #define lE3 rulenumit
266 #define lD3 cIf,l6 3,
267 #define lC3 MakeEqual
269 #define lA3 nH1,{l4::
271 #define l83 branch1op
272 #define l73 branch2op
276 #define l33 );nW l4::
277 #define l23 if nW1 0)
278 #define l13 found_dup
279 #define l03 &1)?(poly^(
282 #define iX2 size_t b=
285 #define iU2 Plan_Has(
289 #define iQ2 const nI2
290 #define iP2 yV1 class
291 #define iO2 namespace
292 #define iN2 rhs.hash2;}
293 #define iM2 rhs.hash1
294 #define iL2 ::res,b8<
307 #define i82 ;if(fp_equal(
318 #define tX2 leaf_count
319 #define tW2 =GetParam(
320 #define tV2 sub_params
322 #define tT2 cbrt_count
323 #define tS2 sqrt_count
325 #define tQ2 p1 eT ifp1
326 #define tP2 pcall_tree
327 #define tO2 after_powi
332 #define tJ2 ,eO3 507 tS
333 #define tI2 ,t71 l7 2,2,
337 #define tE2 cAdd,xZ 2,
338 #define tD2 cInv,xZ 1,
339 #define tC2 cNeg,xZ 1,
341 #define tA2 x11.SubTrees
342 #define t92 x11.Others
343 #define t82 param=*i01
344 #define t72 std::move(
345 #define t62 nM3 switch(
346 #define t52 constraints=
347 #define t42 .constraints
348 #define t32 data;data.
349 #define t22 MakeNEqual
350 #define t12 for yS eC1
352 #define eZ2 Dump(std::
353 #define eY2 isInteger(
354 #define eX2 (cond.cI cA2
356 #define eV2 nG1 r;r tU
357 #define eU2 Comparison
358 #define eT2 needs_flip
359 #define eS2 {data xB lM
360 #define eR2 ,eQ,synth);
361 #define eQ2 (half&63)-1;
363 #define eO2 ));TriTruthValue
364 #define eN2 );range.nN2
365 #define eM2 ,2,1,4,1,2,
366 #define eL2 >StackMax)
367 #define eK2 ~size_t(0)
368 #define eJ2 );t4=!t4;}
369 #define eI2 ;}yV1 static
370 #define eH2 info.lQ[b].
371 #define eG2 const std::eO
372 #define eF2 Rule&rule,
373 #define eE2 .GetHash().
374 #define eD2 (list.first
375 #define eC2 ;iU.hash2+=
377 #define eA2 ,const e1&
379 #define e82 cGreater,
380 #define e72 tree lD 0)
381 #define e62 const eS1&
384 #define e32 cbrt_cost
385 #define e22 best_cost
386 #define e12 )))l81 lH
387 #define e02 result i0
388 #define cZ2 fp_mod(m.
390 #define cX2 (*x6)[a].info
391 #define cW2 tree y21 yI
392 #define cV2 tree nE==
393 #define cU2 condition
395 #define cS2 item_type
398 #define cP2 tS 396676
405 #define cI2 targetpos
406 #define cH2 eat_count
407 #define cG2 ParamSpec
410 #define cD2 ,bool abs){
411 #define cC2 synth.Find(
413 #define cA2 &&cond eH))
414 #define c92 source_tree
415 #define c82 nE==cLog2&&
416 #define c72 =lT1;bool iQ
418 #define c52 p1_evenness
419 #define c42 c32 i13 if(
421 #define c22 isNegative(
424 #define yZ2 StackTopIs(
425 #define yY2 cNop,cNop}}
426 #define yX2 synth.PushImmed(
427 #define yW2 FPoptimizer_ByteCode yU2
428 #define yV2 FPoptimizer_ByteCode::
429 #define yU2 ::ByteCodeSynth x8
430 #define yT2 cTanh,cNop,
432 #define yR2 goto fail;}
437 #define yM2 i7,1,iX+1);
441 #define yI2 best_score
444 #define yF2 nE==cPow&&tJ
445 #define yE2 PowiResult
448 #define yB2 ;pow tU cPow);pow
449 #define yA2 result cM3
450 #define y92 fp_min(xA,
451 #define y82 set_min_max(
455 #define y42 PullResult()
456 #define y32 dup_or_fetch
457 #define y22 nominator]
458 #define y12 Rehash(false
459 #define y02 test_order
461 #define xY2 .param_count
462 #define xX2 shift(index)
463 #define xW2 rulenumber
466 #define xT2 GetDepth()
467 #define xS2 factor_immed
469 #define xQ2 tU tree nE);
470 #define xP2 tU cond nE
471 #define xO2 Become nW1
472 #define xN2 },0,0x1},{{1,
473 #define xM2 ,lJ 0x7 tY3
474 #define xL2 ;n41 eT y9 lD
475 #define xK2 (size_t a=
476 #define xJ2 ;}static yN1
477 #define xI2 tree lD a)
478 #define xH2 for(typename
480 #define xF2 ExponentInfo
481 #define xE2 lower_bound(
483 #define xC2 is_logical
484 #define xB2 newrel_and
485 #define xA2 Suboptimal
487 #define x82 IsAlways;if(
489 #define x62 res_stackpos
491 #define x42 ;}else{x6=new
493 #define x22 {e1 start_at;
494 #define x12 ,(long double)
495 #define x02 .Rehash()
497 #define nY2 );cK3 iJ 2,
498 #define nX2 return false;}
500 #define nV2 xD1 tA+1);
501 #define nU2 ;i7.Remember(
502 #define nT2 .match_tree
503 #define nS2 l81 true;}
504 #define nR2 nD OPCODE
505 #define nQ2 yG x8&immed,
507 #define nO2 CodeTreeData
508 #define nN2 multiply(
511 #define nK2 var_trees
512 #define nJ2 cOr,lP 2,
514 #define nH2 ::Optimize(){
515 #define nG2 second eE3;
516 #define nF2 second.first;
517 #define nE2 log2_exponent
518 #define nD2 tT.swap(tmp);
519 #define nC2 Value(Value::
520 #define nB2 dup_fetch_pos
521 #define nA2 nN,size_t&l31
522 #define n92 *)&*start_at;
523 #define n82 yO3 yI lC
525 #define n62 ContainsOtherCandidates(
526 #define n52 ,cPow l7 2,2,
528 #define n32 lK 2},0,iR 1,
529 #define n22 lK 1},0,iR 1,
530 #define n12 Value_EvenInt
531 #define n02 Sign_Negative
532 #define lZ2 SubFunction:{
533 #define lY2 ParamHolder:{
534 #define lX2 MakeFalse,{l4
535 #define lW2 if(xW lD a)iA
536 #define lV2 ConditionType
537 #define lU2 SpecialOpcode
539 #define lS2 fp_max(xA);
540 #define lR2 assimilated
543 #define lO2 DUP_BOTH();
544 #define lN2 -1-offset].
546 #define lL2 parent_opcode)
547 #define lK2 TreeCounts
548 #define lJ2 bool t4 i13
549 #define lI2 SetOpcode(
550 #define lH2 found_log2
551 #define lG2 div_params
552 #define lF2 .CopyOnWrite()
553 #define lE2 immed_sum
554 #define lD2 OPCODE(opcode)
555 #define lC2 std::cout<<"POP "
556 #define lB2 (stack yA3-
557 #define lA2 break;result*=
558 #define l92 FactorStack x8
559 #define l82 IsAlways yI lC
560 #define l72 l7 2,2,lB1
561 #define l62 248024 tS
562 #define l52 cAnd,lP 2,
564 #define l32 cMul,xZ 2,
565 #define l22 DumpHashesFrom
566 #define l12 replacing_slot
567 #define l02 RefParams
568 #define iZ1 if_always[
569 #define iY1 WhatDoWhenCase
570 #define iX1 exponent_immed
571 #define iW1 new_base_immed
572 #define iV1 base_immed
574 #define iT1 (size_t a xX
575 #define iS1 data[a eD3
576 #define iR1 AddCollection(
577 #define iQ1 if(newrel_or==
578 #define iP1 DUP_ONE(apos);
580 #define iN1 .UseGetNeeded(
581 #define iM1 e9 2,131,
583 #define iK1 OptimizedUsing
584 #define iJ1 Var_or_Funcno
586 #define iH1 DelParam(
587 #define iG1 typename nX1::nX3
588 #define iF1 )nZ2 true
589 #define iE1 GetParams(
591 #define iC1 fphash_value_t
592 #define iB1 signed_chain
593 #define iA1 IsDefined())
596 #define i71 FindClone(xK
597 #define i61 denominator]
598 #define i51 needs_rehash
599 #define i41 AnyWhere_Rec
600 #define i31 minimum_need
604 #define tZ1 ,i01 void*)&
605 #define tY1 41,42,43,44,
606 #define tX1 constraints&
608 #define tV1 p1_logical_b
609 #define tU1 p0_logical_b
610 #define tT1 p1_logical_a
611 #define tS1 p0_logical_a
612 #define tR1 ,PowiCache&i7,
613 #define tQ1 synth.DoDup(
615 #define tO1 cache_needed
616 #define tN1 e9 2,1,e9 2,
618 #define tL1 IsDescendantOf(
619 #define tK1 has_bad_balance
620 #define tJ1 (tree,std::cout)
621 #define tI1 .SetParamsMove(
623 #define tG1 double)cE2
624 #define tF1 {case IsAlways:
625 #define tE1 e02=false
626 #define tD1 ;cE2.Rehash(
628 #define tB1 range x8 result
629 #define tA1 TopLevel)
630 #define t91 *start_at){x6=(
631 #define t81 (rule,tree,info
633 #define t61 ,cEqual l7 2,2,
634 #define t51 cAdd,AnyParams,
636 #define t31 ,cNotNot nR
637 #define t21 ,cLess l7 2,2,
638 #define t11 Oneness_NotOne|
639 #define t01 Value_IsInteger
642 #define eX1 SequenceOpcodes
643 #define eW1 sep_list[
644 #define eV1 );eG n83);
646 #define eT1 TreeCountItem
649 #define eQ1 ,eS1(-1)))xF
650 #define eP1 set_min(fp_floor
651 #define eO1 pihalf_limits
652 #define eN1 y41 p0.min>=0.0)
653 #define eM1 MaxChildDepth
654 #define eL1 situation_flags&
655 #define eK1 i02 opcode)
656 #define eJ1 =yM|i02(nN yA3
657 #define eI1 std::pair<It,It>
658 #define eH1 eO3 483 tS
660 #define eF1 tG2 7168,
661 #define eE1 Value_Logical
662 #define eD1 new_factor_immed
663 #define eC1 if(remaining[a])
664 #define eB1 occurance_pos
665 #define eA1 exponent_hash
666 #define e91 exponent_list
667 #define e81 CollectionSet x8
668 #define e71 CollectMulGroup(
669 #define e61 source_set
671 #define e41 produce_count
674 #define e11 back().thenbranch
675 #define e01 ParamSpec_Extract
676 #define cZ1 retry_anyparams_3
677 #define cY1 retry_anyparams_2
678 #define cX1 needlist_cached_t
679 #define cW1 grammar_rules[*r]
680 #define cV1 tF2 0x1 tY3
681 #define cU1 CodeTreeImmed x8(
682 #define cT1 GetParamCount()==
683 #define cS1 by_float_exponent
684 #define cR1 fp_equal(cE2
686 #define cP1 end()&&i->first==
688 #define cN1 return BecomeZero;
689 #define cM1 return BecomeOne;
690 #define cL1 if(lQ yA3<=n2)
692 #define cJ1 found_log2by
693 #define cI1 ())yE cMul);lC
696 #define cF1 ParsePowiMuli(
697 #define cE1 branch1_backup
698 #define cD1 branch2_backup
699 #define cC1 exponent_map
700 #define cB1 plain_set
701 #define cA1 LightWeight(
702 #define c91 }nM3 case
704 #define c71 synth.x5 1
707 #define c41 set_max(fp_ceil cY
709 #define c21 {eS1 cE2=
710 #define c11 should_regenerate=true;
711 #define c01 should_regenerate,
712 #define yZ1 Collection
713 #define yY1 RelationshipResult
714 #define yX1 Subdivide_Combine(
715 #define yW1 long value
719 #define yS1 eP nE3 StackMax
721 #define yQ1 best_sep_factor
722 #define yP1 tP1!result
723 #define yO1 needlist_cached
724 #define yN1 inline i02
725 #define yM1 221646 tS 24803
726 #define yL1 Constness_Const
727 #define yK1 opcode,bool pad
728 #define yJ1 n_occurrences
729 #define yI1 changed=true;
731 #define yG1 MakesInteger(
732 #define yF1 e62 value
733 #define yE1 best_sep_cost
734 #define yD1 MultiplicationRange
735 #define yC1 ;p1.yB3 p1
737 #define yA1 n_stacked
738 #define y91 AnyParams_Rec
739 #define y81 continue;
740 #define y71 Become(value lD 0))
741 #define y61 ,cGreater l7 2,2,
742 #define y51 yV1 inline TriTruthValue
744 #define y31 ));n41 y3 op1 tT.DelParams(
745 #define y21 .IsImmed()
746 #define y11 =comp.AddItem(atree
747 #define y01 needs_sincos
748 #define xZ1 Recheck_RefCount_Div
749 #define xY1 Recheck_RefCount_Mul
751 #define xW1 n83;n83 tU
752 #define xV1 MultiplyAndMakeLong(
753 #define xU1 cMul);y53;tmp
754 #define xT1 covers_plus1
756 #define xR1 if(synth.FindAndDup(
757 #define xQ1 SynthesizeParam(
758 #define xP1 public e8,public yG<
759 #define xO1 grammar_func
760 #define xN1 221426 tS 237795
761 #define xM1 t93 165888 tS
762 #define xL1 Modulo_Radians},
763 #define xK1 tT.SetParam(
764 #define xJ1 GetImmed()
765 #define xI1 PositionType
766 #define xH1 CollectionResult
768 #define xF1 const_offset
769 #define xE1 stacktop_desired
770 #define xD1 SetStackTop(
771 #define xC1 ,cLessOrEq l7 2,2,
773 #define xA1 cond_type
774 #define x91 Recheck_RefCount_RDiv
775 #define x81 static const range x8
776 #define x71 fPExponentIsTooLarge(
777 #define x61 CollectMulGroup_Item(
778 #define x51 pair<eS1,nV3>
779 #define x41 covers_full_cycle
780 #define x31 AssembleSequence(
781 #define x21 x8(rule.repl_param_list,
784 #define nZ1 <<std::dec<<")";}
785 #define nY1 &&IsLogicalValue(
786 #define nX1 TreeCountType x8
789 #define nU1 std::pair<T1,T2>&
790 #define nT1 n73<typename
791 #define nS1 has_good_balance_found
792 #define nR1 Rehash();tV2 yL
793 #define nQ1 found_log2_on_exponent
794 #define nP1 covers_minus1
795 #define nO1 needs_resynth
796 #define nN1 immed_product
797 #define nM1 }},{ProduceNewTree,2,1,
798 #define nL1 ,2,1)nS if(found[data.
799 #define nK1 t62 bitmask&
800 #define nJ1 Sign_Positive
801 #define nI1 {DataP slot_holder(xY[
802 #define nH1 ::MakeTrue
804 #define nF1 tree.iH1 a
805 #define nE1 tree lD 1)y21&&
806 #define nD1 },{l4::MakeNotP0,l4::
807 #define nC1 SetParamMove(
808 #define nB1 CodeTreeImmed(eS1(
809 #define nA1 <i02 cY2 void
811 #define n81 yG<i02>&c73,
812 #define n71 void ByteCodeSynth x8::
813 #define n61 )const{return
814 #define n51 rhs n61 hash1
815 #define n41 changed_if
816 #define n31 min=eS1(0);
817 #define n21 opposite=
818 #define n11 7168 tS 279818,
820 #define lZ1 MatchResultType
821 #define lY1 resulting_exponent
822 #define lX1 Unknown:default:;}
824 #define lV1 (*x6)[a].start_at
825 #define lU1 ,cAdd,SelectedParams,0},0,
826 #define lT1 GetParam(a)
827 #define lS1 inverse_nominator]
828 #define lR1 void FunctionParserBase
829 #define lQ1 ,nN,IP,limit,y1,stack);
830 #define lP1 ByteCodeSynth x8&synth)
831 #define lO1 xS3 a=0;a<xT;++a)
832 #define lN1 ;std::cout<<
833 #define lM1 const yK2
834 #define lL1 const yG nV1
835 #define lK1 synth.AddOperation(
836 #define lJ1 tQ1 found[data.
837 #define lI1 SetParams(iE1));
838 #define lH1 o<<"("<<std::hex<<data.
839 #define lG1 IfBalanceGood(
840 #define lF1 n_as_tan_param
841 #define lE1 changed_exponent
842 #define lD1 retry_positionalparams_2
843 #define lC1 i02 index
844 #define lB1 463 tS 273436,
845 #define lA1 l7 2,2,473304 tS
846 #define l91 {l4::MakeNotP1,l4::
848 #define l71 yO3 l81 Unknown;}
849 #define l61 PlanNtimesCache(
850 #define l51 AddFunctionOpcode_Float(
851 #define l41 FPoptimizer_Grammar
852 #define l31 IP,size_t limit,size_t y1
853 #define l21 AddOperation(cInv,1,1)nS}
854 #define l11 e92 ImmedHashGenerator
855 #define l01 GetPositivityInfo nO3
857 #define iY CopyOnWrite();
858 #define iX recursioncount
859 #define iW ParamSpec_SubFunctionData
860 #define iV inverse_denominator]
862 #define iT tree.GetParamCount()
863 #define iS PositionalParams_Rec
865 #define iQ needs_cow=GetRefCount()>1;
866 #define iP );nC1 0,cE2);iH1 1);
867 #define iO DumpTreeWithIndent(*this);
868 #define iN switch(type iY2 cond_or:
869 #define iM CalculateResultBoundaries(
870 #define iL e62 v,eS1(lN
871 #define iK AddFunctionOpcode_Integer(
873 #define iI edited_powgroup
874 #define iH has_unknown_max
875 #define iG has_unknown_min
876 #define iF if(keep_powi
877 #define iE synthed_tree
878 #define iD 356668 tS 24852
879 #define iC +2]=yM|i02(Immed yA3);
880 #define iB matched_params
881 #define iA .IsIdenticalTo(
882 #define i9 by_exponent
883 #define i8 collections
886 #define i5 lT void range x8::
887 #define i4 yA comp.cB1[a].value);
888 #define i3 AnyParams,2},0,0x0},{{
892 #define tZ goto ReplaceTreeWithZero;
893 #define tY :goto ReplaceTreeWithOne;case
894 #define tX GetLogicalValue nW1
895 #define tW lN1 std::endl;DumpHashes(
896 #define tV ;p2.yB3 p2);tH iH2 nE);e5}
900 #define tR lZ 0x0},{{
902 #define tP MakeFalse,l4::
903 #define tO ].relationship
904 #define tN <=fp_const_negativezero x8())
905 #define tM .hash1|=key;iC1 n9
906 #define tL [n2 eC3=true;lQ[n2 eD3
907 #define tK l41::Grammar*
908 #define tJ powgroup lD
909 #define tI ;pow tU cLog);tH cMul);
911 #define tG eK2&&found[data.
912 #define tF },{l4::MakeNotNotP1,l4::
913 #define tE },{l4::MakeNotNotP0,l4::
914 #define tD cN3 a-->0;)if(
916 #define tB has_mulgroups_remaining
918 #define t9 MatchInfo x8&
919 #define t8 int_exponent_t
920 #define t7 RootPowerTable x8::RootPowers[
921 #define t6 MatchPositionSpec_AnyParams x8
922 #define t5 iO2 FPoptimizer_ByteCode
924 #define t3 iE1));xX1 Rehash();
925 #define t2 result_positivity
926 #define t1 biggest_minimum
928 #define eZ ParamSpec_NumConstant x8
929 #define eY yK2&tree,std::ostream&o
930 #define eX !=Unchanged)if(TestCase(
934 #define eT .AddParam(
935 #define eS ;xE3(tree)lN1"\n";
937 #define eQ sequencing
938 #define eP StackState
939 #define eO string FP_GetOpcodeName(
941 #define eM {return yK2(
942 #define eL n_as_sin_param
943 #define eK n_as_cos_param
944 #define eJ PowiResolver::
945 #define eI ];};extern"C"{
946 #define eH .BalanceGood
947 #define eG AddParamMove(
949 #define eE best_factor
950 #define eD back().endif_location
955 #define e8 MatchPositionSpecBase
957 #define e6 smallest_maximum
958 #define e5 goto redo;
959 #define e4 ++IP;y81}if(xW3 xV3.
960 #define e3 ReplaceTreeWithParam0;
961 #define e2 factor_needs_rehashing
962 #define e1 MatchPositionSpecBaseP
963 #define e0 nL eS1(-y03;
964 #define cZ 79,112,113,117,118,123,124,127,128,
965 #define cY )l81 m cM3
966 #define cX e01 x8(nM.param_list,
967 #define cW relationships
968 #define cV 28,29,30,31,32,33,34,35,36,
970 #define cT lK 2},0,0x0},{{
971 #define cS data.subfunc_opcode
972 #define cR }if eD2.xJ1==eS1(
974 #define cP :{AdoptChildrenWithSameOpcode(tree);
975 #define cO map<fphash_t,std::set<std::string> >
976 #define cN const SequenceOpCode x8
977 #define cM =fp_cosh(m.min);m.max=fp_cosh(m.max);
978 #define cL MatchPositionSpec_PositionalParams x8
979 #define cK eS1(1.5)*fp_const_pi x8()
980 #define cJ !=Unchanged nZ2 iZ1
981 #define cI FoundChild
982 #define cH CalculatePowiFactorCost(
983 #define cG T1,typename T2>inline i12()(
984 #define cF yK2 tmp;tmp tU
985 #define cE has_nonlogical_values
986 #define cD from_logical_context)
987 #define cC for xK2 xW.cN3 a-->0;)
988 #define cB POWI_CACHE_SIZE
989 #define cA static inline yK2
990 #define c9 BalanceResultType
992 #define c7 nA3(0),Opcode(
993 #define c6 const{return data->
994 #define c5 +=fp_const_twopi x8();
995 #define c4 .AddOperation(lM2,
996 #define c3 for xK2 0;a<cN3++a){if(
997 #define c2 static void MakeHash(nD fphash_t&iU,
999 #define c0 MatchPositionSpec_AnyWhere
1000 #define yZ if iZ2 data.match_type==
1001 #define yY }PACKED_GRAMMAR_ATTRIBUTE;
1002 #define yX ,cGreaterOrEq l7 2,2,
1003 #define yW void OutFloatHex(std::ostream&o,
1004 #define yV yV1 x72 range x8::
1005 #define yU b;}};n73<>e92 Comp<
1006 #define yT eT CodeTreeImmed(
1007 #define yS xK2 0;a<iT;++a)
1008 #define yR t93 115824 tS 122999,
1009 #define yQ t93 129136 tS 128123,
1010 #define yP t93 472176 tS 24699,
1011 #define yO ,typename yK2::
1012 #define yN AssembleSequence_Subdivide(
1013 #define yM 0x80000000u
1014 #define yL .push_back(
1015 #define yK !=eK2){lJ1
1017 #define yI nZ2 false;
1018 #define yH paramholder_matches
1019 #define yG std::vector
1020 #define yF ,AnyParams,0 l1 0,1,
1022 #define yD for(lE3 r=range.first;r!=range eE3;++r){
1023 #define yC eT tree lD
1024 #define yB ComparisonSetBase::
1027 #define y8 fp_const_twopi x8());if(
1028 #define y7 n73 set_min_max_if<cGreater>(eS1(0),
1029 #define y6 iM tree lD
1030 #define y5 =y6 0));range x8
1031 #define y4 tree lD 1).xJ1
1033 #define y2 lX&&tree lD 1)y21
1034 #define y1 factor_stack_base
1035 #define y0 cPow,l6 2,
1036 #define xZ GroupFunction,0},n0{{
1037 #define xY data->c93
1038 #define xX =0;a<nU3.cN3++a)if(
1040 #define xV {lK2.erase(i);y81}
1041 #define xU xK2 iT;a-->0;)
1043 #define xS i02 c;i02 char l[
1044 #define xR 158,167,168,169,178,179,191,195,203,207,215,227,229,232,233,234,235,236,239,240,241,242,245,246,247,248,250,251}};}e92
1045 #define xQ using iO2 FUNCTIONPARSERTYPES;
1046 #define xP const eY=std::cout
1047 #define xO IsIdenticalTo(leaf2 lD
1048 #define xN FPOPT_autoptr
1049 #define xM +=result l81 result;}yV1 inline eS1
1050 #define xL int_exponent
1053 #define xI ParamSpec_SubFunction
1054 #define xH ParamSpec_ParamHolder
1055 #define xG has_highlevel_opcodes
1056 #define xF {if(needs_cow){iY goto
1057 #define xE ;if(fp_nequal(tmp,eS1(0)))lL eS1(1)/tmp)n5}lC
1058 #define xD },{l4::Unchanged,l4::Never},{l4::Unchanged,l4::Never}}
1059 #define xC best_selected_sep
1060 #define xB ->Recalculate_Hash_NoRecursion();}
1061 #define xA fp_sin(min),fp_sin(max))
1062 #define x9 sim.AddConst(
1064 #define x7 :nG1 tmp,tmp2;tmp2 tU
1066 #define x5 GetStackTop()-
1067 #define x4 for yS{range x8
1068 #define x3 SwapLastTwoInStack();
1069 #define x2 FPoptimizer_CodeTree::yK2&tree
1070 #define x1 SetParam(0,iH2 lD 0))yJ p1;p1 tU
1071 #define x0 TestImmedConstraints(param t42,tree)yI
1072 #define nZ {tree.FixIncompleteHashes();}
1073 #define nY {yE3 cInv nW2 x9-1 e21
1074 #define nX paramholder_index
1075 #define nW return true;case
1076 #define nV occurance_counts
1077 #define nU PositionalParams,0},0,
1078 #define nT xQ xD1 tA-1);
1079 #define nS ;synth.yZ2*this)l81;}
1081 #define nQ );a-->0;){lM1&powgroup=lT1;if(powgroup
1082 #define nP ;a<iT;++a)if(ApplyGrammar(tN2,xI2,
1083 #define nO lK 1},0,0x0},{{
1085 #define nM model_tree
1086 #define nL return range x8(
1087 #define nK yG nV1&l02
1088 #define nJ ConstantFolding_LogicCommon(tree,yB
1089 #define nI eS1>p xO3 p.
1090 #define nH nT1 Ref>inline void xN<Ref>::
1091 #define nG ;tmp2 yC 0 y43 cInv);tmp yY3 l81
1092 #define nF ):data(new nO2 x8(
1094 #define nD FUNCTIONPARSERTYPES::
1095 #define nC iJ1(),c93(),Hash(),Depth(1),eZ1 0){}
1096 #define nB SynthesizeByteCode(synth);
1097 #define nA nO2 x8::nO2(
1098 #define n9 crc=(key>>10)|(key<<(64-10))eC2((~iC1(crc))*3)^1234567;}};
1099 #define n8 GetIntegerInfo nW1 0))==IsAlways)lN3
1100 #define n7 eS1(*const func)(eS1),range x8 model){
1102 #define n5 ;goto do_return;}
1103 #define n4 while(ApplyGrammar(i01 Grammar&)
1104 #define n3 DumpParams x8 iZ2 data.param_list,xF3 data xY2,o);
1105 #define n2 restholder_index
1106 #define n1 yK2 cE2;cE2 e53 cE2 eT
1107 #define n0 yL1,0x0},
1108 #define lZ t51 1},0,
1109 #define lY ;tree yA n41)nS2
1111 #define lW eG pow x03;pow.iH1 1);pow.Rehash(tT.nC1 0,pow);goto NowWeAreMulGroup;}
1112 #define lV {cF cPow);y53;tmp yT eS1(
1113 #define lU :if(ParamComparer x8()(c93[1],c93[0])){std::swap(c93[0],c93[1]);Opcode=
1114 #define lT <typename eS1>
1115 #define lS ,eS1(1)/eS1(
1116 #define lR SetParam(0,e72 lD 0)xK1 1,CodeTreeImmed(
1117 #define lQ restholder_matches
1118 #define lP SelectedParams,0},0,0x0},{{
1119 #define lO n41;n41 xQ2 n41 yA e72);n41 eT xW lD
1120 #define lN *const func)(eS1),range x8 model=range x8());
1121 #define lM yV1 yK2::yL2(
1122 #define lL {tree.ReplaceWithImmed(
1123 #define lK cMul,AnyParams,
1124 #define lJ cMul,SelectedParams,0},0,
1125 #define lI cPow,l0 2
1126 #define lH iM tmp)cM3
1127 #define lG :cC3=comp.AddRelationship(atree lD 0),atree lD 1),yB
1128 #define lF typename eS1>i12()i01 eS1&a,e62 b){return a
1130 #define lD .GetParam(
1131 #define lC break;case
1132 #define lB {range x8 m=y6 0));
1133 #define lA xB1 yK2::
1134 #define l9 ?0:1))yJ n41;n41 xQ2 n41 tI1 tree.iE1));n41 y3
1136 #define l7 ,PositionalParams,0 l1
1138 #define l5 cAdd,lP 2,
1139 #define l4 RangeComparisonData
1140 #define l3 PositionalParams,0}},{ProduceNewTree,
1141 #define l2 lJ 0x0},{{
1142 #define l1 }},{ReplaceParams,
1143 #define l0 nU 0x0},{{
1156 crc32{enum{startvalue=0xFFFFFFFFUL,poly=0xEDB88320UL}
1198 #define B4(n) b8<n>iL2 n+1>iL2 n+2>iL2 n+3>::res
1199 #define R(n) B4(n),B4(n+4),B4(n+8),B4(n+12)
1203 table[256]={R(0x00),R(0x10),R(0x20),R(0x30),R(0x40),R(0x50),R(0x60),R(0x70),R(0x80),R(0x90),R(0xA0),R(0xB0),R(0xC0),R(0xD0),R(0xE0),R(0xF0)}
1207 return((crc>>8))^table[(crc^b)&0xFF];i6
1215 p=0;p<size;++p)value=update(value,buf[p])l81
1223 calc_upd(startvalue,buf,size);}
1225 #ifndef FPOptimizerAutoPtrHH
1226 #define FPOptimizerAutoPtrHH
1239 xN&e31=(Ref*b){Set(b)l81*this;}
1241 xN&b){Set(b.p)l81*this;}
1242 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1243 xN(xN&&b):p(b.p){b.p=0;}
1244 xN&e31=(xN&&b){if(p!=b.p){cF2;p=b.p;b.p=0;}
1249 UnsafeSetP(Ref*newp){p=newp
1251 swap(xN<Ref>&b){Ref*tmp=p;p=b.p;b.p=tmp;}
1262 Set(Ref*p2);private:Ref*p;}
1265 nZ2;p->nA3-=1;if(!p->nA3)delete
1268 Have(Ref*p2){if(p2)++(p2->nA3);}
1272 Set(Ref*p2){Have(p2);cF2;p=p2;}
1314 #ifndef FPoptimizerHashHH
1315 #define FPoptimizerHashHH
1322 #define FPHASH_CONST(x) x##ULL
1328 #define FPHASH_CONST(x) x##ULL
1331 FUNCTIONPARSERTYPES{e92
1333 hash1,hash2;fphash_t():hash1(0),hash2(0){}
1337 iC1&b):hash1(a),hash2(b){}
1339 fphash_t&n51==iM2&&hash2==iN2
1341 fphash_t&n51!=iM2||hash2!=iN2
1343 fphash_t&n51!=iM2?hash1<iM2:hash2<iN2}
1346 #ifndef FPOptimizer_CodeTreeHH
1347 #define FPOptimizer_CodeTreeHH
1348 #ifdef FP_SUPPORT_OPTIMIZER
1357 FPoptimizer_CodeTree{iP2
1373 f,FuncOpcodeTag);e92
1378 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1400 keep_powi=false);void
1412 keep_powi=false);void
1413 SynthesizeByteCode(n81
1415 size_t&stacktop_max);void
1416 SynthesizeByteCode(yW2&synth,bool
1417 MustPopTemps=true)const;size_t
1418 SynthCommonSubExpressions(yV2
1429 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1431 SetParams(yG<yL2>&&eU1
1469 GetParam(xL3){return
1532 constantfolding=true);void
1535 Mark_Incompletely_Hashed()cX3
1538 Is_Incompletely_Hashed()c6
1542 GetOptimizedUsing()c6
1551 RecreateInversionsAndNegations(bool
1552 prefer_base2=false);void
1553 FixIncompleteHashes();void
1555 b){data.swap(b.data);}
1585 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1587 eS1&&i);nO2(nO2&&b);
1594 Recalculate_Hash_NoRecursion();private:void
1604 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1606 CodeTreeImmed(eS1&&i)eM
1631 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
1635 DumpTreeWithIndent(xP,const
1636 std::string&indent="\\"
1642 #ifndef FPOPT_NAN_CONST
1644 #define FPOPT_NAN_CONST (-1712345.25)
1646 FPoptimizer_CodeTree{iP2
1650 ImmedConstraint_Value{ValueMask=0x07,Value_AnyNum=0x0,n12=0x1,Value_OddInt=0x2,t01=0x3,Value_NonInteger=0x4,eE1=0x5
1652 ImmedConstraint_Sign{SignMask=0x18,Sign_AnySign=0x00,nJ1=0x08,n02=0x10,Sign_NoIdea=0x18
1654 ImmedConstraint_Oneness{OnenessMask=0x60,Oneness_Any=0x00,Oneness_One=0x20,Oneness_NotOne=0x40
1656 ImmedConstraint_Constness{ConstnessMask=0x180,Constness_Any=0x00,yL1=0x80,Constness_NotConst=0x100
1658 Modulo_Mode{Modulo_None=0,Modulo_Radians=1
1660 Situation_Flags{LogicalContextOnly=0x01,NotForIntegers=0x02,OnlyForIntegers=0x04
1662 lU2{NumConstant,ParamHolder,SubFunction
1664 ParamMatchingType{PositionalParams,SelectedParams,AnyParams,GroupFunction
1666 RuleType{ProduceNewTree,ReplaceParams}
1669 # define PACKED_GRAMMAR_ATTRIBUTE __attribute__((packed))
1671 # define PACKED_GRAMMAR_ATTRIBUTE
1685 ParamSpec_GetDepCode
1692 ParamSpec_NumConstant{eS1
1699 subfunc_opcode:8;ParamMatchingType
1710 situation_flags:3;i02
1711 repl_param_count:2+11;i02
1712 repl_param_list:30;iW
1727 cG2&p,std::ostream&o=std::cout);xB1
1731 count,std::ostream&o=std::cout);}
1734 #define M_PI 3.1415926535897932384626433832795
1736 #define CONSTANT_POS_INF HUGE_VAL
1737 #define CONSTANT_NEG_INF (-HUGE_VAL)
1739 FUNCTIONPARSERTYPES{yV1
1742 fp_const_pihalf(){return
1748 fp_const_twopi(){eS1
1756 fp_const_twoeinv(){eS1
1760 fp_const_negativezero(){
1770 #ifdef FP_SUPPORT_OPTIMIZER
1775 FPoptimizer_Optimize{using
1779 FPoptimizer_CodeTree;xQ
1782 yG<std::pair<bool,yG
1786 MatchInfo():lQ(),yH(),iB(){}
1789 SaveOrTestRestHolder
1823 SaveOrTestParamHolder
1832 if(!yH[nX].iA1{yH[nX]=nG3
1838 SaveMatchedParamIndex(lC1){iB
1841 lM1&GetParamHolderValueIfFound
1851 lM1&GetParamHolderValue
1864 lL1&GetRestHolderValues
1875 yG<i02>&GetMatchedParamIndexes(n61
1879 b){lQ.swap(b.lQ);yH.swap(b.yH);iB.swap(b.iB);}
1883 b){lQ=b.lQ;yH=b.yH;iB=b.iB
1899 f):found(f),specs(){}
1903 s):found(f),specs(s){}
1919 TestParams(t0&nM,lM1&tree
1927 from_logical_context=false);xB1
1928 ApplyGrammars(x2);xG1
1929 IsLogisticallyPlausibleParamsMatch(t0&cB2,const
1937 FPoptimizer_Optimize::t9
1939 DidMatch,std::ostream&o=std::cout);xB1
1944 FPoptimizer_Optimize::t9
1946 char*eY3,std::ostream&o=std::cout);}
1966 char*p=0;switch(opcode
1968 NumConstant:p="NumConstant"
1970 ParamHolder:p="ParamHolder"
1972 SubFunction:p="SubFunction"
1975 tmp;assert(p);tmp<<p;if(pad)while(tmp.str()yA3<12)tmp<<' 'l81
1979 tmp;tmp<<opcode;if(pad)while(tmp.str()yA3<5)tmp<<' 'l81
1988 char*p=0;switch(opcode
2080 cLessOrEq:p="cLessOrEq"
2082 cGreater:p="cGreater"
2084 cGreaterOrEq:p="cGreaterOrEq"
2100 #ifdef FP_SUPPORT_OPTIMIZER
2104 cPopNMov:p="cPopNMov"
2116 cAbsNotNot:p="cAbsNotNot"
2141 tmp;assert(p);tmp<<p;if(pad)while(tmp.str()yA3<12)tmp<<' 'l81
2145 tmp;tmp<<opcode;if(pad)while(tmp.str()yA3<5)tmp<<' 'l81
2149 #ifdef FP_SUPPORT_OPTIMIZER
2152 #ifndef FP_GENERATING_POWI_TABLE
2153 enum{MAX_POWI_BYTECODE_LENGTH=20}
2156 enum{MAX_POWI_BYTECODE_LENGTH=999}
2159 enum{MAX_MULI_BYTECODE_LENGTH=3}
2162 ByteCodeSynth():nN(),Immed(),eP(),tA(0),StackMax(0){nN.nH3
2168 x8&imm,size_t&StackTop_max){for
2173 nN.swap(bc);Immed.swap(imm);StackTop_max=StackMax;}
2196 offset=0){if((int)tA>offset){eP[tA
2206 n61(int)tA>offset&&eP[tA
2227 e41=1){EatNParams(cH2);xQ
2228 AddFunctionOpcode(opcode);ProducedNParams(e41
2237 srcpos+1);eP[cI2]=eP[srcpos];xD1
2271 pos=e33(tree);if(pos!=eK2){
2272 #ifdef DEBUG_SUBSTITUTIONS
2273 std::cout<<tZ3"duplicate at ["
2275 ;xE3(tree)lN1" -- issuing cDup or cFetch\n"
2284 SynthIfStep1(IfData&yJ2,nR2
2292 SynthIfStep2(IfData&yJ2){nT
2293 nN[yJ2.ofs+1]eJ1+2);nN[yJ2.ofs
2301 SynthIfStep3(IfData&yJ2){nT
2302 nN.back()|=yM;nN[yJ2.ofs+1]eJ1-1);nN[yJ2.ofs
2307 0;a<yJ2.ofs;++a){if(nN[a]==cJump&&nN[a+1]==(yM|(yJ2.ofs-1))){nN[a+1]eJ1-1);nN[a
2316 cFetch:a+=1;break;default:nM3}
2321 value){tA=value;if(tA
2322 eL2{StackMax=tA;yS1);}
2329 AddFunctionOpcode(eK1;private:yG<i02>nN;yG
2331 Immed;yG<std::pair<bool,FPoptimizer_CodeTree::yK2> >eP;size_t
2346 #ifdef FP_SUPPORT_OPTIMIZER
2352 op_normal,op_normal_flip;i02
2353 op_inverse,op_inverse_flip;}
2357 x8::AddSequence={eS1(0),cNeg,cAdd,cAdd,cSub,cRSub}
2361 x8::MulSequence={eS1(1),cInv,cMul,cMul,cDiv,cRDiv}
2367 #define incStackPtr() do{if(tA+2 eL2 yS1=tA+2);}while(0)
2368 #define findName(a,b,c) "var"
2369 #define TryCompilePowi(o) false
2371 #define mByteCode nN
2372 #define mImmed Immed
2373 # define FP_FLOAT_VERSION 1
2374 # include "fp_opcode_add.inc"
2375 # undef FP_FLOAT_VERSION
2379 #undef TryCompilePowi
2387 #define incStackPtr() do{if(tA+2 eL2 yS1=tA+2);}while(0)
2388 #define findName(a,b,c) "var"
2389 #define TryCompilePowi(o) false
2391 #define mByteCode nN
2392 #define mImmed Immed
2393 # define FP_FLOAT_VERSION 0
2394 # include "fp_opcode_add.inc"
2395 # undef FP_FLOAT_VERSION
2399 #undef TryCompilePowi
2404 AddFunctionOpcode(eK1{if(IsIntType
2412 #define POWI_TABLE_SIZE 256
2413 #define POWI_WINDOW_SIZE 3
2415 #ifndef FP_GENERATING_POWI_TABLE
2420 powi_table[POWI_TABLE_SIZE];const
2424 powi_table[POWI_TABLE_SIZE]={0,1,1,1,2,1
2434 27,5,8,3,2,1,30,1,31,3,32,1
2437 39,1,16,137,2,1,4,cB3
2438 e43,45,135,4,31,2,5,32,1,2,131,50,1,51,1,8,3,2,1,54,1,55,3,16,1,57,133,4,137,2,135,60,1,61,3,62,133,63,1,tN1
2442 30,1,130,137,2,31,iM1
2449 61,130,133,62,139,130,137,e9
2464 130,133,130,141,130,131,e9
2473 PowiCache{private:int
2476 PowiCache():i7(),tO1(){i7[1]=1;}
2486 yW1){c51<cB)i7[eP2=1
2490 n=2;n<cB;++n)i7[n]=-1;Remember(1,value1_pos);DumpContents();}
2492 Find(yW1)const{c51<cB){if(i7[eP2>=0){FPO(tK3(tO3,"* I found %ld from cache (%u,%d)\n",value,(unsigned)cache[value],tL3 value]))l81
2499 nZ2;FPO(tK3(tO3,"* Remembering that %ld can be found at %u (%d uses remain)\n",value,(unsigned)tW3,tL3 value]));i7[eP2=(int)tW3
2501 DumpContents()const{FPO(for(int a=1;a<POWI_CACHE_SIZE;++a)if(cache[a]>=0||tL3 a]>0){tK3(tO3,"== cache: sp=%d, val=%d, needs=%d\n",cache[a],a,tL3 a]);})}
2503 UseGetNeeded(yW1){c51>=0&&value<cB
2523 cumulation_opcode,i02
2524 cimulation_opcode_flip,lP1;void
2532 #ifdef FP_GENERATING_POWI_TABLE
2536 if(i7.Plan_Add(value,need_count)nZ2;long
2538 1;c51<POWI_TABLE_SIZE){nJ3
2542 FPO(tK3(tO3,"value=%ld, half=%ld, otherhalf=%ld\n",value,half,value/half));l61
2551 value&((1<<POWI_WINDOW_SIZE)-1);else
2555 iT2>cQ||half<0)std::swap(half,cQ);FPO(tK3(tO3,"value=%ld, half=%ld, otherhalf=%ld\n",value,half,otherhalf))iT2==cQ){l61
2569 nK3=i7.Find(value);if(nK3>=0){return
2573 1;c51<POWI_TABLE_SIZE){nJ3
2577 FPO(tK3(tO3,"* I want %ld, my plan is %ld * %ld\n",value,half,value/half));size_t
2583 half)>0||x52!=c71){tQ1
2592 value,tW3);i7.DumpContents()l81
2599 value&((1<<POWI_WINDOW_SIZE)-1);else
2603 iT2>cQ||half<0)std::swap(half,cQ);FPO(tK3(tO3,"* I want %ld, my plan is %ld + %ld\n",value,half,value-half))iT2==cQ){size_t
2608 x52,half,x52,half,i7,eQ.op_normal,eQ.op_normal_flip,synth);}
2611 part2=cQ>0?cQ:-cQ;size_t
2619 FPO(tK3(tO3,"Subdivide(%ld: %ld, %ld)\n",value,half,otherhalf));yX1
2620 part1_pos,part1,part2_pos,part2,i7,cQ>0?eQ.op_normal:eQ.op_inverse,cQ>0?eQ.op_normal_flip:eQ.op_inverse_flip,synth);}
2624 value,tW3);i7.DumpContents()l81
2635 cumulation_opcode,i02
2636 cumulation_opcode_flip,lP1{int
2645 #define DUP_BOTH() do tX3<bpos){size_t tmp=apos;apos=bpos;bpos=tmp;iO1=!iO1;}FPO(tK3(tO3,"-> "tV3 tV3"op\n",(unsigned)apos,(unsigned)bpos));tQ1 apos);tQ1 apos==bpos?c71:bpos);}while(0)
2646 #define DUP_ONE(p) do{FPO(tK3(tO3,"-> "tV3"op\n",(unsigned)p));tQ1 p);}while(0)
2647 if(a_needed>0){if(nL3>0){lO2}
2648 else{if(bpos!=c71)lO2
2658 tX3==bpos&&apos==c71)iP1
2660 apos==c71&&bpos==synth.x5
2661 2){FPO(tK3(tO3,"-> op\n"));iO1=!iO1;}
2664 2&&bpos==c71)FPO(tK3(tO3,"-> op\n"));tP1
2665 apos==c71)DUP_ONE(bpos);tP1
2671 iO1?cumulation_opcode_flip:cumulation_opcode,2);}
2675 count,cN&eQ,lP1{while
2679 powi_table[count]iT2&128){half&=127;cA1
2710 cR3<0){eT2=true;count=-count;}
2720 GetStackTop();i7.Start(c71);FPO(tK3(tO3,"Calculating result for %ld...\n",count));size_t
2728 xE1;if(n_excess>0||x62!=xE1-1){synth.DoPopNMov(xE1-1,x62);}
2735 #ifndef FPOptimizer_RangeEstimationHH
2736 #define FPOptimizer_RangeEstimationHH
2738 FPoptimizer_CodeTree{enum
2739 TriTruthValue{IsAlways,yO3,Unknown}
2743 iV2,has_max;range():min(),max(),iV2(false
2748 ma):min(mi),max(ma),iV2(true
2752 ma):min(),max(ma),iV2(false
2756 mi,bool):min(mi),max(),iV2(true
2828 Unknown;yF1=yZ3;if(isEvenInteger(value)nZ2
2830 isOddInteger(value)nZ2
2850 GetLogicalValue(lM1&tree
2855 tree);if(IsLogicalTrueValue(p,abs)nZ2
2857 IsLogicalFalseValue(p,abs)nZ2
2860 #ifndef FPOptimizer_ConstantFoldingHH
2861 #define FPOptimizer_ConstantFoldingHH
2863 FPoptimizer_CodeTree{xB1
2864 ConstantFolding(eR;}
2869 FPoptimizer_CodeTree;e92
2870 ComparisonSetBase{enum{e93=0x1,Eq_Mask=0x2,Le_Mask=0x3,eA3=0x4,eB3=0x5,Ge_Mask=0x6}
2874 m){return(m&Eq_Mask)|((m&e93)?eA3:0)|((m&eA3)?e93:0);}
2876 yY1{Ok,BecomeZero,BecomeOne,xA2
2878 lV2{cond_or,i32,i42,i52}
2881 ComparisonSet:public
2882 ComparisonSetBase{e92
2888 relationship;eU2():a(),b(),relationship(){}
2894 yN2;Item():value(),yN2(false){}
2897 xF1;ComparisonSet():cW(),cB1(),xF1(0){}
2906 a)){if(yN2!=cB1[c].yN2){iN
2909 i52:cB1.erase(cB1.begin()+c);xF1+=1
2918 pole;pole.value=a;pole.yN2=yN2;cB1
2939 if(!(a.GetHash()<b.GetHash())){a.swap(b);eY1=Swap_Mask(eY1);}
2948 nS3=x92|eY1;if(nS3==7)cM1
2953 nS3=x92&eY1;if(nS3==0)cN1
2957 newrel_or=x92|eY1;int
2962 7&&xB2==0){xF1+=1;cW.erase(cW.begin()+c)n01}
2964 7&&xB2==Eq_Mask){x92=Eq_Mask;xF1+=1
2972 comp;comp.a=a;comp.b=b;comp.relationship=eY1;cW
2980 ConstantFolding_LogicCommon(yK2&tree,CondType
2993 Ok;lM1&atree=xI2;switch(atree
3028 0),false,xA1);break;default:if(xC2||IsLogicalValue(atree))cC3
3029 y11,false,xA1);yN3(cC3){ReplaceTreeWithZero
3031 ReplaceWithImmed(0)l81
3032 true;ReplaceTreeWithOne
3034 ReplaceWithImmed(1);nW
3045 if(should_regenerate){
3046 #ifdef DEBUG_SUBSTITUTIONS
3047 std::cout<<"Before ConstantFolding_LogicCommon: "
3050 if(xC2){tree.DelParams();}
3052 xU{lM1&atree=xI2;if(IsLogicalValue(atree))nF1);}
3058 a){if(comp.cB1[a].yN2)eV2
3074 cNop);switch(comp.cW[a
3110 #ifdef DEBUG_SUBSTITUTIONS
3111 std::cout<<"After ConstantFolding_LogicCommon: "
3118 ConstantFolding_AndLogic(tT3(tree.tU3()==cAnd
3123 ConstantFolding_OrLogic(tT3(tree.tU3()==cOr
3128 ConstantFolding_AddLogicItems(tT3(tree.tU3()==cAdd)l81
3132 ConstantFolding_MulLogicItems(tT3(tree.tU3()==cMul)l81
3138 #include <algorithm>
3142 FPoptimizer_CodeTree;e92
3143 CollectionSetBase{enum
3147 CollectionSet:public
3148 CollectionSetBase{e92
3154 e2;yZ1():value(),xD2(),e2(false){}
3155 yZ1(lM1&v,lM1&f):value(v),xD2(f),e2(false){}
3157 ;std::multimap<fphash_t,yZ1>i8;typedef
3159 std::multimap<fphash_t,yZ1>::nX3
3160 xI1;CollectionSet():i8(){}
3162 FindIdenticalValueTo(lM1&value){fphash_t
3163 hash=value.GetHash();for(xI1
3179 AddCollectionTo(lM1&xD2,const
3180 xI1&into_which){yZ1&c=into_which
3191 xD2);c.xD2.swap(add);c.e2=true;}
3196 lM1&value,lM1&xD2){const
3198 hash=value.GetHash();xI1
3200 hash);for(;i!=i8.cP1
3205 AddCollectionTo(xD2,i);}
3206 i8.nT3,std::make_pair(hash,yZ1(value,xD2)))l81
3216 ConstantExponentCollection{typedef
3221 xF2;yG<xF2>data;ConstantExponentCollection():data(){}
3227 std::x51(e51()));data.back()eE3.swap(e61
3231 eS1&e51&e61){typename
3235 data.end(),cE2,Compare1st());if(i!=data.cP1
3240 else{data.nT3,std::x51(cE2,e61));}
3247 data.end(),Compare1st());redo:for
3263 xG2=exp_b-exp_a;if(xG2>=fp_abs(exp_a
3265 exp_diff_still_probable_integer=xG2*eS1(16);if(eY2
3266 exp_diff_still_probable_integer)&&!(eY2
3268 xG2))){nV3&a_set=iS1;nV3&b_set=data[b
3270 #ifdef DEBUG_SUBSTITUTIONS
3271 std::cout<<"Before ConstantExponentCollection iteration:\n"
3275 if(isEvenInteger(exp_b)&&!isEvenInteger(xG2+exp_a))nG1
3291 a_set.insert(a_set.end(),b_set.i62
3293 b_copy=b_set;data.erase(data.begin()+b);MoveToSet_NonUnique(xG2,b_copy);yI1
3294 #ifdef DEBUG_SUBSTITUTIONS
3295 std::cout<<"After ConstantExponentCollection iteration:\n"
3304 #ifdef DEBUG_SUBSTITUTIONS
3311 a){out.precision(12);out<<data[a
3316 b){if(b>0)out<<'*';xE3(iS1[b],out);}
3325 yK2&value,bool&xG){switch(value
3335 cRSqrt:value.y71;xG=true
3338 cInv:value.y71;xG=true
3346 e81&mul,lM1&tree,lM1&xD2,bool&c01
3355 y21||xD2.xJ1!=1.0)nG1
3364 #if 0 /* FIXME: This does not work */
3366 nE==cMul){if(1){bool
3367 exponent_is_even=cE2
3368 y21&&isEvenInteger(cE2.xJ1);eW3
3376 val,tmp));if(exponent_is_even||(exp
3377 y21&&isEvenInteger(exp.xJ1)))nG1
3384 exp);cQ1.ConstantFolding();if(!cQ1
3385 y21||!isEvenInteger(cQ1.xJ1)){goto
3397 value,cE2)==CollectionSetBase::xA2)c11}
3401 ConstantFolding_MulGrouping(eR{bool
3414 std::multimap<fphash_t,e91>cC1;cC1
3418 j!=mul.i8.end();++j)nG1&value=j
3425 eA1=cE2.GetHash();typename
3441 i9.nT3,std::make_pair(eA1,std::make_pair(cE2,yG
3442 nV1(size_t(1),value))));skip_b:;}
3443 #ifdef FP_MUL_COMBINE_EXPONENTS
3444 ConstantExponentCollection
3449 i!=i9.end();i=j){j=i;++j;e91&list=i
3453 list.first.xJ1;if(!(cE2==eS1(0)))cS1.MoveToSet_Unique(cE2,list
3456 if(cS1.Optimize())c11
3458 if(should_regenerate)nG1
3459 before=tree;before.iY
3460 #ifdef DEBUG_SUBSTITUTIONS
3461 std::cout<<"Before ConstantFolding_MulGrouping: "
3465 tree.DelParams();xH2
3468 i!=i9.end();++i){e91&list=i
3470 #ifndef FP_MUL_COMBINE_EXPONENTS
3474 list.first.xJ1;if(cE2==eS1(0))y81
3475 if(cR1,nY3{tree.AddParamsMove(list
3486 x02;if(xG&&list.first
3488 eD2.xJ1==eS1(1)/eS1(3))nG1
3521 #ifdef FP_MUL_COMBINE_EXPONENTS
3527 eC3;if(cR1,nY3{tree.AddParamsMove(i2[a
3544 #ifdef DEBUG_SUBSTITUTIONS
3545 std::cout<<"After ConstantFolding_MulGrouping: "
3553 ConstantFolding_AddGrouping(eR{bool
3562 if(add.AddCollection
3564 a))==CollectionSetBase::xA2)c11}
3565 yG<bool>remaining(iT);size_t
3576 c=add.FindIdenticalValueTo(n83
3578 b));if(add.Found(c))nG1
3583 x02;add.AddCollectionTo(tmp,c);c11
3587 remaining[a]=true;tB+=1;done_a:;}
3589 if(tB>0){if(tB>1){yG<std::pair<yK2,size_t> >nV;std::multimap<fphash_t,size_t>eB1;bool
3597 p_hash=p.GetHash();for(std::multimap<fphash_t,size_t>::const_iterator
3606 eD3+=1;l13=true;goto
3607 found_mulgroup_item_dup;}
3611 std::make_pair(p,size_t(1)));eB1.insert(std::make_pair(p_hash,nV
3612 yA3-1));found_mulgroup_item_dup:;}
3633 #ifdef DEBUG_SUBSTITUTIONS
3634 std::cout<<"Duplicate across some trees: "
3653 tmp);remaining[a]i13
3667 t12{if(add.AddCollection
3669 a))==CollectionSetBase::xA2)c11}
3671 if(should_regenerate){
3672 #ifdef DEBUG_SUBSTITUTIONS
3673 std::cout<<"Before ConstantFolding_AddGrouping: "
3676 tree.DelParams();xH2
3679 j!=add.i8.end();++j)nG1&value=j
3685 tF3(fp_equal(coeff.xJ1,eS1(0)))y81
3686 if(fp_equal(coeff.xJ1,nY3{tree
3697 coeff);mul.Rehash(tT
3699 #ifdef DEBUG_SUBSTITUTIONS
3700 std::cout<<"After ConstantFolding_AddGrouping: "
3709 FPoptimizer_CodeTree;xG1
3710 ConstantFolding_IfOperations(tT3(tree.tU3()==cIf
3711 tI3()==i03);for(;;){l23
3755 xP2==cIf?cNotNot:cAbsNotNot);l53
3757 x03;ConstantFolding(l53)yJ
3759 xP2==cIf?cNotNot:cAbsNotNot);truth_b
3762 ConstantFolding(truth_b);if(l53
3890 nE==cIf?cNot:yR3);cN2
3933 nE;if(op1==op2){if(xW.cT1
4043 cOr)&&op2==cNotNot)nG1&l73=y9
4059 if(op2==cAdd||op2==cMul||(op2==cAnd
4081 if((op2==cAnd||op2==cOr)&&op1==cNotNot)nG1&l83=xW
4105 FPoptimizer_CodeTree;yV1
4107 maxFPExponent(){return
4117 xB3(0))||fp_equal(xB3(1))yI
4119 cE2>=eS1(maxFPExponent
4120 x8())/fp_log2(base);}
4122 ConstantFolding_PowOperations(tT3(tree.tU3()==cPow);y2){eS1
4125 tT.ReplaceWithImmed(const_value)l81
4128 fp_equal(y4,nY3{tree.xO2
4157 iW1,eS1(0)))break;if(!xR2){xR2=true;xX1
4165 #ifdef DEBUG_SUBSTITUTIONS
4166 std::cout<<"Before pow-mul change: "
4173 #ifdef DEBUG_SUBSTITUTIONS
4174 std::cout<<"After pow-mul change: "
4200 eD1,eS1(0)))break;if(!xR2){xR2=true;xX1
4212 tree.iE1));cD3.y12);tH
4231 c=a*b;if(isEvenInteger(a)&&!isEvenInteger(c))nG1
4249 FPoptimizer_CodeTree;e92
4251 cO2{MakeFalse=0,MakeTrue=1,t22=2,lC3=3,MakeNotNotP0=4,MakeNotNotP1=5,MakeNotP0=6,MakeNotP1=7,Unchanged=8
4253 iY1{Never=0,Eq0=1,Eq1=2,xD3=3,xR3=4}
4262 Analyze(lM1&a,lM1&b)const{if(a
4272 i0&&p1.iV2){if(p0.max<p1.min&&iZ1
4274 0];if(p0.max<=p1.min&&iZ1
4280 i0){if(p0.min>p1.max&&iZ1
4282 2];if(p0.min>=p1.max&&iZ1
4285 if(IsLogicalValue(a)){if(tS1
4292 if(IsLogicalValue(b)){if(tT1
4325 RangeComparisonsData{static
4384 lC3,l4::Unchanged,l4
4393 ConstantFolding_Comparison(eR{using
4395 RangeComparisonsData;assert(tree.tU3()>=cEqual&&tree.tU3()<=cGreaterOrEq);switch(Data[tree
4403 ReplaceWithImmed(0);nW
4452 cLessOrEq?cGreaterOrEq:cV2
4454 cGreaterOrEq?cLessOrEq:tree
4468 cTanh:if(fp_less(fp_abs(y4),nY3{tree.lR
4473 #include <algorithm>
4474 #ifdef FP_SUPPORT_OPTIMIZER
4477 #ifdef DEBUG_SUBSTITUTIONS
4487 #ifdef FP_SUPPORT_FLOAT_TYPE
4498 #ifdef FP_SUPPORT_LONG_DOUBLE_TYPE
4504 ld;e92{uint_least64_t
4514 #ifdef FP_SUPPORT_LONG_INT_TYPE
4524 FPoptimizer_CodeTree{lM
4534 #ifdef __GXX_EXPERIMENTAL_CXX0X__
4574 #ifdef DEBUG_SUBSTITUTIONS
4575 std::cout<<"Replacing "
4576 ;xE3(*this);if(IsImmed())OutFloatHex(std::cout,xJ1)lN1" with const value "
4577 <<i;OutFloatHex(std::cout,i)lN1"\n"
4584 ParamComparer{i12()(lM1&a,lM1&b)const{if(a.xT2!=b.xT2
4588 a.GetHash()<b.GetHash();}
4592 x8::Sort(){switch(Opcode
4626 AddParam(lM1¶m){xY
4633 yK2());xY.back().swap(param);}
4652 nK){xY.insert(xY.end(),l02.i62
4655 AddParamsMove(nK){size_t
4660 endpos+added,yK2());for(size_t
4661 p=0;p<added;++p)xY[endpos+p
4665 AddParamsMove(nK,size_t
4670 l12);AddParamsMove(eU1}
4679 SetParamsMove(nK){xY.swap(eU1
4681 #ifdef __GXX_EXPERIMENTAL_CXX0X__
4684 nV1&&l02){SetParamsMove(eU1}
4691 #ifdef __GXX_EXPERIMENTAL_CXX0X__
4696 c93[index].data=0;for(size_t
4699 p)c93[p].data.UnsafeSetP(&*c93[p+1
4701 c93[nF3-1].data.UnsafeSetP(0);iC2
4706 DelParams(){xY.clear();}
4708 yK2::IsIdenticalTo(lM1&b)const{if(&*data==&*b.data
4712 data->IsIdenticalTo(*b.data);}
4718 x8&b)const{if(Hash!=b.Hash
4725 fp_equal(Value,t53;case
4730 cPCall:if(iJ1!=b.iJ1
4744 Become(lM1&b){if(&b!=this&&&*data!=&*b.data){DataP
4749 CopyOnWrite(){if(GetRefCount()>1)data=new
4754 yK2::GetUniqueRef(){if(GetRefCount()>1
4756 yK2(*this,CloneTag())l81*this;}
4765 t53,iJ1(b.iJ1),c93(b.c93),Hash(b.Hash),Depth(b.Depth),eZ1
4773 #ifdef __GXX_EXPERIMENTAL_CXX0X__
4780 t53),iJ1(b.iJ1),c93(t72
4781 b.c93)),Hash(b.Hash),Depth(b.Depth),eZ1
4800 l43),iJ1(f),c93(),Hash(),Depth(1),eZ1
4804 #ifdef FP_SUPPORT_OPTIMIZER
4811 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
4814 cA3,eH3&done,std::ostream&o){for
4818 done,o);std::ostringstream
4819 buf;xE3(tree,buf);done[tree.GetHash()].insert(buf.str());}
4823 FPoptimizer_CodeTree{
4824 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
4829 done;l22(tree,done,o);for(eH3::const_iterator
4831 i!=done.end();++i){const
4832 std::set<std::string>&flist=i
4834 yA3!=1)o<<"ERROR - HASH COLLISION?\n"
4835 ;for(std::set<std::string>::const_iterator
4837 j!=flist.end();++j){o<<'['<<std::hex<<i->first.hash1<<','<<i->first.hash2<<']'<<std::dec;o<<": "
4852 <<(tree.GetVar()-iE2)l81;case
4862 ;break;default:tN3;o<<FP_GetOpcodeName
4865 cPCall)o<<':'<<tree.GetFuncNo();}
4866 o<<'(';if(iT<=1&&sep2[1])o<<(sep2+1)<<' 'eV3
4869 o);if(a+1<iT)o<<sep2;}
4875 std::string&indent){o<<'['<<std::hex<<(void*)(&tree.iE1))<<std::dec<<','<<tree.GetRefCount()<<']';o<<indent<<'_';switch
4879 <<yZ3;o<<'\n'l81;case
4881 <<(tree.GetVar()-iE2);o<<'\n'l81;default:o<<FP_GetOpcodeName
4884 cPCall)o<<':'<<tree.GetFuncNo();o<<'\n';}
4887 ind=indent;for(size_t
4889 yA3;p+=2)if(ind[p]=='\\')ind[p]=' ';ind+=(a+1<iT)?" |"
4911 xH&a=*(xH*)aa;xH&b=*(xH*)bb
4915 t42&&a.index==b.index&&a.depcode==b.depcode
4917 NumConstant:{eZ&a=*(eZ*)aa;eZ&b=*(eZ*)bb
4919 fp_equal(a.xZ3,b.xZ3)&&a.modulo==b.modulo
4921 xI&a=*(xI*)aa;xI&b=*(xI*)bb
4925 t42&&a.cS==b.cS&&a.data.match_type==b.data.match_type&&a.data
4927 xY2&&a.data.param_list==b.data.param_list&&a.data.n2==b.data.n2&&a.depcode==b.depcode;}
4932 ParamSpec_GetDepCode
4934 cG2&b){switch(b.first
4956 std::ostream&o){static
4959 ParamHolderNames[][2]={"%"
4973 eZ*x01;o.precision(12);o<<xF3
4978 xH*x01;o<<ParamHolderNames[xF3
4997 opcode=FP_GetOpcodeName((nR2)xF3
5001 a)opcode[a]=(char)std::toupper(opcode[a]);o<<opcode<<"( "
5006 else{o<<'('<<FP_GetOpcodeName((nR2)xF3
5008 PositionalParams)o<<'[';yZ
5009 SelectedParams)o<<'{';n3
5015 PositionalParams)o<<"]"
5017 SelectedParams)o<<"}"
5020 yN3(ImmedConstraint_Value(tX1
5026 Value_OddInt:o<<"@O"
5030 Value_NonInteger:o<<"@F"
5034 ImmedConstraint_Sign(tX1
5042 ImmedConstraint_Oneness(tX1
5048 Oneness_NotOne:o<<"@M"
5050 ImmedConstraint_Constness(tX1
5053 yL1:if(lF3.first==ParamHolder){yK3&t82
5059 Constness_NotConst:o<<"@V"
5066 count,std::ostream&o){for
5068 a=0;a<count;++a){if(a>0)o<<' ';const
5070 x8(paramlist,a);DumpParam
5072 depcode=ParamSpec_GetDepCode(param);if(depcode!=0)o<<"@D"
5076 #include <algorithm>
5081 plist_p[36]={{2,0,0x0}
5087 n02|Constness_NotConst,0x0}
5092 ,{3,Sign_NoIdea,0x0}
5096 ,{3,Value_OddInt,0x0}
5097 ,{3,Value_NonInteger,0x0}
5100 ,{0,n02|n0{0,n0{0,nJ1|n0{0,n12|n0{0,yL1,0x1}
5101 ,{0,t01|nJ1|n0{0,t11
5104 n0{0,Oneness_One|n0{0,eE1|n0{1,n0{1,n12|n0{1,t11
5105 n0{1,t01|n0{1,nJ1|n0{6,0,0x0}
5112 plist_n_container{static
5120 x8::plist_n[19]={{eS1(-2
5148 x8(),xL1{eS1(0),xL1{fp_const_pihalf
5149 x8(),xL1{fp_const_pi
5153 plist_s[464]={{{1,15,tC2
5154 15,cNeg,GroupFunction,0}
5407 365609,lI,222257,lI,365617,lI,366633,lI,366641,lI,48128,lI,15,lI,15,cV1
5408 16,lI,10240,lI,11264,lI,7170,lI,7168,lI,7168,y0
5410 17408,lI,19456,lI,16384,lI,15360,lI,27648,lI,30720,lI,30722,lI,24,tF2
5413 24,lI,7192,lI,68608,lI,83968,lI,86040,lI,87040,lI,88064,lI,90112,lI,432128,lI,433152,lI,37895,lI,14342,lI,25607,lI,7183,lI,56327,lI,114703,lI,114718,lI,257024,lI,419840,lI,260103,lI,37953,tF2
5424 38991,lI,44111,lI,44135,lI,44124,y0
5425 44136,lI,48240,lI,60693,lI,38253,y0
5436 38292,lI,38294,lI,38300,lI,38301,lI,38312,y0
5439 38332,lI,38341,lI,38341,y0
5440 38343,lI,60,lI,60,tF2
5444 48552,lI,257198,lI,260274,lI,24792,lI,7172,cPow,PositionalParams,0}
5618 256216,cLessOrEq,tG2
5648 0,0,cAnd,AnyParams,1}
5684 grammar_rules[253]={{ProduceNewTree,1,1,0,{1,0,cAbs,xJ
5730 403,{1,114,cFloor,eL3
5745 460,{3,381020637,cIf
5747 0,3,31492569,{3,35682779,cIf
5749 0,3,31492575,{3,35682785,cIf,xJ
5767 427009,cMin,AnyParams,0}
5769 ,{ProduceNewTree,0,1,203
6053 70674,cMul,SelectedParams,0
6310 511,{1,5,cAnd,AnyParams,1
6329 393702,cAnd,AnyParams,0
6331 0,2,479697,{3,489115088,cAnd
6352 136197,cOr,AnyParams,0}
6354 ,{ProduceNewTree,0,1,517,{1,2,xJ3
6360 482,{1,228,cAbsNotNot,AnyParams,0
6362 476,{1,227,cAbsNotNot,AnyParams,0}
6364 ,{ProduceNewTree,0,1,383,{3,31464955,eP3
6370 0,3,31492569,{3,35682779,eP3
6375 grammar_optimize_abslogical_type{xS
6378 grammar_optimize_abslogical_type
6379 grammar_optimize_abslogical={9,{21,183,219,228,231,237,244,249,252}
6383 grammar_optimize_ignore_if_sideeffects_type{xS
6386 grammar_optimize_ignore_if_sideeffects_type
6387 grammar_optimize_ignore_if_sideeffects={59,{0,20,22,23,24,25,26,27,cV
6391 grammar_optimize_nonshortcut_logical_evaluation_type{xS
6394 grammar_optimize_nonshortcut_logical_evaluation_type
6395 grammar_optimize_nonshortcut_logical_evaluation={56,{0,26,cV
6398 158,167,168,169,178,179,191,195,203,207,215,227,229,230,232,233,234,235,236,238,239,240,241,242,243,245,246,247,248,250,251}
6402 grammar_optimize_round1_type{xS
6405 grammar_optimize_round1_type
6406 grammar_optimize_round1={118,{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,18,26,cV
6408 45,46,47,48,49,50,51,52,53,54,58,59,60,61,62,63,64,65,66,67,68,69,70,71,78,79,80,81,82,83,88,89,90,91,92,93,94,95,96,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,132,xR
6409 grammar_optimize_round2_type{xS
6412 grammar_optimize_round2_type
6413 grammar_optimize_round2={100,{0,15,16,17,26,cV
6415 45,46,47,48,49,50,51,52,53,54,59,60,72,73,78,79,84,85,86,87,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,117,118,119,120,121,122,123,124,125,126,127,128,133,157,xR
6416 grammar_optimize_round3_type{xS
6419 grammar_optimize_round3_type
6420 grammar_optimize_round3={79,{74,75,76,77,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,159,160,161,162,163,164,165,166,170,171,172,173,174,175,176,177,180,181,182,184,185,186,187,188,189,190,192,193,194,196,197,198,199,200,201,202,204,205,206,208,209,210,211,212,213,214,216,217,218,220,221,222,223,224,225,226}
6424 grammar_optimize_round4_type{xS
6427 grammar_optimize_round4_type
6428 grammar_optimize_round4={10,{19,55,56,57,130,131,153,154,155,156}
6432 grammar_optimize_shortcut_logical_evaluation_type{xS
6435 grammar_optimize_shortcut_logical_evaluation_type
6436 grammar_optimize_shortcut_logical_evaluation={53,{0,26,cV
6439 158,167,168,169,178,179,191,195,203,207,215,227,229,232,233,234,235,236,239,240,241,242,245,246,247,248,250,251}
6448 paramlist,lC1){index=(paramlist>>(index*10))&1023;if(index>=55
6452 plist_s[index-55]);if(index>=36
6457 x8::plist_n[index-36])l81
6462 #ifdef FP_SUPPORT_OPTIMIZER
6464 #include <algorithm>
6472 FPoptimizer_CodeTree;using
6474 FPoptimizer_Optimize;iO2{nT1
6483 len=last-first;while(len>0){size_t
6486 n43(first);n43+=half;if(comp(*n43,val)){first=n43;++first;len=len-half-1;}
6488 comp(val,*n43)){len=half;}
6490 left(first);{It&cR2=left;It
6492 len2=last2-cR2;while(len2>0){size_t
6494 middle2(cR2);middle2+=half2;if(comp(*middle2,val)){cR2=middle2;++cR2;len2=len2-half2-1;}
6499 right(++n43);{It&cR2=right;It&last2=first;size_t
6500 len2=last2-cR2;while(len2>0){size_t
6502 middle2(cR2);middle2+=half2;if(comp(val,*middle2))len2=half2;else{cR2=middle2;++cR2;len2=len2-half2-1;}
6511 OpcodeRuleCompare{i12()(lM1&tree,i02
6513 Rule&rule=grammar_rules[xW2]l81
6516 nT2.subfunc_opcode;}
6521 Rule&rule=grammar_rules[xW2]l81
6523 nT2.subfunc_opcode<tree
6527 TestRuleAndApplyIfMatch
6533 found(false,e1());if((rule.eL1
6534 LogicalContextOnly)&&!cD{yR2
6537 x8::result){if(rule.eL1
6542 #ifdef DEBUG_SUBSTITUTIONS
6544 found=TestParams(rule
6545 nT2,tree,found.specs,info,true);if(found.found)break;if(!&*found.specs){fail:;
6546 #ifdef DEBUG_SUBSTITUTIONS
6551 #ifdef DEBUG_SUBSTITUTIONS
6558 FPoptimizer_Optimize{xG1
6561 Grammar&tN2,yK2&tree,bool
6562 cD{if(tree.GetOptimizedUsing()==&tN2){
6563 #ifdef DEBUG_SUBSTITUTIONS
6564 std::cout<<"Already optimized: "
6585 i03:if(ApplyGrammar(tN2,e72,cV2
6597 if(changed){tree.Mark_Incompletely_Hashed()nS2}
6601 char*lE3;std::pair<lE3,lE3>range=MyEqualRange(tN2.rule_list,tN2.rule_list+tN2.rule_count,tree,OpcodeRuleCompare
6605 #ifdef DEBUG_SUBSTITUTIONS
6607 char>rules;rules.nH3
6610 if(IsLogisticallyPlausibleParamsMatch(cW1
6615 range.first=&rules[0];range
6617 yA3-1]+1;if(range.eQ3
6619 eE3){std::cout<<"Input ("
6624 std::cout<<"(Logical)"
6626 first=i21,prev=i21;const
6629 if(first==i21)first=prev=*r;tP1*r==prev+1)prev=*r;else{std::cout<<sep<<first;sep=","
6630 ;if(prev!=first)std::cout<<'-'<<prev;first=prev=*r;}
6633 i21){std::cout<<sep<<first;if(prev!=first)std::cout<<'-'<<prev;}
6642 #ifndef DEBUG_SUBSTITUTIONS
6643 if(!IsLogisticallyPlausibleParamsMatch(cW1
6648 if(TestRuleAndApplyIfMatch(cW1,tree,cD){yI1
6651 #ifdef DEBUG_SUBSTITUTIONS
6652 std::cout<<"Changed."
6658 tree.Mark_Incompletely_Hashed()nS2}
6659 tree.SetOptimizedUsing(&tN2)l81
6663 #ifdef DEBUG_SUBSTITUTIONS
6665 tJ3"grammar_optimize_round1\n"
6669 grammar_optimize_round1
6671 #ifdef DEBUG_SUBSTITUTIONS
6673 tJ3"grammar_optimize_round2\n"
6677 grammar_optimize_round2
6679 #ifdef DEBUG_SUBSTITUTIONS
6681 tJ3"grammar_optimize_round3\n"
6685 grammar_optimize_round3
6687 #ifndef FP_ENABLE_SHORTCUT_LOGICAL_EVALUATION
6688 #ifdef DEBUG_SUBSTITUTIONS
6690 tJ3"grammar_optimize_nonshortcut_logical_evaluation\n"
6694 grammar_optimize_nonshortcut_logical_evaluation
6697 #ifdef DEBUG_SUBSTITUTIONS
6699 tJ3"grammar_optimize_round4\n"
6703 grammar_optimize_round4
6705 #ifdef FP_ENABLE_SHORTCUT_LOGICAL_EVALUATION
6706 #ifdef DEBUG_SUBSTITUTIONS
6708 tJ3"grammar_optimize_shortcut_logical_evaluation\n"
6712 grammar_optimize_shortcut_logical_evaluation
6715 #ifdef FP_ENABLE_IGNORE_IF_SIDEEFFECTS
6716 #ifdef DEBUG_SUBSTITUTIONS
6718 tJ3"grammar_optimize_ignore_if_sideeffects\n"
6722 grammar_optimize_ignore_if_sideeffects
6725 #ifdef DEBUG_SUBSTITUTIONS
6727 tJ3"grammar_optimize_abslogical\n"
6731 grammar_optimize_abslogical
6737 #ifdef FP_SUPPORT_OPTIMIZER
6738 #include <algorithm>
6742 #include <memory> /* for auto_ptr */
6748 FPoptimizer_CodeTree;using
6750 FPoptimizer_Optimize;iO2{xG1
6751 TestImmedConstraints
6754 eR{switch(bitmask&ValueMask
6758 n12:if(GetEvennessInfo
6761 Value_OddInt:if(GetEvennessInfo
6764 t01:if(GetIntegerInfo
6767 Value_NonInteger:if(GetIntegerInfo
6770 eE1:if(!IsLogicalValue(tree)yI
6788 if(!fp_equal(fp_abs(yZ3),eS1(1))yI
6790 Oneness_NotOne:if(!cW2
6791 if(fp_equal(fp_abs(yZ3),eS1(1))yI
6798 Constness_NotConst:if(cW2
6807 nbitmap{private:static
6810 bits_in_char=8;static
6814 cS2)*bits_in_char)/nbits;cS2
6815 data[(extent+cT2-1)/cT2];e13
6818 by=1){data[pos(index)]+=by*cS2(1<<xX2);i6
6820 dec(lC1){inc(index,-1);}
6823 n61(data[pos(index)]>>xX2)&mask()xJ2
6828 nbits*(index%cT2)xJ2
6829 mask(){return(1<<nbits)-1
6839 cG3:8;nbitmap<iE2,2>SubTreesDetail;c83(){std::memset(this,0,xK3*this));}
6842 c83&b){std::memcpy(this,&b,xK3
6845 c83&b){std::memcpy(this,&b,xK3
6850 CreateNeedList_uncached(t0&cB2){c83
6856 x8(cB2.param_list,a);xT3
6861 GroupFunction)++tA3;else{++tA2;assert(param.data.subfunc_opcode<VarBegin);x11.SubTreesDetail.inc
6867 ParamHolder:++t92;++x11.i31;nM3}
6871 c83&CreateNeedList(t0&cB2){typedef
6872 std::map<t0*,c83>cX1;static
6875 i=yO1.xE2&cB2);if(i!=yO1.cP1&cB2
6880 yO1.nT3,std::make_pair(&cB2,CreateNeedList_uncached
6884 CalculateGroupFunction
6901 info.GetParamHolderValueIfFound
6919 tmp(CalculateGroupFunction(e01
6922 data.param_list,a),info));result
6933 FPoptimizer_Optimize{xG1
6934 IsLogisticallyPlausibleParamsMatch(t0&cB2,const
6938 eR3=iT;if(eR3<size_t(x11.i31)){nX2
6945 cImmed:if(tA3>0)--tA3;else--t92;lC
6948 cPCall:--t92;break;default:assert(opcode<VarBegin);if(tA2>0&&x11.SubTreesDetail.get(opcode)>0){--tA2;x11.SubTreesDetail.dec(opcode);}
6951 if(tA3>0||tA2>0||t92>0){nX2
6952 if(cB2.match_type!=AnyParams){if(0||tA2<0||t92<0){nX2}
6973 Modulo_Radians:imm=fp_mod(imm,y8
6977 x8())imm-=fp_const_twopi
6986 info.SaveOrTestParamHolder
6992 GroupFunction){if(!x0
6994 xO1=CalculateGroupFunction(xZ2
6996 #ifdef DEBUG_SUBSTITUTIONS
6997 DumpHashes(xO1)lN1*i01
7003 ;DumpHashes(tree)lN1"Comparing "
7017 else{if(!&*start_at){if(!x0
7025 data,tree,start_at,info,false);}
7034 info;iS()yC3,info(){}
7037 MatchPositionSpec_PositionalParams:xP1
7041 MatchPositionSpec_PositionalParams(xL3):xM3
7066 info,yG<bool>&used,bool
7076 iT;++a){if(used[a])y81
7087 retry_anywhere_2:if(&*lV1){goto
7096 info;yG<bool>used;iF2
7098 eR3)yC3,info(),used(eR3){}
7101 MatchPositionSpec_AnyParams:xP1
7105 MatchPositionSpec_AnyParams(xL3,size_t
7113 TestParams(t0&nM,lM1&tree
7117 tA1{if(nM.match_type!=AnyParams){if(xT!=iT
7119 if(!IsLogisticallyPlausibleParamsMatch(nM
7121 switch(nM.match_type
7123 PositionalParams:{xN<cL>x6;i02
7132 xT;++a){cX2=info;retry_positionalparams:{lZ1
7138 lD1:if(&*lV1){info=cX2;goto
7139 retry_positionalparams;}
7152 AnyParams:{xN<t6>x6;yG<bool>used(iT);yG<i02>iG2(xT);yG<i02>y02(xT)lO1{const
7155 a);iG2[a]=ParamSpec_GetDepCode(lF3);}
7159 if(iG2[a]!=0)y02[b++]=a
7161 if(iG2[a]==0)y02[b++]=a;}
7171 t6(xT,iT);a=0;if(xT!=0){(*x6)[0].info=info;(*x6)[0].used=used;}
7174 xT;++a){if(a>0){cX2=info;(*x6)[a].used=used;}
7175 retry_anyparams:{lZ1
7176 r=TestParam_AnyWhere
7182 cY1:if(&*lV1){info=cX2;used=(*x6)[a].used;goto
7184 cZ1:if(a>0){--a;goto
7189 retry_anyparams_4:if(nM.n2!=0){if(!TopLevel||!info.HasRestHolder(nM.n2)){yG
7193 b=0;b<iT;++b){if(xN3)y81
7201 if(!info.SaveOrTestRestHolder(nM.n2,yS2)){goto
7204 else{lL1&yS2=info.GetRestHolderValues(nM.n2)c23
7210 b=0;b<iT;++b){if(xN3)y81
7214 b))){xN3=true;if(tA1
7223 lZ1(true,xT?&*x6:0)cM3
7227 #ifdef FP_SUPPORT_OPTIMIZER
7228 #include <algorithm>
7232 FPoptimizer_CodeTree;using
7234 FPoptimizer_Optimize;iO2{yV1
7253 info.GetParamHolderValue
7270 data.param_list,a),info,true
7278 trees(info.GetRestHolderValues
7280 data.n2)tT.AddParamsMove(trees);if(iT==1){assert(tree.tU3()==cAdd tI3()==cMul tI3()==cMin tI3()==cMax tI3()==cAnd tI3()==cOr tI3()==cAbsAnd tI3()==cAbsOr);tree.xO2
7302 FPoptimizer_Optimize{xB1
7306 info){switch(rule.ruletype
7308 ProduceNewTree:{tree.Become(xQ1
7313 ReplaceParams:default:{yG<i02>list=info.GetMatchedParamIndexes();std::sort(list.i62
7318 a=0;a<rule.repl_param_count;++a)nG1
7330 #ifdef DEBUG_SUBSTITUTIONS
7338 FPoptimizer_CodeTree;using
7340 FPoptimizer_Optimize;iO2
7347 DidMatch,std::ostream&o){DumpMatch
7348 t81,DidMatch?tZ3"match"
7357 char*eY3,std::ostream&o){static
7360 ParamHolderNames[][2]={"%"
7370 <<(&rule-grammar_rules)<<")"
7373 tmp;tmp.first=SubFunction;xI
7377 void*)&tmp2;DumpParam
7379 o<<"\n Replacement: "
7382 rule.repl_param_count,o);o<<"\n"
7384 ;xE3(tree,o);o<<"\n"
7385 ;if(!std::strcmp(eY3,tZ3"match"
7386 ))DumpHashes(tree,o)c23
7392 <<ParamHolderNames[a]<<" = "
7393 ;xE3(i33[a],o);o<<"\n"
7408 second[a],o);o<<std::endl;}
7414 #include <algorithm>
7415 #ifdef FP_SUPPORT_OPTIMIZER
7418 MarkIncompletes(x2){if(tree.Is_Incompletely_Hashed(iF1;bool
7423 i51|=MarkIncompletes
7425 a));if(i51)tree.Mark_Incompletely_Hashed()l81
7428 FixIncompletes(x2){if(tree.Is_Incompletely_Hashed()){for
7437 FPoptimizer_CodeTree{lA
7442 constantfolding){if(constantfolding)ConstantFolding(*this);else
7453 value=Value;eB=crc32::calc(i01
7456 value));key^=(key<<24);
7471 data;memset(&data,0,xK3
7472 data));data.buf2.v=Value;eB=data.buf1.key;
7476 lQ2=std::frexp(Value,&cE2);eB=iL1(cE2+0x8000)&0xFFFF);if(lQ2<0){lQ2=-lQ2;key=key^0xFFFF;}
7478 key+=0x10000;lQ2-=yF3;key<<=39;key|=iC1((lQ2+lQ2)*eS1(1u<<31))<<8;
7482 #ifdef FP_SUPPORT_LONG_INT_TYPE
7489 #ifdef FP_SUPPORT_GMP_INT_TYPE
7498 x8::Recalculate_Hash_NoRecursion(){fphash_t
7499 iU(iC1(Opcode)<<56,Opcode*tM3(0x1131462E270012B));Depth=1;switch(Opcode
7501 cImmed:{ImmedHashGenerator
7502 x8::MakeHash(iU,Value
7506 eC2((eC)*11)^tM3(0x3A83A83A83A83A0);nM3
7510 eC2((~eC)*7)^3456789;}
7516 a){if(c93[a].xT2>eM1)eM1=c93[a].xT2;nP3+=((c93[a]eE2
7517 hash1*(a+1))>>12)eC2
7520 eC2(3)*tM3(0x9ABCD801357);iU.hash2*=tM3(0xECADB912345)eC2(~c93[a]eE2
7524 if(Hash!=iU){Hash=iU;iK1=0;}
7527 FixIncompleteHashes(){MarkIncompletes(*this);FixIncompletes(*this);}
7533 #ifdef FP_SUPPORT_OPTIMIZER
7537 FPoptimizer_CodeTree;xG1
7543 x8&eQ,yW2&synth,size_t
7544 max_bytecode_grow_length);static
7547 SinCosTanDataType{OPCODE
7549 inverse_opcode;enum{nominator,denominator,inverse_nominator,inverse_denominator}
7552 SinCosTanData[12]={{cTan,cCot,{cSin,cCos,cCsc,cSec}
7554 ,{cCot,cCot,{cCos,cSin,cSec,cCsc}
7556 ,{cCos,cSec,{cSin,cTan,cCsc,cCot}
7558 ,{cSec,cCos,{cTan,cSin,cCot,cCsc}
7560 ,{cSin,cCsc,{cCos,cCot,cSec,cTan}
7562 ,{cCsc,cSin,{cCot,cCos,cTan,cSec}
7565 yY2,{cSinh,cNop,{yT2
7573 cSinh,yY2,{cNop,cSinh,{cNop,cTanh,cH3
7576 ,{cNop,cH3{cTanh,cSinh,yY2}
7579 FPoptimizer_CodeTree{lA
7580 SynthesizeByteCode(yG<i02>&nN,yG
7581 x8&Immed,size_t&stacktop_max){
7582 #ifdef DEBUG_SUBSTITUTIONS
7583 std::cout<<"Making bytecode for:\n"
7586 while(RecreateInversionsAndNegations()){
7587 #ifdef DEBUG_SUBSTITUTIONS
7588 std::cout<<"One change issued, produced:\n"
7591 FixIncompleteHashes();}
7592 #ifdef DEBUG_SUBSTITUTIONS
7593 std::cout<<"Actually synthesizing, after recreating inv/neg:\n"
7597 synth;SynthesizeByteCode(synth,false
7598 eU3.Pull(nN,Immed,stacktop_max);}
7600 SynthesizeByteCode(yW2&synth,bool
7601 MustPopTemps)const{xR1*this)){return;}
7605 SinCosTanDataType&data=SinCosTanData[a];if(data.whichopcode!=cNop){if(lM2!=data.whichopcode)y81
7610 data.inverse_opcode);lJ3.y12);xR1
7612 else{if(lM2!=cInv)y81
7613 if(GetParam(0)nE!=data.inverse_opcode)y81
7615 GetParam(0))){synth.l21
7619 tree;if(data.t03]==cNop){tH
7624 data.t03^2]);lK3.y12
7631 tree.y12);found[b]t13
7633 if(found[data.y22!=tG
7662 n_subexpressions_synthesized=SynthCommonSubExpressions(synth);switch(lM2
7664 iE2:synth.PushVar(GetVar());lC
7674 cAbsOr:{if(lM2==cMul){bool
7679 y21&&isLongInteger(lT1.xJ1)){yW1=makeLongInteger(lT1.xJ1);yL2
7681 yL2::CloneTag());tmp
7687 x8::AddSequence,synth,MAX_MULI_BYTECODE_LENGTH)){xU3=true;nM3}
7691 yA1=0;yG<bool>done(GetParamCount(),false);yL2
7699 if(synth.IsStackTop(lT1)){found=true;done[a]=true;lT1.nB
7702 lT1);if(++yA1>1){synth
7715 lT1);if(++yA1>1){synth
7721 if(yA1==0){switch(lM2
7733 0);break;default:nM3++yA1;}
7734 assert(n_stacked==1);nM3
7748 x8::MulSequence,synth,MAX_POWI_BYTECODE_LENGTH)){p0.nB
7756 yJ2;GetParam(0)t33.SynthIfStep1(yJ2,lM2);GetParam(1)t33.SynthIfStep2(yJ2);GetParam(2)t33.SynthIfStep3(yJ2
7765 iL1)GetParamCount());lK1
7773 iL1)GetParamCount()nW2}
7774 synth.yZ2*this);if(MustPopTemps&&n_subexpressions_synthesized>0){size_t
7777 GetStackTop(eU3.DoPopNMov(top-1-n_subexpressions_synthesized,top-1);}
7786 x8&eQ,yW2&synth,size_t
7787 max_bytecode_grow_length){if
7789 backup=synth;tree.nB
7793 GetByteCodeSize();yV2
7798 bytecode_grow_amount
7800 GetByteCodeSize()-bytecodesize_backup;if(bytecode_grow_amount>max_bytecode_grow_length){synth=backup
7812 #ifdef FP_SUPPORT_OPTIMIZER
7816 FPoptimizer_CodeTree;
7817 #define FactorStack yG
7826 iseq_powi={cSqr,cMul,cInv,cSqrt,cRSqrt}
7827 ,iseq_muli={i21,cAdd,cNeg,i21,i21}
7831 PowiMuliType&xV3,const
7832 yG<i02>&nA2,l92&stack){eS1
7834 1);while(IP<limit){if(xW3
7835 xV3.opcode_square){if(!eY2
7838 opcode_invert){result=-result;e4
7839 opcode_half){if(result>eS1(0)&&isEvenInteger(cZ3
7841 opcode_invhalf){if(result>eS1(0)&&isEvenInteger(cZ3
7846 cFetch){lC1=yL3;if(index<y1||size_t(index-y1)>=stack
7848 lhs=stack[index-y1];goto
7851 cDup){lhs=result;goto
7857 if(IP>=limit||nN[IP]!=xV3.opcode_cumulate){IP=nB2;nM3++IP;stack.pop_back();result+=lhs*subexponent;y81}
7880 CodeTreeParserData{e13
7882 CodeTreeParserData(bool
7883 k_powi):stack(),clones(),keep_powi(k_powi){}
7894 cB2);if(!keep_powi)switch(opcode
7963 n83(p1.GetParamCount())c23
7983 xK.Rehash(!keep_powi);i71,false);
7984 #ifdef DEBUG_SUBSTITUTIONS
7986 <<FP_GetOpcodeName(opcode)<<"->"
7987 <<FP_GetOpcodeName(xK
8001 x8(opcode,funcno);yG
8006 #ifdef DEBUG_SUBSTITUTIONS
8016 xX3=CodeTreeImmed(value);i71);Push(xK
8022 x8(varno);i71);Push(xK
8024 SwapLastTwoInStack(){y73
8034 which){Push(stack[which]);}
8039 #ifdef DEBUG_SUBSTITUTIONS
8049 source){stack[target]=stack[source];stack
8053 y42{clones.clear()yJ
8055 stack.back());stack.resize
8066 n=0;n<n_pop;++n)result[n
8070 #ifdef DEBUG_SUBSTITUTIONS
8071 for(xL3=n_pop;n-->0;){lC2;xE3(result[n])tW
8083 FindClone(yK2&,bool=true){return;}
8086 stack;std::multimap<fphash_t,yK2>clones;bool
8087 keep_powi;private:CodeTreeParserData
8089 CodeTreeParserData&);CodeTreeParserData&e31=i01
8090 CodeTreeParserData&);}
8097 endif_location;IfInfo():cU2(),thenbranch(),endif_location(){}
8101 FPoptimizer_CodeTree{lA
8113 cJ3.mVariablesAmount)xS3
8114 n=0;n<cJ3.mVariablesAmount;++n){nK2
8118 GenerateFrom(nN,Immed,cJ3,nK2,keep_powi);}
8131 #ifdef DEBUG_SUBSTITUTIONS
8132 std::cout<<"ENTERS GenerateFrom()\n"
8137 sim(keep_powi);yG<IfInfo
8139 IP=0,DP=0;;++IP){tO2:while(!eN
8140 cQ3&&(eN.eD==IP||(IP<nN
8142 cJump&&eN.e11.iA1)){yL2
8148 3,cIf);eN.pop_back();}
8151 opcode=nN[IP];if((opcode==cSqr||opcode==cDup||(opcode==cInv&&!IsIntType
8152 x8::result)||opcode==cNeg||opcode==cSqrt||opcode==cRSqrt||opcode==cFetch)){size_t
8154 cE2=ParsePowiSequence
8161 if(opcode==cDup||opcode==cFetch||opcode==cNeg){eS1
8162 xD2=ParseMuliSequence
8172 if(lD2>=iE2){sim.Push(nK2[opcode-iE2]);}
8180 res(sim.y42);eN.back().cU2.swap(res);eN.eD=nN
8184 res(sim.y42);eN.e11.swap(res);eN.eD=nN[IP+1]+1;IP+=2;y81}
8191 funcno=yL3;assert(funcno<fpdata.mFuncPtrs.size());i02
8194 mParams;sim.EatFunc(cB2,lD2,funcno
8198 funcno=yL3;assert(funcno<fpdata.tQ3.size());const
8205 mParams;yG<yL2>paramlist=sim.Pop(cB2);yL2
8206 tP2;tP2.GenerateFrom(p.mData->mByteCode,p.mData->mImmed,*p.mData,paramlist)yG3
8287 cSinCos:sim.Dup();yE3
8330 cFetch:sim.Fetch(yL3);lC
8332 stackOffs_target=yL3;i02
8333 stackOffs_source=yL3;sim.PopNMov(stackOffs_target,stackOffs_source
8335 #ifndef FP_DISABLE_EVAL
8338 paramcount=cJ3.mVariablesAmount;iJ
8343 funcno=opcode-cAbs;assert(funcno<FUNC_AMOUNT);const
8344 FuncDefinition&func=Functions[funcno];iJ
8349 #ifdef DEBUG_SUBSTITUTIONS
8350 std::cout<<"Produced tree:\n"
8356 #include <algorithm>
8357 #ifdef FP_SUPPORT_OPTIMIZER
8359 #define FP_MUL_COMBINE_EXPONENTS
8363 FPoptimizer_CodeTree;yV1
8366 AdoptChildrenWithSameOpcode(eR{
8367 #ifdef DEBUG_SUBSTITUTIONS
8378 #ifdef DEBUG_SUBSTITUTIONS
8379 if(!lR2){std::cout<<"Before assimilation: "
8385 a).GetUniqueRef().iE1),a);}
8386 #ifdef DEBUG_SUBSTITUTIONS
8387 if(lR2){std::cout<<"After assimilation: "
8393 FPoptimizer_CodeTree{xB1
8394 ConstantFolding(eR{tree.Sort();
8395 #ifdef DEBUG_SUBSTITUTIONS
8398 <<(&yM3)<<"]Runs ConstantFolding for: "
8402 if(false){redo:;tree.Sort();
8403 #ifdef DEBUG_SUBSTITUTIONS
8405 <<(&yM3)<<"]Re-runs ConstantFolding: "
8419 if(false){ReplaceTreeWithOne
8421 ReplaceWithImmed(eS1(1));goto
8422 do_return;ReplaceTreeWithZero
8424 ReplaceWithImmed(eS1(0));goto
8425 do_return;ReplaceTreeWithParam0:
8426 #ifdef DEBUG_SUBSTITUTIONS
8427 std::cout<<"Before replace: "
8433 hash2<<']'<<std::dec
8438 #ifdef DEBUG_SUBSTITUTIONS
8439 std::cout<<"After replace: "
8445 hash2<<']'<<std::dec
8474 cAnd?cNotNot:cAbsNotNot);e5
8476 xU2==cAnd||!cE)if(ConstantFolding_AndLogic
8499 cOr?cNotNot:cAbsNotNot);e5
8501 xU2==cOr||!cE)if(ConstantFolding_OrLogic
8530 yR3;break;default:nM3
8532 OPCODE(opposite)tT.SetParamsMove
8534 0).GetUniqueRef().iE1));e5
8543 xU2==cNot&&GetPositivityInfo
8559 nE==cNot?cNotNot:cAbsNotNot);tQ2
8571 nE==cNot?cNotNot:cAbsNotNot);yT3
8586 xU2==cNotNot&&GetPositivityInfo
8600 cG1{tree.SetParam(0,iH2
8619 i03:{if(ConstantFolding_IfOperations
8623 cMul:{NowWeAreMulGroup:;AdoptChildrenWithSameOpcode(tree);eS1
8631 immed=xI2.xJ1;if(immed==eS1(0))tZ
8633 if(i81>1||(i81==1&&fp_equal(nN1,nY3)nO1=true;if(nO1){
8634 #ifdef DEBUG_SUBSTITUTIONS
8635 std::cout<<"cMul: Will add new "
8645 #ifdef DEBUG_SUBSTITUTIONS
8646 std::cout<<" - For that, deleting "
8652 lM3!fp_equal(nN1,nY3
8661 default:if(ConstantFolding_MulGrouping
8663 if(ConstantFolding_MulLogicItems
8676 immed=xI2.xJ1;lE2+=immed;++i81;}
8677 if(i81>1||(i81==1&&lE2==0.0))nO1=true;if(nO1){
8678 #ifdef DEBUG_SUBSTITUTIONS
8679 std::cout<<"cAdd: Will add new "
8690 #ifdef DEBUG_SUBSTITUTIONS
8691 std::cout<<" - For that, deleting "
8704 default:if(ConstantFolding_AddGrouping
8706 if(ConstantFolding_AddLogicItems
8720 a+1)))nF1+1);range<nI
8722 i0||(p.max)<e6.max)){e6.max=p.max;e6
8728 iV2&&a!=y52&&p.min>=e6.max)lM3
8742 a+1)))nF1+1);range<nI
8743 iV2&&(!t1.iV2||p.min>t1.min)){t1.min=p.min;t1.iV2=true;y52=a;}
8747 has_max&&a!=y52&&(p.max)<t1.min){nF1);}
8757 cGreaterOrEq:if(ConstantFolding_Comparison
8802 #ifdef DEBUG_SUBSTITUTIONS
8803 std::cout<<"Abs: mul group has "
8813 #ifdef DEBUG_SUBSTITUTIONS
8814 std::cout<<"AbsReplace-Before: "
8816 <<std::flush;DumpHashes
8849 AddParamsMove(lO3);if(!c02
8854 AddParamsMove(c02);}
8856 #ifdef DEBUG_SUBSTITUTIONS
8857 std::cout<<"AbsReplace-After: "
8861 <<std::flush;DumpHashes
8868 #define HANDLE_UNARY_CONST_FUNC(funcname) lX)lL funcname(n6))n5
8870 cLog:tH3(fp_log);l23
8874 0);if(GetPositivityInfo(pow
8880 if(GetEvennessInfo(pow
8919 cAcosh:tH3(fp_acosh);lC
8920 cAsinh:tH3(fp_asinh);lC
8921 cAtanh:tH3(fp_atanh);lC
8922 cAcos:tH3(fp_acos);lC
8923 cAsin:tH3(fp_asin);lC
8924 cAtan:tH3(fp_atan);lC
8925 cCosh:tH3(fp_cosh);lC
8926 cSinh:tH3(fp_sinh);lC
8927 cTanh:tH3(fp_tanh);lC
8939 cCbrt:tH3(fp_cbrt);lC
8940 cSqrt:tH3(fp_sqrt);lC
8942 cLog2:tH3(fp_log2);lC
8943 cLog10:tH3(fp_log10);lC
8954 1));lX&&fp_equal(n6,eS1(0))){if(p1
8963 fp_equal(y4,eS1(0))){if(p0
8964 i0&&(p0.max)<0)lL-fp_const_pihalf
8976 i0&&(p1.max)<fp_const_negativezero
9000 cPow:{if(ConstantFolding_PowOperations
9024 cExp2:tH3(fp_exp2);lC
9028 cCot:lX)nQ3=fp_tan(n6)xE
9029 cSec:lX)nQ3=fp_cos(n6)xE
9030 cCsc:lX)nQ3=fp_sin(n6)xE
9045 #ifdef DEBUG_SUBSTITUTIONS
9047 <<(&yM3)<<"]Done ConstantFolding, result: "
9054 #ifdef FP_SUPPORT_OPTIMIZER
9058 FPoptimizer_CodeTree;iO2{n73<i02
9063 Comp<cLess>{n73<lF<yU
9064 cLessOrEq>{n73<lF<=yU
9066 cGreaterOrEq>{n73<lF>=yU
9072 FPoptimizer_CodeTree{c12
9073 set_abs(){if(!iV2&&!iI2{iV2=yV3}
9075 t83){iV2=true;min=-max;iJ2
9083 nZ2;tP1!iI2{iV2=yV3}
9086 t83)nQ3(-max);max=-min;min=tmp;}
9087 tP1-min>=max){max=-min;n31}
9091 set_neg(){std::swap(iV2,iI2;std::swap(min,max);min=-min;max=-max;}
9094 if(iV2&&Comp<cY2()(min,v))min=func(min
9102 if(has_max&&Comp<cY2()(max,v))max=func(max
9111 set_min_if<cY2(v,func,model);set_max_if<cY2(v,func,model);}
9133 set_min(func,model);set_max(func,model);}
9140 #ifdef DEBUG_SUBSTITUTIONS_extra_verbose
9143 tmp=CalculateResultBoundaries_do(tree)lN1"Estimated boundaries: "
9144 ;if(tmp.iV2)std::cout<<tmp.min;else
9148 i0)std::cout<<tmp.max;else
9158 yK2::CalculateResultBoundaries_do
9163 eO1(-fp_const_pihalf
9164 x8(),fp_const_pihalf
9166 pi_limits(-fp_const_pi
9169 abs_pi_limits(eS1(0),fp_const_pi
9209 set_min_max_if<cGreaterOrEq
9220 set_min_if<cGreater>(eS1(-1),fp_atanh);m
9228 i0&&(m.max)<eS1(1))?fp_acos(m.max):eS1(0),(m
9229 y41(m.min)>=eS1(-1))?fp_acos(m.min):fp_const_pi
9234 set_min_if<cGreater>(eS1(-1),fp_asin,eO1);m
9249 1));lX&&fp_equal(n6,eS1(0))){return
9252 fp_equal(y4,eS1(0))){return
9260 i0||(m.max-m.min)>=(y8
9277 xT1=(min<=fp_const_pihalf
9278 x8()&&max>=fp_const_pihalf
9280 nP1=(min<=cK&&max>=cK);if(xT1&&nP1)e0
9290 if(m.iV2)m.min+=fp_const_pihalf
9292 i0)m.max+=fp_const_pihalf
9295 i0||(m.max-m.min)>=(y8
9312 xT1=(min<=fp_const_pihalf
9313 x8()&&max>=fp_const_pihalf
9315 nP1=(min<=cK&&max>=cK);if(xT1&&nP1)e0
9349 tP1(m.min)t83&&m.max
9352 if(tmp>m.max)m.max=tmp;m.min=eS1(1);}
9355 std::swap(m.min,m.max);}
9360 m.min=fp_cosh(m.min);}
9366 else{m.iV2=true;m.min=eS1(1);if(m
9367 i0){m.min=fp_cosh(m.max);m
9382 2));if(!res2.iV2)res1.iV2
9386 y41(res2.min)<res1.min)res1.min=res2.min;if(!res2
9391 i0&&(res2.max)>res1.max)res1.max=res2.max
9403 xO3!m.iV2)iG=true;yP1.iV2||(m.min)<i11)i11=m.min;if(!m
9405 i0||(m.max)<e63)e63=m.max;}
9418 xO3!m.iV2)iG=true;yP1.iV2||m.min>i11)i11=m.min;if(!m
9420 i0||m.max>e63)e63=m.max;}
9425 cAdd:{tB1(eS1(0),eS1(0));x4
9428 item.iV2)i11+=item.min;else
9431 i0)e63+=item.max;else
9436 e02&&i11>e63)std::swap(i11,e63)l81
9440 lR3{tR2,i91,PlusInf}
9446 v):eF(tR2),value(v){}
9450 eF==i91||(eF==tR2&&value
9454 Value&rhs){if(eF==tR2&&rhs.eF==tR2)value*=rhs.value;else
9455 eF=(c22)!=rhs.c22)?i91:PlusInf);}
9458 n61(eF==i91&&rhs.eF!=i91)||(eF==tR2&&(rhs.eF==PlusInf||(rhs.eF==tR2&&value<rhs.value)));}
9462 yC2,yD2;yD1():yC2(Value::PlusInf),yD2(Value::i91){}
9467 Value&value2){yX3*=value2;if(yX3<yC2)yC2=yX3;if(yD2<yX3)yD2=yX3;}
9474 lS3=c32?Value(i11):nC2
9476 lT3=e02?Value(e63):nC2
9478 lU3=item.iV2?Value(item.min):nC2
9481 i0?Value(item.max):nC2
9490 lT3,lV3);if(range.yC2.eF==Value::tR2)i11=range.yC2.value;else
9492 range.yD2.eF==Value::tR2)e63=range.yD2.value;else
9497 e02&&i11>e63)std::swap(i11,e63)l81
9506 cH1){if(!x.iV2||(x.min)<0)nL-y.max,y.max);else
9513 y.max,fp_const_negativezero
9527 y4>0&&GetEvennessInfo
9534 result;c32=true;i11=0;if(tmp
9539 i0&&tmp.max<=0)i11=eG3
9540 tmp.max,cE2);tE1;if(tmp
9543 i0){e02=true;e63=std::max(fp_abs(tmp.min),fp_abs(tmp.max));e63=eG3
9555 y41(p0.min)cH1)?IsAlways:(p0
9556 i0&&(p0.max)t83?yO3:Unknown);TriTruthValue
9561 t2=Unknown;switch(p0_positivity)tF1
9564 default:switch(c52)tF1
9576 p0.min,p1.min);if(p0.min
9588 p0.max,p1.max);if(min>max)std::swap(min,max);nL
9593 false,fp_const_negativezero
9653 if(m.iV2)m.min=(m.min)<0?0:fp_sqrt(m.min);if(m
9654 i0)m.max=(m.max)<0?0:fp_sqrt(m.max
9659 xsqr,ysqr,add,sqrt;xsqr
9733 yZ3)?IsAlways:yO3;case
9783 fp_equal(yZ3,eS1(0))||fp_equal(yZ3,eS1(1));case
9813 #ifdef FP_SUPPORT_OPTIMIZER
9815 #if defined(__x86_64) || !defined(FP_SUPPORT_CBRT)
9816 # define CBRT_IS_SLOW
9818 #if defined(DEBUG_POWI) || defined(DEBUG_SUBSTITUTIONS)
9828 FPoptimizer_CodeTree;xG1
9829 IsOptimizableUsingPowi(long
9832 synth;synth.PushVar(iE2);size_t
9835 GetByteCodeSize();yV2
9839 x8::MulSequence,synth);size_t
9840 bytecode_grow_amount
9842 GetByteCodeSize()-bytecodesize_backup
9844 bytecode_grow_amount<size_t(MAX_POWI_BYTECODE_LENGTH-penalty);}
9846 ChangeIntoRootChain(yK2&tree,bool
9849 tT2){while(tT2>0){cF
9850 cCbrt);nZ3);tmp.Rehash(nD2--tT2;}
9856 nZ3);tmp.Rehash(nD2--tS2;}
9862 RootPowerTable{static
9865 RootPowers[(1+4)*(1+3)];}
9869 t7(1+4)*(1+3)]={eS1(1)lS
9916 yE2{yE2():n_int_sqrt(0),n_int_cbrt(0),sep_list(),lY1(0){}
9926 CreatePowiResult(eS1
9929 eE=FindIntegerFactor(cE2);if(eE==0){
9931 tU2"no factor found for %Lg\n"
9938 e22=EvaluateFactorCost(eE,0,0,0)+cH
9945 y33);tU2"plain factor = "
9947 ,(int)eE,(long)e22);
9951 n_s=0;n_s<MaxSep;++n_s){int
9961 n_cbrt=s/tC3;if(n_sqrt+n_cbrt>4)y81
9964 s];tH1=FindIntegerFactor(lE1);if(xD2!=0){t8
9967 cost=EvaluateFactorCost(xD2,tD3+n_sqrt,tE3+n_cbrt,lW3+1)+cH
9970 tU2"Candidate sep %u (%d*sqrt %d*cbrt)factor = "
9971 tS3"%ld (for %Lg to %ld)\n"
9972 ,s,n_sqrt,n_cbrt,xD2,(long)cost
9976 if(cost<yE1){xC=s;yQ1=xD2;yE1=cost;}
9981 tU2"CHOSEN sep %u (%d*sqrt %d*cbrt)factor = "
9982 tS3"%ld, exponent %Lg->%Lg\n"
9983 ,xC,xC%tC3,xC/tC3,yQ1,yE1
9990 xC];tD3+=xC%tC3;tE3+=xC/tC3;e22=yE1;eE=yQ1;lW3+=1;}
9994 tU2"resulting exponent is %ld (from exponent=%Lg, best_factor=%Lg)\n"
10000 while(eE%2==0){++tC1
10002 while(eE%3==0){++tC1
10027 xL,0.0);n63&cost=tC1
10028 second;while(xL>1){int
10029 xD2=0;if(xL<256){xD2=yV2
10030 powi_table[xL];if(xD2&128)xD2&=127;else
10031 xD2=0;if(xD2&64)xD2=-(xD2&63)-1;}
10034 if(!(xL&1)){xL/=2;cost+=6;}
10035 else{cost+=7;xL-=1;}
10043 makeLongInteger(value*eS1(xD2))eI2
10047 v=value*eS1(xD2)l81
10048 isLongInteger(v)eI2
10050 FindIntegerFactor(yF1){tH1=(2*2*2*2);
10051 #ifdef CBRT_IS_SLOW
10057 value,xD2)){result=xD2;while((xD2%2)==0&&yG1
10058 value,xD2/2))result=xD2/=2;while((xD2%3)==0&&yG1
10059 value,xD2/3))result=xD2/=3;}
10060 #ifdef CBRT_IS_SLOW
10061 if(result==0){if(yG1
10069 EvaluateFactorCost(int
10075 #ifdef CBRT_IS_SLOW
10083 result=s*lY3+c*e32;while(xD2%2==0){xD2/=2;result+=lY3;}
10084 while(xD2%3==0){xD2/=3;result+=e32;}
10091 FPoptimizer_CodeTree{xG1
10092 yK2::RecreateInversionsAndNegations(bool
10096 0;a<cN3++a)if(lT1.RecreateInversionsAndNegations(prefer_base2))yI1
10097 if(changed){exit_changed:Mark_Incompletely_Hashed()nS2
10104 lH2,cJ1;if(true){bool
10114 1)y21){nQ1=true;nE2=tJ
10120 y21){immeds*=powgroup.xJ1;yH1}
10124 a-->0;)nG1&powgroup=lT1;if(powgroup
10136 immeds,eS1(1)/nE2)));log2.Rehash(nW2}
10143 1)y21){lM1&exp_param=tJ
10145 cE2=exp_param.xJ1;if(cR1,eS1(-1))){iY
10172 nE==cLog2by&&!cJ1.iA1{cJ1=powgroup;iY
10187 IsImmed()&&fp_equal(xX1
10209 RecreateInversionsAndNegations(prefer_base2))xX1
10210 FixIncompleteHashes();lI2
10225 RecreateInversionsAndNegations(prefer_base2))xX1
10226 FixIncompleteHashes();DelParams();lI2
10263 fp_equal(xD2,eS1(-2)))xF
10324 #ifdef DEBUG_SUBSTITUTIONS
10325 tU2"Will make a Sub conversion in:\n"
10326 );fflush(stdout);iO
10341 y21&&fp_equal(cK1.xJ1,eS1(0))){lI2
10343 else{if(cK1.xT2==1){lI2
10367 #ifdef DEBUG_SUBSTITUTIONS
10368 tU2"After Sub conversion:\n"
10369 );fflush(stdout);iO
10382 CreatePowiResult(fp_abs
10383 n03));if(r.lY1!=0){bool
10391 tU2"Will resolve powi %Lg as powi(chain(%d,%d),%ld)"
10395 x33,r.n_int_cbrt,r.lY1)xS3
10404 tC3;tU2"*chain(%d,%d)"
10414 ChangeIntoRootChain(yG2,iB1,r
10415 x33,r.n_int_cbrt);yG2
10417 pow;if(r.lY1!=1){pow
10442 ChangeIntoRootChain(e52,false,n_sqrt,n_cbrt);e52
10453 cMul);SetParamsMove(mul.iE1));}
10461 y21||!isLongInteger
10462 n03)||!IsOptimizableUsingPowi
10465 y21&&p0.xJ1>0.0){if(prefer_base2){eS1
10466 yH2=fp_log2(p0.xJ1)i82
10478 yH2=fp_log(p0.xJ1)i82
10491 GetPositivityInfo(p0)==IsAlways){if(prefer_base2)nG1
10520 cDiv:{if(GetParam(0)y21&&fp_equal(GetParam(0).xJ1,nY3{lI2
10531 #ifdef FP_SUPPORT_OPTIMIZER
10535 FPoptimizer_CodeTree;class
10541 eT1():yJ1(0),eK(0),eL(0),lF1(0){}
10553 GetCSEscore()const{size_t
10558 NeedsSinCos()const{bool
10559 always_sincostan=(yJ1==(eK+eL+lF1));if((lF1&&(eL||eK))||(eL&&eK)){if(always_sincostan
10567 MinimumDepth()const{size_t
10568 n_sincos=std::min(eK,eL);if(n_sincos==0
10575 TreeCountType:public
10576 std::multimap<fphash_t,std::pair<eT1,yK2> >{}
10578 FindTreeCounts(nX1&lK2,lM1&tree,OPCODE
10581 tree.GetHash());bool
10585 tree.GetHash();++i){if(tree
10591 lL2;found=true;nM3}
10594 lL2;lK2.nT3,std::make_pair(tree.GetHash(),std::make_pair
10599 FindTreeCounts(lK2,xI2,tree
10608 lM1&root,lM1&c53{if(root
10615 result={true,false}
10630 2),c53;if(cond.cI||xW.cI||y9.cI){tC1
10633 eH=((xW.cI==y9.cI)||eX2&&(cond
10634 eH||(xW.cI&&y9.cI))&&(xW
10644 root.GetParamCount(),a=0;a<b;++a){c9
10648 a),c53;if(tmp.cI)tC1
10650 eH==false)tK1=true;tP1
10652 if(tK1&&!nS1)result
10663 iT,a=0;a<b;++a){lM1&leaf=xI2;iG1
10665 nX1::const_iterator
10667 i!=lK2.end();++i){if(i->eQ3
10673 score=occ.GetCSEscore();lM1&candidate=i->nG2
10676 if(leaf.xT2<occ.MinimumDepth())y81
10680 leaf)eH==false)continue
10689 lM1&nU3,lM1&expr){for
10705 GoodMomentForCSE(lM1&nU3,lM1&expr){if(nU3
10725 FPoptimizer_CodeTree{yV1
10727 yK2::SynthCommonSubExpressions(yV2
10733 lK2;FindTreeCounts(lK2,*this,lM2);
10734 #ifdef DEBUG_SUBSTITUTIONS_CSE
10741 i!=lK2.end();i=j){j=i;++j;const
10745 score=occ.GetCSEscore();lM1&tree=i->nG2
10746 #ifdef DEBUG_SUBSTITUTIONS_CSE
10747 std::cout<<"Score "
10749 ;DumpTreeWithIndent(tree);
10753 if(tree.xT2<occ.MinimumDepth())xV
10755 if(lG1*this,tree)eH==false)xV
10756 if(n62*this,tree,synth,lK2)){y81}
10757 if(!GoodMomentForCSE(*this
10760 score*=tree.xT2;if(score>yI2){yI2=score;lT2=i;}
10762 if(yI2<=0)break;const
10766 #ifdef DEBUG_SUBSTITUTIONS_CSE
10767 std::cout<<tZ3"Common Subexpression:"
10773 y01=occ.NeedsSinCos()yJ
10774 tY2,tZ2;if(y01){tY2
10786 tZ2)){if(y01==2){lK2.erase(lT2);y81}
10789 tree.SynthesizeByteCode(synth,false);lK2.erase(lT2);
10790 #ifdef DEBUG_SUBSTITUTIONS_CSE
10791 std::cout<<"Done with Common Subexpression:"
10796 if(y01){if(y01==2){tQ1
10810 #ifdef FP_SUPPORT_OPTIMIZER
10817 FPoptimizer_CodeTree;CopyOnWrite()yJ
10818 tree;tree.GenerateFrom(mData->mByteCode,mData->mImmed,*mData);FPoptimizer_Optimize::ApplyGrammars(tree);yG<i02>c73;yG
10821 stacktop_max=0;tree.SynthesizeByteCode(c73,immed,stacktop_max);if(mData->mStackSize!=stacktop_max){mData->mStackSize=i02(stacktop_max);
10822 #if !defined(FP_USE_THREAD_SAFE_EVAL) && \
10823 !defined(FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA)
10829 mData->mByteCode.swap(c73);mData->mImmed.swap(immed);}
10830 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
10831 n73<>lR1<MpfrFloat>nH2}
10833 #ifdef FP_SUPPORT_GMP_INT_TYPE
10834 n73<>lR1<GmpInt>nH2}
10836 FUNCTIONPARSER_INSTANTIATE_TYPES