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 3387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3398 } | 3398 } |
3399 ComputeMinusZeroChecks(); | 3399 ComputeMinusZeroChecks(); |
3400 | 3400 |
3401 // Eliminate redundant stack checks on backwards branches. | 3401 // Eliminate redundant stack checks on backwards branches. |
3402 HStackCheckEliminator sce(this); | 3402 HStackCheckEliminator sce(this); |
3403 sce.Process(); | 3403 sce.Process(); |
3404 | 3404 |
3405 EliminateRedundantBoundsChecks(); | 3405 EliminateRedundantBoundsChecks(); |
3406 DehoistSimpleArrayIndexComputations(); | 3406 DehoistSimpleArrayIndexComputations(); |
3407 | 3407 |
3408 EliminateUnusedInstructions(); | |
3409 | |
3408 return true; | 3410 return true; |
3409 } | 3411 } |
3410 | 3412 |
3413 void HGraph::EliminateUnusedInstructions() { | |
3414 HPhase phase("H_EliminateUnusedInstructions", this); | |
ulan
2012/10/01 18:15:19
Maybe I should just do one pass instead of this co
| |
3415 ZoneList<HInstruction*> worklist(blocks_.length(), zone()); | |
3416 for (int i = 0; i < blocks()->length(); ++i) { | |
3417 HInstruction* instr = blocks()->at(i)->first(); | |
3418 while (instr != NULL) { | |
3419 if (instr->UnusedAndSafeToDelete()) { | |
3420 worklist.Add(instr, zone()); | |
3421 } | |
3422 instr = instr->next(); | |
3423 } | |
3424 } | |
3425 | |
3426 while (!worklist.is_empty()) { | |
3427 HInstruction* instr = worklist.RemoveLast(); | |
3428 instr->DeleteAndReplaceWith(NULL); | |
3429 for (int i = 0; i < instr->OperandCount(); ++i) { | |
3430 HValue* operand = instr->OperandAt(i); | |
3431 if (operand->IsInstruction() && | |
3432 HInstruction::cast(operand)->UnusedAndSafeToDelete()) { | |
3433 worklist.Add(HInstruction::cast(operand), zone()); | |
3434 } | |
3435 } | |
3436 } | |
3437 } | |
3411 | 3438 |
3412 // We try to "factor up" HBoundsCheck instructions towards the root of the | 3439 // We try to "factor up" HBoundsCheck instructions towards the root of the |
3413 // dominator tree. | 3440 // dominator tree. |
3414 // For now we handle checks where the index is like "exp + int32value". | 3441 // For now we handle checks where the index is like "exp + int32value". |
3415 // If in the dominator tree we check "exp + v1" and later (dominated) | 3442 // If in the dominator tree we check "exp + v1" and later (dominated) |
3416 // "exp + v2", if v2 <= v1 we can safely remove the second check, and if | 3443 // "exp + v2", if v2 <= v1 we can safely remove the second check, and if |
3417 // v2 > v1 we can use v2 in the 1st check and again remove the second. | 3444 // v2 > v1 we can use v2 in the 1st check and again remove the second. |
3418 // To do so we keep a dictionary of all checks where the key if the pair | 3445 // To do so we keep a dictionary of all checks where the key if the pair |
3419 // "exp, length". | 3446 // "exp, length". |
3420 // The class BoundsCheckKey represents this key. | 3447 // The class BoundsCheckKey represents this key. |
(...skipping 4826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8247 HValue* index) { | 8274 HValue* index) { |
8248 AddInstruction(new(zone()) HCheckNonSmi(string)); | 8275 AddInstruction(new(zone()) HCheckNonSmi(string)); |
8249 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 8276 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
8250 HStringLength* length = new(zone()) HStringLength(string); | 8277 HStringLength* length = new(zone()) HStringLength(string); |
8251 AddInstruction(length); | 8278 AddInstruction(length); |
8252 HInstruction* checked_index = | 8279 HInstruction* checked_index = |
8253 AddInstruction(new(zone()) HBoundsCheck(index, length)); | 8280 AddInstruction(new(zone()) HBoundsCheck(index, length)); |
8254 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 8281 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
8255 } | 8282 } |
8256 | 8283 |
8284 // Checks if the given shift amounts have form: (sa) and (32 - sa). | |
8285 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, | |
8286 HValue* const32_minus_sa) { | |
8287 if (!const32_minus_sa->IsSub()) return false; | |
8288 HSub* sub = HSub::cast(const32_minus_sa); | |
8289 HValue* const32 = sub->left(); | |
8290 if (!const32->IsConstant() || | |
8291 HConstant::cast(const32)->Integer32Value() != 32) { | |
8292 return false; | |
8293 } | |
8294 return (sub->right() == sa); | |
8295 } | |
8296 | |
8297 | |
8298 // Checks if the left and the right are shift instructions with the oposite | |
8299 // directions that can be replaced by one rotate right instruction or not. | |
8300 // Returns the operand and the shift amount for the rotate instruction in the | |
8301 // former case. | |
8302 bool HGraphBuilder::MatchRotateRight(HValue* left, | |
8303 HValue* right, | |
8304 HValue** operand, | |
8305 HValue** shift_amount) { | |
8306 HShl* shl; | |
8307 HShr* shr; | |
8308 if (left->IsShl() && right->IsShr()) { | |
8309 shl = HShl::cast(left); | |
8310 shr = HShr::cast(right); | |
8311 } else if (left->IsShr() && right->IsShl()) { | |
8312 shl = HShl::cast(right); | |
8313 shr = HShr::cast(left); | |
8314 } else { | |
8315 return false; | |
8316 } | |
8317 | |
8318 if (!ShiftAmountsAllowReplaceByRotate(shl->right(), shr->right()) && | |
8319 !ShiftAmountsAllowReplaceByRotate(shr->right(), shl->right())) { | |
8320 return false; | |
8321 } | |
8322 *operand= shr->left(); | |
8323 *shift_amount = shr->right(); | |
8324 return true; | |
8325 } | |
8326 | |
8327 | |
8328 bool CanBeZero(HValue *right) { | |
8329 if (right->IsConstant()) { | |
8330 HConstant* right_const = HConstant::cast(right); | |
8331 if (right_const->HasInteger32Value() && | |
8332 (right_const->Integer32Value() & 0x1f) != 0) { | |
8333 return false; | |
8334 } | |
8335 } | |
8336 return true; | |
8337 } | |
8338 | |
8257 | 8339 |
8258 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 8340 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, |
8259 HValue* left, | 8341 HValue* left, |
8260 HValue* right) { | 8342 HValue* right) { |
8261 HValue* context = environment()->LookupContext(); | 8343 HValue* context = environment()->LookupContext(); |
8262 TypeInfo info = oracle()->BinaryType(expr); | 8344 TypeInfo info = oracle()->BinaryType(expr); |
8263 if (info.IsUninitialized()) { | 8345 if (info.IsUninitialized()) { |
8264 AddInstruction(new(zone()) HSoftDeoptimize); | 8346 AddInstruction(new(zone()) HSoftDeoptimize); |
8265 current_block()->MarkAsDeoptimizing(); | 8347 current_block()->MarkAsDeoptimizing(); |
8266 info = TypeInfo::Unknown(); | 8348 info = TypeInfo::Unknown(); |
(...skipping 18 matching lines...) Expand all Loading... | |
8285 instr = HMul::NewHMul(zone(), context, left, right); | 8367 instr = HMul::NewHMul(zone(), context, left, right); |
8286 break; | 8368 break; |
8287 case Token::MOD: | 8369 case Token::MOD: |
8288 instr = HMod::NewHMod(zone(), context, left, right); | 8370 instr = HMod::NewHMod(zone(), context, left, right); |
8289 break; | 8371 break; |
8290 case Token::DIV: | 8372 case Token::DIV: |
8291 instr = HDiv::NewHDiv(zone(), context, left, right); | 8373 instr = HDiv::NewHDiv(zone(), context, left, right); |
8292 break; | 8374 break; |
8293 case Token::BIT_XOR: | 8375 case Token::BIT_XOR: |
8294 case Token::BIT_AND: | 8376 case Token::BIT_AND: |
8295 case Token::BIT_OR: | |
8296 instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left, right); | 8377 instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left, right); |
8297 break; | 8378 break; |
8379 case Token::BIT_OR: { | |
8380 HValue* operand, *shift_amount; | |
8381 if (info.IsInteger32() && | |
8382 MatchRotateRight(left, right, &operand, &shift_amount)) { | |
8383 instr = new(zone()) HRor(context, operand, shift_amount); | |
8384 } else { | |
8385 instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left, right); | |
8386 } | |
8387 break; | |
8388 } | |
8298 case Token::SAR: | 8389 case Token::SAR: |
8299 instr = HSar::NewHSar(zone(), context, left, right); | 8390 instr = HSar::NewHSar(zone(), context, left, right); |
8300 break; | 8391 break; |
8301 case Token::SHR: | 8392 case Token::SHR: |
8302 instr = HShr::NewHShr(zone(), context, left, right); | 8393 instr = HShr::NewHShr(zone(), context, left, right); |
8303 if (FLAG_opt_safe_uint32_operations && instr->IsShr()) { | 8394 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && |
8304 bool can_be_shift_by_zero = true; | 8395 CanBeZero(right)) { |
8305 if (right->IsConstant()) { | 8396 graph()->RecordUint32Instruction(instr); |
8306 HConstant* right_const = HConstant::cast(right); | |
8307 if (right_const->HasInteger32Value() && | |
8308 (right_const->Integer32Value() & 0x1f) != 0) { | |
8309 can_be_shift_by_zero = false; | |
8310 } | |
8311 } | |
8312 | |
8313 if (can_be_shift_by_zero) graph()->RecordUint32Instruction(instr); | |
8314 } | 8397 } |
8315 break; | 8398 break; |
8316 case Token::SHL: | 8399 case Token::SHL: |
8317 instr = HShl::NewHShl(zone(), context, left, right); | 8400 instr = HShl::NewHShl(zone(), context, left, right); |
8318 break; | 8401 break; |
8319 default: | 8402 default: |
8320 UNREACHABLE(); | 8403 UNREACHABLE(); |
8321 } | 8404 } |
8322 | 8405 |
8323 // If we hit an uninitialized binary op stub we will get type info | 8406 // If we hit an uninitialized binary op stub we will get type info |
(...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9983 } | 10066 } |
9984 } | 10067 } |
9985 | 10068 |
9986 #ifdef DEBUG | 10069 #ifdef DEBUG |
9987 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10070 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
9988 if (allocator_ != NULL) allocator_->Verify(); | 10071 if (allocator_ != NULL) allocator_->Verify(); |
9989 #endif | 10072 #endif |
9990 } | 10073 } |
9991 | 10074 |
9992 } } // namespace v8::internal | 10075 } } // namespace v8::internal |
OLD | NEW |