Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: src/compiler/effect-control-linearizer.cc

Issue 2215183003: [turbofan] Move lowering of Float64 optional operators to EffectControlLinearizer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Update. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/effect-control-linearizer.h ('k') | src/compiler/representation-change.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/effect-control-linearizer.h" 5 #include "src/compiler/effect-control-linearizer.h"
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/compiler/access-builder.h" 8 #include "src/compiler/access-builder.h"
9 #include "src/compiler/js-graph.h" 9 #include "src/compiler/js-graph.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 break; 725 break;
726 case IrOpcode::kTransitionElementsKind: 726 case IrOpcode::kTransitionElementsKind:
727 state = LowerTransitionElementsKind(node, *effect, *control); 727 state = LowerTransitionElementsKind(node, *effect, *control);
728 break; 728 break;
729 case IrOpcode::kLoadTypedElement: 729 case IrOpcode::kLoadTypedElement:
730 state = LowerLoadTypedElement(node, *effect, *control); 730 state = LowerLoadTypedElement(node, *effect, *control);
731 break; 731 break;
732 case IrOpcode::kStoreTypedElement: 732 case IrOpcode::kStoreTypedElement:
733 state = LowerStoreTypedElement(node, *effect, *control); 733 state = LowerStoreTypedElement(node, *effect, *control);
734 break; 734 break;
735 case IrOpcode::kFloat64RoundUp:
736 state = LowerFloat64RoundUp(node, *effect, *control);
737 break;
738 case IrOpcode::kFloat64RoundDown:
739 state = LowerFloat64RoundDown(node, *effect, *control);
740 break;
741 case IrOpcode::kFloat64RoundTruncate:
742 state = LowerFloat64RoundTruncate(node, *effect, *control);
743 break;
735 default: 744 default:
736 return false; 745 return false;
737 } 746 }
738 NodeProperties::ReplaceUses(node, state.value, state.effect, state.control); 747 NodeProperties::ReplaceUses(node, state.value, state.effect, state.control);
739 *effect = state.effect; 748 *effect = state.effect;
740 *control = state.control; 749 *control = state.control;
741 return true; 750 return true;
742 } 751 }
743 752
744 EffectControlLinearizer::ValueEffectControl 753 EffectControlLinearizer::ValueEffectControl
(...skipping 1950 matching lines...) Expand 10 before | Expand all | Expand 10 after
2695 2704
2696 // Perform the actual typed element access. 2705 // Perform the actual typed element access.
2697 effect = graph()->NewNode( 2706 effect = graph()->NewNode(
2698 simplified()->StoreElement( 2707 simplified()->StoreElement(
2699 AccessBuilder::ForTypedArrayElement(array_type, true)), 2708 AccessBuilder::ForTypedArrayElement(array_type, true)),
2700 storage, index, value, effect, control); 2709 storage, index, value, effect, control);
2701 2710
2702 return ValueEffectControl(nullptr, effect, control); 2711 return ValueEffectControl(nullptr, effect, control);
2703 } 2712 }
2704 2713
2714 EffectControlLinearizer::ValueEffectControl
2715 EffectControlLinearizer::LowerFloat64RoundUp(Node* node, Node* effect,
2716 Node* control) {
2717 // Nothing to be done if a fast hardware instruction is available.
2718 if (machine()->Float64RoundUp().IsSupported()) {
2719 return ValueEffectControl(node, effect, control);
2720 }
2721
2722 Node* const one = jsgraph()->Float64Constant(1.0);
2723 Node* const zero = jsgraph()->Float64Constant(0.0);
2724 Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
2725 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
2726 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
2727 Node* const input = node->InputAt(0);
2728
2729 // General case for ceil.
2730 //
2731 // if 0.0 < input then
2732 // if 2^52 <= input then
2733 // input
2734 // else
2735 // let temp1 = (2^52 + input) - 2^52 in
2736 // if temp1 < input then
2737 // temp1 + 1
2738 // else
2739 // temp1
2740 // else
2741 // if input == 0 then
2742 // input
2743 // else
2744 // if input <= -2^52 then
2745 // input
2746 // else
2747 // let temp1 = -0 - input in
2748 // let temp2 = (2^52 + temp1) - 2^52 in
2749 // let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
2750 // -0 - temp3
2751 //
2752 // Note: We do not use the Diamond helper class here, because it really hurts
2753 // readability with nested diamonds.
2754
2755 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
2756 Node* branch0 =
2757 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
2758
2759 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2760 Node* vtrue0;
2761 {
2762 Node* check1 =
2763 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
2764 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
2765
2766 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2767 Node* vtrue1 = input;
2768
2769 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2770 Node* vfalse1;
2771 {
2772 Node* temp1 = graph()->NewNode(
2773 machine()->Float64Sub(),
2774 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
2775 vfalse1 = graph()->NewNode(
2776 common()->Select(MachineRepresentation::kFloat64),
2777 graph()->NewNode(machine()->Float64LessThan(), temp1, input),
2778 graph()->NewNode(machine()->Float64Add(), temp1, one), temp1);
2779 }
2780
2781 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2782 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2783 vtrue1, vfalse1, if_true0);
2784 }
2785
2786 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2787 Node* vfalse0;
2788 {
2789 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
2790 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
2791 check1, if_false0);
2792
2793 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2794 Node* vtrue1 = input;
2795
2796 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2797 Node* vfalse1;
2798 {
2799 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
2800 input, minus_two_52);
2801 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
2802 check2, if_false1);
2803
2804 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
2805 Node* vtrue2 = input;
2806
2807 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
2808 Node* vfalse2;
2809 {
2810 Node* temp1 =
2811 graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
2812 Node* temp2 = graph()->NewNode(
2813 machine()->Float64Sub(),
2814 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
2815 Node* temp3 = graph()->NewNode(
2816 common()->Select(MachineRepresentation::kFloat64),
2817 graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
2818 graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
2819 vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
2820 }
2821
2822 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
2823 vfalse1 =
2824 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2825 vtrue2, vfalse2, if_false1);
2826 }
2827
2828 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2829 vfalse0 =
2830 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2831 vtrue1, vfalse1, if_false0);
2832 }
2833
2834 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2835 Node* value =
2836 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2837 vtrue0, vfalse0, merge0);
2838 return ValueEffectControl(value, effect, merge0);
2839 }
2840
2841 EffectControlLinearizer::ValueEffectControl
2842 EffectControlLinearizer::LowerFloat64RoundDown(Node* node, Node* effect,
2843 Node* control) {
2844 // Nothing to be done if a fast hardware instruction is available.
2845 if (machine()->Float64RoundDown().IsSupported()) {
2846 return ValueEffectControl(node, effect, control);
2847 }
2848
2849 Node* const one = jsgraph()->Float64Constant(1.0);
2850 Node* const zero = jsgraph()->Float64Constant(0.0);
2851 Node* const minus_one = jsgraph()->Float64Constant(-1.0);
2852 Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
2853 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
2854 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
2855 Node* const input = node->InputAt(0);
2856
2857 // General case for floor.
2858 //
2859 // if 0.0 < input then
2860 // if 2^52 <= input then
2861 // input
2862 // else
2863 // let temp1 = (2^52 + input) - 2^52 in
2864 // if input < temp1 then
2865 // temp1 - 1
2866 // else
2867 // temp1
2868 // else
2869 // if input == 0 then
2870 // input
2871 // else
2872 // if input <= -2^52 then
2873 // input
2874 // else
2875 // let temp1 = -0 - input in
2876 // let temp2 = (2^52 + temp1) - 2^52 in
2877 // if temp2 < temp1 then
2878 // -1 - temp2
2879 // else
2880 // -0 - temp2
2881 //
2882 // Note: We do not use the Diamond helper class here, because it really hurts
2883 // readability with nested diamonds.
2884
2885 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
2886 Node* branch0 =
2887 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
2888
2889 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2890 Node* vtrue0;
2891 {
2892 Node* check1 =
2893 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
2894 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
2895
2896 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2897 Node* vtrue1 = input;
2898
2899 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2900 Node* vfalse1;
2901 {
2902 Node* temp1 = graph()->NewNode(
2903 machine()->Float64Sub(),
2904 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
2905 vfalse1 = graph()->NewNode(
2906 common()->Select(MachineRepresentation::kFloat64),
2907 graph()->NewNode(machine()->Float64LessThan(), input, temp1),
2908 graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
2909 }
2910
2911 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2912 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2913 vtrue1, vfalse1, if_true0);
2914 }
2915
2916 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2917 Node* vfalse0;
2918 {
2919 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
2920 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
2921 check1, if_false0);
2922
2923 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2924 Node* vtrue1 = input;
2925
2926 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2927 Node* vfalse1;
2928 {
2929 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
2930 input, minus_two_52);
2931 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
2932 check2, if_false1);
2933
2934 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
2935 Node* vtrue2 = input;
2936
2937 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
2938 Node* vfalse2;
2939 {
2940 Node* temp1 =
2941 graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
2942 Node* temp2 = graph()->NewNode(
2943 machine()->Float64Sub(),
2944 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
2945 vfalse2 = graph()->NewNode(
2946 common()->Select(MachineRepresentation::kFloat64),
2947 graph()->NewNode(machine()->Float64LessThan(), temp2, temp1),
2948 graph()->NewNode(machine()->Float64Sub(), minus_one, temp2),
2949 graph()->NewNode(machine()->Float64Sub(), minus_zero, temp2));
2950 }
2951
2952 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
2953 vfalse1 =
2954 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2955 vtrue2, vfalse2, if_false1);
2956 }
2957
2958 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2959 vfalse0 =
2960 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2961 vtrue1, vfalse1, if_false0);
2962 }
2963
2964 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2965 Node* value =
2966 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2967 vtrue0, vfalse0, merge0);
2968 return ValueEffectControl(value, effect, merge0);
2969 }
2970
2971 EffectControlLinearizer::ValueEffectControl
2972 EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node, Node* effect,
2973 Node* control) {
2974 // Nothing to be done if a fast hardware instruction is available.
2975 if (machine()->Float64RoundTruncate().IsSupported()) {
2976 return ValueEffectControl(node, effect, control);
2977 }
2978
2979 Node* const one = jsgraph()->Float64Constant(1.0);
2980 Node* const zero = jsgraph()->Float64Constant(0.0);
2981 Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
2982 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
2983 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
2984 Node* const input = node->InputAt(0);
2985
2986 // General case for trunc.
2987 //
2988 // if 0.0 < input then
2989 // if 2^52 <= input then
2990 // input
2991 // else
2992 // let temp1 = (2^52 + input) - 2^52 in
2993 // if input < temp1 then
2994 // temp1 - 1
2995 // else
2996 // temp1
2997 // else
2998 // if input == 0 then
2999 // input
3000 // else
3001 // if input <= -2^52 then
3002 // input
3003 // else
3004 // let temp1 = -0 - input in
3005 // let temp2 = (2^52 + temp1) - 2^52 in
3006 // let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
3007 // -0 - temp3
3008 //
3009 // Note: We do not use the Diamond helper class here, because it really hurts
3010 // readability with nested diamonds.
3011
3012 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
3013 Node* branch0 =
3014 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
3015
3016 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3017 Node* vtrue0;
3018 {
3019 Node* check1 =
3020 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
3021 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
3022
3023 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3024 Node* vtrue1 = input;
3025
3026 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3027 Node* vfalse1;
3028 {
3029 Node* temp1 = graph()->NewNode(
3030 machine()->Float64Sub(),
3031 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
3032 vfalse1 = graph()->NewNode(
3033 common()->Select(MachineRepresentation::kFloat64),
3034 graph()->NewNode(machine()->Float64LessThan(), input, temp1),
3035 graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
3036 }
3037
3038 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3039 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3040 vtrue1, vfalse1, if_true0);
3041 }
3042
3043 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3044 Node* vfalse0;
3045 {
3046 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
3047 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
3048 check1, if_false0);
3049
3050 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3051 Node* vtrue1 = input;
3052
3053 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3054 Node* vfalse1;
3055 {
3056 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
3057 input, minus_two_52);
3058 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
3059 check2, if_false1);
3060
3061 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
3062 Node* vtrue2 = input;
3063
3064 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
3065 Node* vfalse2;
3066 {
3067 Node* temp1 =
3068 graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
3069 Node* temp2 = graph()->NewNode(
3070 machine()->Float64Sub(),
3071 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
3072 Node* temp3 = graph()->NewNode(
3073 common()->Select(MachineRepresentation::kFloat64),
3074 graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
3075 graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
3076 vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
3077 }
3078
3079 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
3080 vfalse1 =
3081 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3082 vtrue2, vfalse2, if_false1);
3083 }
3084
3085 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3086 vfalse0 =
3087 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3088 vtrue1, vfalse1, if_false0);
3089 }
3090
3091 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
3092 Node* value =
3093 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3094 vtrue0, vfalse0, merge0);
3095 return ValueEffectControl(value, effect, merge0);
3096 }
3097
2705 Factory* EffectControlLinearizer::factory() const { 3098 Factory* EffectControlLinearizer::factory() const {
2706 return isolate()->factory(); 3099 return isolate()->factory();
2707 } 3100 }
2708 3101
2709 Isolate* EffectControlLinearizer::isolate() const { 3102 Isolate* EffectControlLinearizer::isolate() const {
2710 return jsgraph()->isolate(); 3103 return jsgraph()->isolate();
2711 } 3104 }
2712 3105
2713 Operator const* EffectControlLinearizer::ToNumberOperator() { 3106 Operator const* EffectControlLinearizer::ToNumberOperator() {
2714 if (!to_number_operator_.is_set()) { 3107 if (!to_number_operator_.is_set()) {
2715 Callable callable = CodeFactory::ToNumber(isolate()); 3108 Callable callable = CodeFactory::ToNumber(isolate());
2716 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 3109 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
2717 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 3110 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
2718 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 3111 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
2719 Operator::kNoThrow); 3112 Operator::kNoThrow);
2720 to_number_operator_.set(common()->Call(desc)); 3113 to_number_operator_.set(common()->Call(desc));
2721 } 3114 }
2722 return to_number_operator_.get(); 3115 return to_number_operator_.get();
2723 } 3116 }
2724 3117
2725 } // namespace compiler 3118 } // namespace compiler
2726 } // namespace internal 3119 } // namespace internal
2727 } // namespace v8 3120 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/effect-control-linearizer.h ('k') | src/compiler/representation-change.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698