| OLD | NEW | 
 |    1  | 
|    1 // Copyright 2015 the V8 project authors. All rights reserved. |    2 // 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 |    3 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    4 // found in the LICENSE file. | 
|    4  |    5  | 
|    5 #include "src/compiler/js-intrinsic-lowering.h" |    6 #include "src/compiler/js-intrinsic-lowering.h" | 
|    6  |    7  | 
|    7 #include "src/compiler/access-builder.h" |    8 #include "src/compiler/access-builder.h" | 
|    8 #include "src/compiler/js-graph.h" |    9 #include "src/compiler/js-graph.h" | 
|    9 #include "src/compiler/node-properties.h" |   10 #include "src/compiler/node-properties.h" | 
|   10  |   11  | 
|   11 namespace v8 { |   12 namespace v8 { | 
|   12 namespace internal { |   13 namespace internal { | 
|   13 namespace compiler { |   14 namespace compiler { | 
|   14  |   15  | 
|   15 JSIntrinsicLowering::JSIntrinsicLowering(JSGraph* jsgraph) |   16 JSIntrinsicLowering::JSIntrinsicLowering(JSGraph* jsgraph) | 
|   16     : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {} |   17     : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {} | 
|   17  |   18  | 
|   18  |   19  | 
|   19 Reduction JSIntrinsicLowering::Reduce(Node* node) { |   20 Reduction JSIntrinsicLowering::Reduce(Node* node) { | 
|   20   if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange(); |   21   if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange(); | 
|   21   const Runtime::Function* const f = |   22   const Runtime::Function* const f = | 
|   22       Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id()); |   23       Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id()); | 
|   23   if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange(); |   24   if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange(); | 
|   24   switch (f->function_id) { |   25   switch (f->function_id) { | 
 |   26     case Runtime::kInlineConstructDouble: | 
 |   27       return ReduceConstructDouble(node); | 
|   25     case Runtime::kInlineDeoptimizeNow: |   28     case Runtime::kInlineDeoptimizeNow: | 
|   26       return ReduceInlineDeoptimizeNow(node); |   29       return ReduceDeoptimizeNow(node); | 
 |   30     case Runtime::kInlineDoubleHi: | 
 |   31       return ReduceDoubleHi(node); | 
 |   32     case Runtime::kInlineDoubleLo: | 
 |   33       return ReduceDoubleLo(node); | 
 |   34     case Runtime::kInlineHeapObjectGetMap: | 
 |   35       return ReduceHeapObjectGetMap(node); | 
 |   36     case Runtime::kInlineIsArray: | 
 |   37       return ReduceIsInstanceType(node, JS_ARRAY_TYPE); | 
 |   38     case Runtime::kInlineIsFunction: | 
 |   39       return ReduceIsInstanceType(node, JS_FUNCTION_TYPE); | 
 |   40     case Runtime::kInlineIsNonNegativeSmi: | 
 |   41       return ReduceIsNonNegativeSmi(node); | 
 |   42     case Runtime::kInlineIsRegExp: | 
 |   43       return ReduceIsInstanceType(node, JS_REGEXP_TYPE); | 
|   27     case Runtime::kInlineIsSmi: |   44     case Runtime::kInlineIsSmi: | 
|   28       return ReduceInlineIsSmi(node); |   45       return ReduceIsSmi(node); | 
|   29     case Runtime::kInlineIsNonNegativeSmi: |  | 
|   30       return ReduceInlineIsNonNegativeSmi(node); |  | 
|   31     case Runtime::kInlineIsArray: |  | 
|   32       return ReduceInlineIsInstanceType(node, JS_ARRAY_TYPE); |  | 
|   33     case Runtime::kInlineIsFunction: |  | 
|   34       return ReduceInlineIsInstanceType(node, JS_FUNCTION_TYPE); |  | 
|   35     case Runtime::kInlineJSValueGetValue: |   46     case Runtime::kInlineJSValueGetValue: | 
|   36       return ReduceInlineJSValueGetValue(node); |   47       return ReduceJSValueGetValue(node); | 
|   37     case Runtime::kInlineConstructDouble: |   48     case Runtime::kInlineMapGetInstanceType: | 
|   38       return ReduceInlineConstructDouble(node); |   49       return ReduceMapGetInstanceType(node); | 
|   39     case Runtime::kInlineDoubleLo: |  | 
|   40       return ReduceInlineDoubleLo(node); |  | 
|   41     case Runtime::kInlineDoubleHi: |  | 
|   42       return ReduceInlineDoubleHi(node); |  | 
|   43     case Runtime::kInlineIsRegExp: |  | 
|   44       return ReduceInlineIsInstanceType(node, JS_REGEXP_TYPE); |  | 
|   45     case Runtime::kInlineMathClz32: |   50     case Runtime::kInlineMathClz32: | 
|   46       return ReduceInlineMathClz32(node); |   51       return ReduceMathClz32(node); | 
|   47     case Runtime::kInlineMathFloor: |   52     case Runtime::kInlineMathFloor: | 
|   48       return ReduceInlineMathFloor(node); |   53       return ReduceMathFloor(node); | 
|   49     case Runtime::kInlineMathSqrt: |   54     case Runtime::kInlineMathSqrt: | 
|   50       return ReduceInlineMathSqrt(node); |   55       return ReduceMathSqrt(node); | 
|   51     case Runtime::kInlineStringGetLength: |   56     case Runtime::kInlineStringGetLength: | 
|   52       return ReduceInlineStringGetLength(node); |   57       return ReduceStringGetLength(node); | 
|   53     case Runtime::kInlineValueOf: |   58     case Runtime::kInlineValueOf: | 
|   54       return ReduceInlineValueOf(node); |   59       return ReduceValueOf(node); | 
|   55     default: |   60     default: | 
|   56       break; |   61       break; | 
|   57   } |   62   } | 
|   58   return NoChange(); |   63   return NoChange(); | 
|   59 } |   64 } | 
|   60  |   65  | 
|   61  |   66  | 
|   62 Reduction JSIntrinsicLowering::ReduceInlineDeoptimizeNow(Node* node) { |   67 Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) { | 
 |   68   Node* high = NodeProperties::GetValueInput(node, 0); | 
 |   69   Node* low = NodeProperties::GetValueInput(node, 1); | 
 |   70   Node* value = | 
 |   71       graph()->NewNode(machine()->Float64InsertHighWord32(), | 
 |   72                        graph()->NewNode(machine()->Float64InsertLowWord32(), | 
 |   73                                         jsgraph()->Constant(0), low), | 
 |   74                        high); | 
 |   75   NodeProperties::ReplaceWithValue(node, value); | 
 |   76   return Replace(value); | 
 |   77 } | 
 |   78  | 
 |   79  | 
 |   80 Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) { | 
|   63   if (!FLAG_turbo_deoptimization) return NoChange(); |   81   if (!FLAG_turbo_deoptimization) return NoChange(); | 
|   64  |   82  | 
|   65   Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); |   83   Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | 
|   66   DCHECK_EQ(frame_state->opcode(), IrOpcode::kFrameState); |   84   DCHECK_EQ(frame_state->opcode(), IrOpcode::kFrameState); | 
|   67  |   85  | 
|   68   Node* effect = NodeProperties::GetEffectInput(node); |   86   Node* effect = NodeProperties::GetEffectInput(node); | 
|   69   Node* control = NodeProperties::GetControlInput(node); |   87   Node* control = NodeProperties::GetControlInput(node); | 
|   70  |   88  | 
|   71   // We are making the continuation after the call dead. To |   89   // We are making the continuation after the call dead. To | 
|   72   // model this, we generate if (true) statement with deopt |   90   // model this, we generate if (true) statement with deopt | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|   92     end_pred->set_op(common()->Merge(inputs)); |  110     end_pred->set_op(common()->Merge(inputs)); | 
|   93   } else { |  111   } else { | 
|   94     Node* merge = graph()->NewNode(common()->Merge(2), end_pred, deopt); |  112     Node* merge = graph()->NewNode(common()->Merge(2), end_pred, deopt); | 
|   95     NodeProperties::ReplaceControlInput(graph()->end(), merge); |  113     NodeProperties::ReplaceControlInput(graph()->end(), merge); | 
|   96   } |  114   } | 
|   97  |  115  | 
|   98   return Changed(deopt); |  116   return Changed(deopt); | 
|   99 } |  117 } | 
|  100  |  118  | 
|  101  |  119  | 
|  102 Reduction JSIntrinsicLowering::ReduceInlineIsSmi(Node* node) { |  120 Reduction JSIntrinsicLowering::ReduceDoubleHi(Node* node) { | 
|  103   return Change(node, simplified()->ObjectIsSmi()); |  121   return Change(node, machine()->Float64ExtractHighWord32()); | 
|  104 } |  122 } | 
|  105  |  123  | 
|  106  |  124  | 
|  107 Reduction JSIntrinsicLowering::ReduceInlineIsNonNegativeSmi(Node* node) { |  125 Reduction JSIntrinsicLowering::ReduceDoubleLo(Node* node) { | 
|  108   return Change(node, simplified()->ObjectIsNonNegativeSmi()); |  126   return Change(node, machine()->Float64ExtractLowWord32()); | 
|  109 } |  127 } | 
|  110  |  128  | 
|  111  |  129  | 
|  112 Reduction JSIntrinsicLowering::ReduceInlineJSValueGetValue(Node* node) { |  130 Reduction JSIntrinsicLowering::ReduceHeapObjectGetMap(Node* node) { | 
|  113   Node* value = NodeProperties::GetValueInput(node, 0); |  131   Node* value = NodeProperties::GetValueInput(node, 0); | 
|  114   Node* effect = NodeProperties::GetEffectInput(node); |  132   Node* effect = NodeProperties::GetEffectInput(node); | 
|  115   Node* control = NodeProperties::GetControlInput(node); |  133   Node* control = NodeProperties::GetControlInput(node); | 
|  116   return Change(node, simplified()->LoadField(AccessBuilder::ForValue()), value, |  134   return Change(node, simplified()->LoadField(AccessBuilder::ForMap()), value, | 
|  117                 effect, control); |  135                 effect, control); | 
|  118 } |  136 } | 
|  119  |  137  | 
|  120  |  138  | 
|  121 Reduction JSIntrinsicLowering::ReduceInlineConstructDouble(Node* node) { |  139 Reduction JSIntrinsicLowering::ReduceIsInstanceType( | 
|  122   Node* high = NodeProperties::GetValueInput(node, 0); |  | 
|  123   Node* low = NodeProperties::GetValueInput(node, 1); |  | 
|  124   Node* value = |  | 
|  125       graph()->NewNode(machine()->Float64InsertHighWord32(), |  | 
|  126                        graph()->NewNode(machine()->Float64InsertLowWord32(), |  | 
|  127                                         jsgraph()->Constant(0), low), |  | 
|  128                        high); |  | 
|  129   NodeProperties::ReplaceWithValue(node, value); |  | 
|  130   return Replace(value); |  | 
|  131 } |  | 
|  132  |  | 
|  133  |  | 
|  134 Reduction JSIntrinsicLowering::ReduceInlineDoubleLo(Node* node) { |  | 
|  135   return Change(node, machine()->Float64ExtractLowWord32()); |  | 
|  136 } |  | 
|  137  |  | 
|  138  |  | 
|  139 Reduction JSIntrinsicLowering::ReduceInlineDoubleHi(Node* node) { |  | 
|  140   return Change(node, machine()->Float64ExtractHighWord32()); |  | 
|  141 } |  | 
|  142  |  | 
|  143  |  | 
|  144 Reduction JSIntrinsicLowering::ReduceInlineIsInstanceType( |  | 
|  145     Node* node, InstanceType instance_type) { |  140     Node* node, InstanceType instance_type) { | 
|  146   // if (%_IsSmi(value)) { |  141   // if (%_IsSmi(value)) { | 
|  147   //   return false; |  142   //   return false; | 
|  148   // } else { |  143   // } else { | 
|  149   //   return %_GetInstanceType(%_GetMap(value)) == instance_type; |  144   //   return %_GetInstanceType(%_GetMap(value)) == instance_type; | 
|  150   // } |  145   // } | 
|  151   MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged); |  146   MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged); | 
|  152  |  147  | 
|  153   Node* value = NodeProperties::GetValueInput(node, 0); |  148   Node* value = NodeProperties::GetValueInput(node, 0); | 
|  154   Node* effect = NodeProperties::GetEffectInput(node); |  149   Node* effect = NodeProperties::GetEffectInput(node); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  174  |  169  | 
|  175   // Replace all effect uses of {node} with the {ephi}. |  170   // Replace all effect uses of {node} with the {ephi}. | 
|  176   Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); |  171   Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); | 
|  177   NodeProperties::ReplaceWithValue(node, node, ephi); |  172   NodeProperties::ReplaceWithValue(node, node, ephi); | 
|  178  |  173  | 
|  179   // Turn the {node} into a Phi. |  174   // Turn the {node} into a Phi. | 
|  180   return Change(node, common()->Phi(type, 2), vtrue, vfalse, merge); |  175   return Change(node, common()->Phi(type, 2), vtrue, vfalse, merge); | 
|  181 } |  176 } | 
|  182  |  177  | 
|  183  |  178  | 
|  184 Reduction JSIntrinsicLowering::ReduceInlineMathClz32(Node* node) { |  179 Reduction JSIntrinsicLowering::ReduceIsNonNegativeSmi(Node* node) { | 
 |  180   return Change(node, simplified()->ObjectIsNonNegativeSmi()); | 
 |  181 } | 
 |  182  | 
 |  183  | 
 |  184 Reduction JSIntrinsicLowering::ReduceIsSmi(Node* node) { | 
 |  185   return Change(node, simplified()->ObjectIsSmi()); | 
 |  186 } | 
 |  187  | 
 |  188  | 
 |  189 Reduction JSIntrinsicLowering::ReduceJSValueGetValue(Node* node) { | 
 |  190   Node* value = NodeProperties::GetValueInput(node, 0); | 
 |  191   Node* effect = NodeProperties::GetEffectInput(node); | 
 |  192   Node* control = NodeProperties::GetControlInput(node); | 
 |  193   return Change(node, simplified()->LoadField(AccessBuilder::ForValue()), value, | 
 |  194                 effect, control); | 
 |  195 } | 
 |  196  | 
 |  197  | 
 |  198 Reduction JSIntrinsicLowering::ReduceMapGetInstanceType(Node* node) { | 
 |  199   Node* value = NodeProperties::GetValueInput(node, 0); | 
 |  200   Node* effect = NodeProperties::GetEffectInput(node); | 
 |  201   Node* control = NodeProperties::GetControlInput(node); | 
 |  202   return Change(node, | 
 |  203                 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), | 
 |  204                 value, effect, control); | 
 |  205 } | 
 |  206  | 
 |  207  | 
 |  208 Reduction JSIntrinsicLowering::ReduceMathClz32(Node* node) { | 
|  185   return Change(node, machine()->Word32Clz()); |  209   return Change(node, machine()->Word32Clz()); | 
|  186 } |  210 } | 
|  187  |  211  | 
|  188  |  212  | 
|  189 Reduction JSIntrinsicLowering::ReduceInlineMathFloor(Node* node) { |  213 Reduction JSIntrinsicLowering::ReduceMathFloor(Node* node) { | 
|  190   if (!machine()->HasFloat64RoundDown()) return NoChange(); |  214   if (!machine()->HasFloat64RoundDown()) return NoChange(); | 
|  191   return Change(node, machine()->Float64RoundDown()); |  215   return Change(node, machine()->Float64RoundDown()); | 
|  192 } |  216 } | 
|  193  |  217  | 
|  194  |  218  | 
|  195 Reduction JSIntrinsicLowering::ReduceInlineMathSqrt(Node* node) { |  219 Reduction JSIntrinsicLowering::ReduceMathSqrt(Node* node) { | 
|  196   return Change(node, machine()->Float64Sqrt()); |  220   return Change(node, machine()->Float64Sqrt()); | 
|  197 } |  221 } | 
|  198  |  222  | 
|  199  |  223  | 
|  200 Reduction JSIntrinsicLowering::ReduceInlineStringGetLength(Node* node) { |  224 Reduction JSIntrinsicLowering::ReduceStringGetLength(Node* node) { | 
|  201   Node* value = NodeProperties::GetValueInput(node, 0); |  225   Node* value = NodeProperties::GetValueInput(node, 0); | 
|  202   Node* effect = NodeProperties::GetEffectInput(node); |  226   Node* effect = NodeProperties::GetEffectInput(node); | 
|  203   Node* control = NodeProperties::GetControlInput(node); |  227   Node* control = NodeProperties::GetControlInput(node); | 
|  204   return Change(node, simplified()->LoadField(AccessBuilder::ForStringLength()), |  228   return Change(node, simplified()->LoadField(AccessBuilder::ForStringLength()), | 
|  205                 value, effect, control); |  229                 value, effect, control); | 
|  206 } |  230 } | 
|  207  |  231  | 
|  208  |  232  | 
|  209 Reduction JSIntrinsicLowering::ReduceInlineValueOf(Node* node) { |  233 Reduction JSIntrinsicLowering::ReduceValueOf(Node* node) { | 
|  210   // if (%_IsSmi(value)) { |  234   // if (%_IsSmi(value)) { | 
|  211   //   return value; |  235   //   return value; | 
|  212   // } else if (%_GetInstanceType(%_GetMap(value)) == JS_VALUE_TYPE) { |  236   // } else if (%_GetInstanceType(%_GetMap(value)) == JS_VALUE_TYPE) { | 
|  213   //   return %_GetValue(value); |  237   //   return %_GetValue(value); | 
|  214   // } else { |  238   // } else { | 
|  215   //   return value; |  239   //   return value; | 
|  216   // } |  240   // } | 
|  217   const Operator* const merge_op = common()->Merge(2); |  241   const Operator* const merge_op = common()->Merge(2); | 
|  218   const Operator* const ephi_op = common()->EffectPhi(2); |  242   const Operator* const ephi_op = common()->EffectPhi(2); | 
|  219   const Operator* const phi_op = common()->Phi(kMachAnyTagged, 2); |  243   const Operator* const phi_op = common()->Phi(kMachAnyTagged, 2); | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  300 } |  324 } | 
|  301  |  325  | 
|  302  |  326  | 
|  303 MachineOperatorBuilder* JSIntrinsicLowering::machine() const { |  327 MachineOperatorBuilder* JSIntrinsicLowering::machine() const { | 
|  304   return jsgraph()->machine(); |  328   return jsgraph()->machine(); | 
|  305 } |  329 } | 
|  306  |  330  | 
|  307 }  // namespace compiler |  331 }  // namespace compiler | 
|  308 }  // namespace internal |  332 }  // namespace internal | 
|  309 }  // namespace v8 |  333 }  // namespace v8 | 
| OLD | NEW |