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

Side by Side Diff: src/hydrogen.cc

Issue 11377135: Don't emit code for instructions that are hiding behind an HSoftDeoptimize (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix rebasing error Created 8 years 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 | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698