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

Side by Side Diff: src/hydrogen.cc

Issue 11033005: Add rotate-right instruction to hydrogen and use it instead of bitwise operations (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 2 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 | 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 3387 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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