OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1234 block->AssignCommonDominator(block->predecessors()->first()); | 1234 block->AssignCommonDominator(block->predecessors()->first()); |
1235 block->AssignLoopSuccessorDominators(); | 1235 block->AssignLoopSuccessorDominators(); |
1236 } else { | 1236 } else { |
1237 for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) { | 1237 for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) { |
1238 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); | 1238 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); |
1239 } | 1239 } |
1240 } | 1240 } |
1241 } | 1241 } |
1242 } | 1242 } |
1243 | 1243 |
1244 | |
1244 // Mark all blocks that are dominated by an unconditional soft deoptimize to | 1245 // Mark all blocks that are dominated by an unconditional soft deoptimize to |
1245 // prevent code motion across those blocks. | 1246 // prevent code motion across those blocks. |
1246 void HGraph::PropagateDeoptimizingMark() { | 1247 void HGraph::PropagateDeoptimizingMark() { |
1247 HPhase phase("H_Propagate deoptimizing mark", this); | 1248 HPhase phase("H_Propagate deoptimizing mark", this); |
1248 MarkAsDeoptimizingRecursively(entry_block()); | 1249 MarkAsDeoptimizingRecursively(entry_block()); |
1250 NullifyUnreachableInstructions(); | |
1249 } | 1251 } |
1250 | 1252 |
1253 | |
1251 void HGraph::MarkAsDeoptimizingRecursively(HBasicBlock* block) { | 1254 void HGraph::MarkAsDeoptimizingRecursively(HBasicBlock* block) { |
1252 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { | 1255 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { |
1253 HBasicBlock* dominated = block->dominated_blocks()->at(i); | 1256 HBasicBlock* dominated = block->dominated_blocks()->at(i); |
1254 if (block->IsDeoptimizing()) dominated->MarkAsDeoptimizing(); | 1257 if (block->IsDeoptimizing()) dominated->MarkAsDeoptimizing(); |
1255 MarkAsDeoptimizingRecursively(dominated); | 1258 MarkAsDeoptimizingRecursively(dominated); |
1256 } | 1259 } |
1257 } | 1260 } |
1258 | 1261 |
1262 | |
1263 void HGraph::NullifyUnreachableInstructions() { | |
danno
2013/01/10 12:30:05
Can you skip this pass all together if there are n
Jakob Kummerow
2013/01/16 11:35:02
I can skip the entire phase when there are no soft
| |
1264 int block_count = blocks_.length(); | |
1265 for (int i = 0; i < block_count; ++i) { | |
1266 HBasicBlock* block = blocks_.at(i); | |
1267 bool nullify = false; | |
1268 const ZoneList<HBasicBlock*>* predecessors = block->predecessors(); | |
1269 int predecessors_length = predecessors->length(); | |
1270 bool all_predecessors_deoptimizing = (predecessors_length > 0); | |
1271 for (int j = 0; j < predecessors_length; ++j) { | |
1272 if (!predecessors->at(j)->IsDeoptimizing()) { | |
1273 all_predecessors_deoptimizing = false; | |
1274 break; | |
1275 } | |
1276 } | |
1277 if (all_predecessors_deoptimizing) nullify = true; | |
1278 for (HInstruction* instr = block->first(); instr != NULL; | |
1279 instr = instr->next()) { | |
1280 // Leave the basic structure of the graph intact. | |
1281 if (instr->IsBlockEntry()) continue; | |
1282 if (instr->IsControlInstruction()) continue; | |
1283 if (instr->IsSimulate()) continue; | |
1284 if (instr->IsEnterInlined()) continue; | |
1285 if (instr->IsLeaveInlined()) continue; | |
1286 if (nullify) { | |
1287 HInstruction* last_dummy = NULL; | |
1288 for (int j = 0; j < instr->OperandCount(); ++j) { | |
1289 HValue* operand = instr->OperandAt(j); | |
1290 // Insert an HDummyUse for each operand, unless the operand | |
1291 // is an HDummyUse itself. If it's even from the same block, | |
1292 // remember it as a potential replacement for the instruction. | |
1293 if (operand->IsDummyUse()) { | |
1294 if (operand->block() == instr->block() && | |
1295 last_dummy == NULL) { | |
1296 last_dummy = HInstruction::cast(operand); | |
1297 } | |
1298 continue; | |
1299 } | |
1300 HDummyUse* dummy = new(zone()) HDummyUse(operand); | |
1301 dummy->InsertBefore(instr); | |
1302 last_dummy = dummy; | |
1303 } | |
1304 if (last_dummy == NULL) last_dummy = GetConstant1(); | |
1305 instr->DeleteAndReplaceWith(last_dummy); | |
1306 continue; | |
1307 } | |
1308 if (instr->IsSoftDeoptimize()) { | |
1309 ASSERT(block->IsDeoptimizing()); | |
1310 nullify = true; | |
1311 } | |
1312 } | |
1313 } | |
1314 } | |
1315 | |
1316 | |
1259 void HGraph::EliminateRedundantPhis() { | 1317 void HGraph::EliminateRedundantPhis() { |
1260 HPhase phase("H_Redundant phi elimination", this); | 1318 HPhase phase("H_Redundant phi elimination", this); |
1261 | 1319 |
1262 // Worklist of phis that can potentially be eliminated. Initialized with | 1320 // Worklist of phis that can potentially be eliminated. Initialized with |
1263 // all phi nodes. When elimination of a phi node modifies another phi node | 1321 // all phi nodes. When elimination of a phi node modifies another phi node |
1264 // the modified phi node is added to the worklist. | 1322 // the modified phi node is added to the worklist. |
1265 ZoneList<HPhi*> worklist(blocks_.length(), zone()); | 1323 ZoneList<HPhi*> worklist(blocks_.length(), zone()); |
1266 for (int i = 0; i < blocks_.length(); ++i) { | 1324 for (int i = 0; i < blocks_.length(); ++i) { |
1267 worklist.AddAll(*blocks_[i]->phis(), zone()); | 1325 worklist.AddAll(*blocks_[i]->phis(), zone()); |
1268 } | 1326 } |
(...skipping 2681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3950 current_block()->AddPhi(instr); | 4008 current_block()->AddPhi(instr); |
3951 } | 4009 } |
3952 | 4010 |
3953 | 4011 |
3954 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { | 4012 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { |
3955 Push(instr); | 4013 Push(instr); |
3956 AddInstruction(instr); | 4014 AddInstruction(instr); |
3957 } | 4015 } |
3958 | 4016 |
3959 | 4017 |
4018 void HOptimizedGraphBuilder::AddSoftDeoptimize() { | |
4019 if (FLAG_always_opt) return; | |
4020 if (current_block()->IsDeoptimizing()) return; | |
4021 AddInstruction(new(zone()) HSoftDeoptimize()); | |
4022 current_block()->MarkAsDeoptimizing(); | |
4023 } | |
4024 | |
4025 | |
3960 template <class Instruction> | 4026 template <class Instruction> |
3961 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | 4027 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
3962 int count = call->argument_count(); | 4028 int count = call->argument_count(); |
3963 ZoneList<HValue*> arguments(count, zone()); | 4029 ZoneList<HValue*> arguments(count, zone()); |
3964 for (int i = 0; i < count; ++i) { | 4030 for (int i = 0; i < count; ++i) { |
3965 arguments.Add(Pop(), zone()); | 4031 arguments.Add(Pop(), zone()); |
3966 } | 4032 } |
3967 | 4033 |
3968 while (!arguments.is_empty()) { | 4034 while (!arguments.is_empty()) { |
3969 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); | 4035 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); |
(...skipping 2149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6119 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; | 6185 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
6120 return new(zone()) HLoadNamedField(object, false, offset); | 6186 return new(zone()) HLoadNamedField(object, false, offset); |
6121 } | 6187 } |
6122 } | 6188 } |
6123 | 6189 |
6124 | 6190 |
6125 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 6191 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
6126 HValue* object, | 6192 HValue* object, |
6127 Handle<String> name, | 6193 Handle<String> name, |
6128 Property* expr) { | 6194 Property* expr) { |
6129 if (expr->IsUninitialized() && !FLAG_always_opt) { | 6195 if (expr->IsUninitialized()) { |
6130 AddInstruction(new(zone()) HSoftDeoptimize); | 6196 AddSoftDeoptimize(); |
6131 current_block()->MarkAsDeoptimizing(); | |
6132 } | 6197 } |
6133 HValue* context = environment()->LookupContext(); | 6198 HValue* context = environment()->LookupContext(); |
6134 return new(zone()) HLoadNamedGeneric(context, object, name); | 6199 return new(zone()) HLoadNamedGeneric(context, object, name); |
6135 } | 6200 } |
6136 | 6201 |
6137 | 6202 |
6138 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( | 6203 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( |
6139 HValue* object, | 6204 HValue* object, |
6140 Handle<Map> map, | 6205 Handle<Map> map, |
6141 Handle<JSFunction> getter, | 6206 Handle<JSFunction> getter, |
(...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8013 | 8078 |
8014 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { | 8079 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { |
8015 CHECK_ALIVE(VisitForValue(expr->expression())); | 8080 CHECK_ALIVE(VisitForValue(expr->expression())); |
8016 HValue* value = Pop(); | 8081 HValue* value = Pop(); |
8017 HValue* context = environment()->LookupContext(); | 8082 HValue* context = environment()->LookupContext(); |
8018 HInstruction* instr = | 8083 HInstruction* instr = |
8019 new(zone()) HMul(context, value, graph()->GetConstantMinus1()); | 8084 new(zone()) HMul(context, value, graph()->GetConstantMinus1()); |
8020 TypeInfo info = oracle()->UnaryType(expr); | 8085 TypeInfo info = oracle()->UnaryType(expr); |
8021 Representation rep = ToRepresentation(info); | 8086 Representation rep = ToRepresentation(info); |
8022 if (info.IsUninitialized()) { | 8087 if (info.IsUninitialized()) { |
8023 AddInstruction(new(zone()) HSoftDeoptimize); | 8088 AddSoftDeoptimize(); |
8024 current_block()->MarkAsDeoptimizing(); | |
8025 info = TypeInfo::Unknown(); | 8089 info = TypeInfo::Unknown(); |
8026 } | 8090 } |
8027 HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep); | 8091 HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep); |
8028 return ast_context()->ReturnInstruction(instr, expr->id()); | 8092 return ast_context()->ReturnInstruction(instr, expr->id()); |
8029 } | 8093 } |
8030 | 8094 |
8031 | 8095 |
8032 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { | 8096 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { |
8033 CHECK_ALIVE(VisitForValue(expr->expression())); | 8097 CHECK_ALIVE(VisitForValue(expr->expression())); |
8034 HValue* value = Pop(); | 8098 HValue* value = Pop(); |
8035 TypeInfo info = oracle()->UnaryType(expr); | 8099 TypeInfo info = oracle()->UnaryType(expr); |
8036 if (info.IsUninitialized()) { | 8100 if (info.IsUninitialized()) { |
8037 AddInstruction(new(zone()) HSoftDeoptimize); | 8101 AddSoftDeoptimize(); |
8038 current_block()->MarkAsDeoptimizing(); | |
8039 } | 8102 } |
8040 HInstruction* instr = new(zone()) HBitNot(value); | 8103 HInstruction* instr = new(zone()) HBitNot(value); |
8041 return ast_context()->ReturnInstruction(instr, expr->id()); | 8104 return ast_context()->ReturnInstruction(instr, expr->id()); |
8042 } | 8105 } |
8043 | 8106 |
8044 | 8107 |
8045 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { | 8108 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { |
8046 if (ast_context()->IsTest()) { | 8109 if (ast_context()->IsTest()) { |
8047 TestContext* context = TestContext::cast(ast_context()); | 8110 TestContext* context = TestContext::cast(ast_context()); |
8048 VisitForControl(expr->expression(), | 8111 VisitForControl(expr->expression(), |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8384 HValue* right) { | 8447 HValue* right) { |
8385 HValue* context = environment()->LookupContext(); | 8448 HValue* context = environment()->LookupContext(); |
8386 TypeInfo left_info, right_info, result_info, combined_info; | 8449 TypeInfo left_info, right_info, result_info, combined_info; |
8387 oracle()->BinaryType(expr, &left_info, &right_info, &result_info); | 8450 oracle()->BinaryType(expr, &left_info, &right_info, &result_info); |
8388 Representation left_rep = ToRepresentation(left_info); | 8451 Representation left_rep = ToRepresentation(left_info); |
8389 Representation right_rep = ToRepresentation(right_info); | 8452 Representation right_rep = ToRepresentation(right_info); |
8390 Representation result_rep = ToRepresentation(result_info); | 8453 Representation result_rep = ToRepresentation(result_info); |
8391 if (left_info.IsUninitialized()) { | 8454 if (left_info.IsUninitialized()) { |
8392 // Can't have initialized one but not the other. | 8455 // Can't have initialized one but not the other. |
8393 ASSERT(right_info.IsUninitialized()); | 8456 ASSERT(right_info.IsUninitialized()); |
8394 AddInstruction(new(zone()) HSoftDeoptimize); | 8457 AddSoftDeoptimize(); |
8395 current_block()->MarkAsDeoptimizing(); | |
8396 left_info = right_info = TypeInfo::Unknown(); | 8458 left_info = right_info = TypeInfo::Unknown(); |
8397 } | 8459 } |
8398 HInstruction* instr = NULL; | 8460 HInstruction* instr = NULL; |
8399 switch (expr->op()) { | 8461 switch (expr->op()) { |
8400 case Token::ADD: | 8462 case Token::ADD: |
8401 if (left_info.IsString() && right_info.IsString()) { | 8463 if (left_info.IsString() && right_info.IsString()) { |
8402 AddInstruction(new(zone()) HCheckNonSmi(left)); | 8464 AddInstruction(new(zone()) HCheckNonSmi(left)); |
8403 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); | 8465 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
8404 AddInstruction(new(zone()) HCheckNonSmi(right)); | 8466 AddInstruction(new(zone()) HCheckNonSmi(right)); |
8405 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | 8467 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8699 } | 8761 } |
8700 | 8762 |
8701 TypeInfo left_type, right_type, overall_type_info; | 8763 TypeInfo left_type, right_type, overall_type_info; |
8702 oracle()->CompareType(expr, &left_type, &right_type, &overall_type_info); | 8764 oracle()->CompareType(expr, &left_type, &right_type, &overall_type_info); |
8703 Representation combined_rep = ToRepresentation(overall_type_info); | 8765 Representation combined_rep = ToRepresentation(overall_type_info); |
8704 Representation left_rep = ToRepresentation(left_type); | 8766 Representation left_rep = ToRepresentation(left_type); |
8705 Representation right_rep = ToRepresentation(right_type); | 8767 Representation right_rep = ToRepresentation(right_type); |
8706 // Check if this expression was ever executed according to type feedback. | 8768 // Check if this expression was ever executed according to type feedback. |
8707 // Note that for the special typeof/null/undefined cases we get unknown here. | 8769 // Note that for the special typeof/null/undefined cases we get unknown here. |
8708 if (overall_type_info.IsUninitialized()) { | 8770 if (overall_type_info.IsUninitialized()) { |
8709 AddInstruction(new(zone()) HSoftDeoptimize); | 8771 AddSoftDeoptimize(); |
8710 current_block()->MarkAsDeoptimizing(); | |
8711 overall_type_info = left_type = right_type = TypeInfo::Unknown(); | 8772 overall_type_info = left_type = right_type = TypeInfo::Unknown(); |
8712 } | 8773 } |
8713 | 8774 |
8714 CHECK_ALIVE(VisitForValue(expr->left())); | 8775 CHECK_ALIVE(VisitForValue(expr->left())); |
8715 CHECK_ALIVE(VisitForValue(expr->right())); | 8776 CHECK_ALIVE(VisitForValue(expr->right())); |
8716 | 8777 |
8717 HValue* context = environment()->LookupContext(); | 8778 HValue* context = environment()->LookupContext(); |
8718 HValue* right = Pop(); | 8779 HValue* right = Pop(); |
8719 HValue* left = Pop(); | 8780 HValue* left = Pop(); |
8720 Token::Value op = expr->op(); | 8781 Token::Value op = expr->op(); |
(...skipping 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10170 } | 10231 } |
10171 } | 10232 } |
10172 | 10233 |
10173 #ifdef DEBUG | 10234 #ifdef DEBUG |
10174 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10235 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
10175 if (allocator_ != NULL) allocator_->Verify(); | 10236 if (allocator_ != NULL) allocator_->Verify(); |
10176 #endif | 10237 #endif |
10177 } | 10238 } |
10178 | 10239 |
10179 } } // namespace v8::internal | 10240 } } // namespace v8::internal |
OLD | NEW |