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

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 564843002: Initial steps towards cleaning up integer arithmetic IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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 (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 BinarySmiOpInstr* smi_shift_left = NULL; 284 BinarySmiOpInstr* smi_shift_left = NULL;
285 if (bit_and_instr->InputAt(0)->IsSingleUse()) { 285 if (bit_and_instr->InputAt(0)->IsSingleUse()) {
286 smi_shift_left = AsSmiShiftLeftInstruction(left_instr); 286 smi_shift_left = AsSmiShiftLeftInstruction(left_instr);
287 } 287 }
288 if ((smi_shift_left == NULL) && (bit_and_instr->InputAt(1)->IsSingleUse())) { 288 if ((smi_shift_left == NULL) && (bit_and_instr->InputAt(1)->IsSingleUse())) {
289 smi_shift_left = AsSmiShiftLeftInstruction(right_instr); 289 smi_shift_left = AsSmiShiftLeftInstruction(right_instr);
290 } 290 }
291 if (smi_shift_left == NULL) return; 291 if (smi_shift_left == NULL) return;
292 292
293 // Pattern recognized. 293 // Pattern recognized.
294 smi_shift_left->set_is_truncating(true); 294 smi_shift_left->mark_truncating();
295 ASSERT(bit_and_instr->IsBinarySmiOp() || bit_and_instr->IsBinaryMintOp()); 295 ASSERT(bit_and_instr->IsBinarySmiOp() || bit_and_instr->IsBinaryMintOp());
296 if (bit_and_instr->IsBinaryMintOp()) { 296 if (bit_and_instr->IsBinaryMintOp()) {
297 // Replace Mint op with Smi op. 297 // Replace Mint op with Smi op.
298 BinarySmiOpInstr* smi_op = new(I) BinarySmiOpInstr( 298 BinarySmiOpInstr* smi_op = new(I) BinarySmiOpInstr(
299 Token::kBIT_AND, 299 Token::kBIT_AND,
300 new(I) Value(left_instr), 300 new(I) Value(left_instr),
301 new(I) Value(right_instr), 301 new(I) Value(right_instr),
302 Isolate::kNoDeoptId, // BIT_AND cannot deoptimize. 302 Isolate::kNoDeoptId); // BIT_AND cannot deoptimize.
303 Scanner::kNoSourcePos);
304 bit_and_instr->ReplaceWith(smi_op, current_iterator()); 303 bit_and_instr->ReplaceWith(smi_op, current_iterator());
305 } 304 }
306 } 305 }
307 306
308 307
309 308
310 // Used by TryMergeDivMod. 309 // Used by TryMergeDivMod.
311 // Inserts a load-indexed instruction between a TRUNCDIV or MOD instruction, 310 // Inserts a load-indexed instruction between a TRUNCDIV or MOD instruction,
312 // and the using instruction. This is an intermediate step before merging. 311 // and the using instruction. This is an intermediate step before merging.
313 void FlowGraphOptimizer::AppendLoadIndexedForMerged(Definition* instr, 312 void FlowGraphOptimizer::AppendLoadIndexedForMerged(Definition* instr,
(...skipping 1928 matching lines...) Expand 10 before | Expand all | Expand 10 after
2242 call->token_pos()), 2241 call->token_pos()),
2243 call->env(), 2242 call->env(),
2244 FlowGraph::kEffect); 2243 FlowGraph::kEffect);
2245 ConstantInstr* constant = 2244 ConstantInstr* constant =
2246 flow_graph()->GetConstant(Smi::Handle(I, 2245 flow_graph()->GetConstant(Smi::Handle(I,
2247 Smi::New(Smi::Cast(obj).Value() - 1))); 2246 Smi::New(Smi::Cast(obj).Value() - 1)));
2248 BinarySmiOpInstr* bin_op = 2247 BinarySmiOpInstr* bin_op =
2249 new(I) BinarySmiOpInstr(Token::kBIT_AND, 2248 new(I) BinarySmiOpInstr(Token::kBIT_AND,
2250 new(I) Value(left), 2249 new(I) Value(left),
2251 new(I) Value(constant), 2250 new(I) Value(constant),
2252 call->deopt_id(), 2251 call->deopt_id());
2253 call->token_pos());
Cutch 2014/09/11 17:41:53 Why are we dropping the token position?
Vyacheslav Egorov (Google) 2014/09/11 19:50:47 Because it was not used anywhere. Remains of ancie
2254 ReplaceCall(call, bin_op); 2252 ReplaceCall(call, bin_op);
2255 return true; 2253 return true;
2256 } 2254 }
2257 } 2255 }
2258 // Insert two smi checks and attach a copy of the original 2256 // Insert two smi checks and attach a copy of the original
2259 // environment because the smi operation can still deoptimize. 2257 // environment because the smi operation can still deoptimize.
2260 AddCheckSmi(left, call->deopt_id(), call->env(), call); 2258 AddCheckSmi(left, call->deopt_id(), call->env(), call);
2261 AddCheckSmi(right, call->deopt_id(), call->env(), call); 2259 AddCheckSmi(right, call->deopt_id(), call->env(), call);
2262 BinarySmiOpInstr* bin_op = 2260 BinarySmiOpInstr* bin_op =
2263 new(I) BinarySmiOpInstr(op_kind, 2261 new(I) BinarySmiOpInstr(op_kind,
2264 new(I) Value(left), 2262 new(I) Value(left),
2265 new(I) Value(right), 2263 new(I) Value(right),
2266 call->deopt_id(), call->token_pos()); 2264 call->deopt_id());
2267 ReplaceCall(call, bin_op); 2265 ReplaceCall(call, bin_op);
2268 } else { 2266 } else {
2269 ASSERT(operands_type == kSmiCid); 2267 ASSERT(operands_type == kSmiCid);
2270 // Insert two smi checks and attach a copy of the original 2268 // Insert two smi checks and attach a copy of the original
2271 // environment because the smi operation can still deoptimize. 2269 // environment because the smi operation can still deoptimize.
2272 AddCheckSmi(left, call->deopt_id(), call->env(), call); 2270 AddCheckSmi(left, call->deopt_id(), call->env(), call);
2273 AddCheckSmi(right, call->deopt_id(), call->env(), call); 2271 AddCheckSmi(right, call->deopt_id(), call->env(), call);
2274 if (left->IsConstant() && 2272 if (left->IsConstant() &&
2275 ((op_kind == Token::kADD) || (op_kind == Token::kMUL))) { 2273 ((op_kind == Token::kADD) || (op_kind == Token::kMUL))) {
2276 // Constant should be on the right side. 2274 // Constant should be on the right side.
2277 Definition* temp = left; 2275 Definition* temp = left;
2278 left = right; 2276 left = right;
2279 right = temp; 2277 right = temp;
2280 } 2278 }
2281 BinarySmiOpInstr* bin_op = 2279 BinarySmiOpInstr* bin_op =
2282 new(I) BinarySmiOpInstr( 2280 new(I) BinarySmiOpInstr(
2283 op_kind, new(I) Value(left), new(I) Value(right), 2281 op_kind,
2284 call->deopt_id(), call->token_pos()); 2282 new(I) Value(left),
2283 new(I) Value(right),
2284 call->deopt_id());
2285 ReplaceCall(call, bin_op); 2285 ReplaceCall(call, bin_op);
2286 } 2286 }
2287 return true; 2287 return true;
2288 } 2288 }
2289 2289
2290 2290
2291 bool FlowGraphOptimizer::TryReplaceWithUnaryOp(InstanceCallInstr* call, 2291 bool FlowGraphOptimizer::TryReplaceWithUnaryOp(InstanceCallInstr* call,
2292 Token::Kind op_kind) { 2292 Token::Kind op_kind) {
2293 ASSERT(call->ArgumentCount() == 1); 2293 ASSERT(call->ArgumentCount() == 1);
2294 Definition* input = call->ArgumentAt(0); 2294 Definition* input = call->ArgumentAt(0);
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after
3164 const int64_t mask_value = mask_literal.AsInt64Value(); 3164 const int64_t mask_value = mask_literal.AsInt64Value();
3165 ASSERT(mask_value >= 0); 3165 ASSERT(mask_value >= 0);
3166 if (mask_value > Smi::kMaxValue) { 3166 if (mask_value > Smi::kMaxValue) {
3167 // The result will not be Smi. 3167 // The result will not be Smi.
3168 return false; 3168 return false;
3169 } 3169 }
3170 BinarySmiOpInstr* left_shift = 3170 BinarySmiOpInstr* left_shift =
3171 new(I) BinarySmiOpInstr(Token::kSHL, 3171 new(I) BinarySmiOpInstr(Token::kSHL,
3172 new(I) Value(value), 3172 new(I) Value(value),
3173 new(I) Value(count), 3173 new(I) Value(count),
3174 call->deopt_id(), call->token_pos()); 3174 call->deopt_id());
3175 left_shift->set_is_truncating(true); 3175 left_shift->mark_truncating();
3176 if ((kBitsPerWord == 32) && (mask_value == 0xffffffffLL)) { 3176 if ((kBitsPerWord == 32) && (mask_value == 0xffffffffLL)) {
3177 // No BIT_AND operation needed. 3177 // No BIT_AND operation needed.
3178 ReplaceCall(call, left_shift); 3178 ReplaceCall(call, left_shift);
3179 } else { 3179 } else {
3180 InsertBefore(call, left_shift, call->env(), FlowGraph::kValue); 3180 InsertBefore(call, left_shift, call->env(), FlowGraph::kValue);
3181 BinarySmiOpInstr* bit_and = 3181 BinarySmiOpInstr* bit_and =
3182 new(I) BinarySmiOpInstr(Token::kBIT_AND, 3182 new(I) BinarySmiOpInstr(Token::kBIT_AND,
3183 new(I) Value(left_shift), 3183 new(I) Value(left_shift),
3184 new(I) Value(int32_mask), 3184 new(I) Value(int32_mask),
3185 call->deopt_id(), 3185 call->deopt_id());
3186 call->token_pos());
3187 ReplaceCall(call, bit_and); 3186 ReplaceCall(call, bit_and);
3188 } 3187 }
3189 return true; 3188 return true;
3190 } 3189 }
3191 3190
3192 if (HasTwoMintOrSmi(ic_data) && 3191 if (HasTwoMintOrSmi(ic_data) &&
3193 HasOnlyOneSmi(ICData::Handle(I, 3192 HasOnlyOneSmi(ICData::Handle(I,
3194 ic_data.AsUnaryClassChecksForArgNr(1)))) { 3193 ic_data.AsUnaryClassChecksForArgNr(1)))) {
3195 if (!FlowGraphCompiler::SupportsUnboxedMints() || 3194 if (!FlowGraphCompiler::SupportsUnboxedMints() ||
3196 ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) { 3195 ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) {
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
3855 NULL, 3854 NULL,
3856 FlowGraph::kValue); 3855 FlowGraph::kValue);
3857 3856
3858 intptr_t element_size = Instance::ElementSizeFor(array_cid); 3857 intptr_t element_size = Instance::ElementSizeFor(array_cid);
3859 ConstantInstr* bytes_per_element = 3858 ConstantInstr* bytes_per_element =
3860 flow_graph()->GetConstant(Smi::Handle(I, Smi::New(element_size))); 3859 flow_graph()->GetConstant(Smi::Handle(I, Smi::New(element_size)));
3861 BinarySmiOpInstr* len_in_bytes = 3860 BinarySmiOpInstr* len_in_bytes =
3862 new(I) BinarySmiOpInstr(Token::kMUL, 3861 new(I) BinarySmiOpInstr(Token::kMUL,
3863 new(I) Value(length), 3862 new(I) Value(length),
3864 new(I) Value(bytes_per_element), 3863 new(I) Value(bytes_per_element),
3865 call->deopt_id(), call->token_pos()); 3864 call->deopt_id());
3866 *cursor = flow_graph()->AppendTo(*cursor, len_in_bytes, call->env(), 3865 *cursor = flow_graph()->AppendTo(*cursor, len_in_bytes, call->env(),
3867 FlowGraph::kValue); 3866 FlowGraph::kValue);
3868 3867
3869 // adjusted_length = len_in_bytes - (element_size - 1). 3868 // adjusted_length = len_in_bytes - (element_size - 1).
3870 Definition* adjusted_length = len_in_bytes; 3869 Definition* adjusted_length = len_in_bytes;
3871 intptr_t adjustment = Instance::ElementSizeFor(view_cid) - 1; 3870 intptr_t adjustment = Instance::ElementSizeFor(view_cid) - 1;
3872 if (adjustment > 0) { 3871 if (adjustment > 0) {
3873 ConstantInstr* length_adjustment = 3872 ConstantInstr* length_adjustment =
3874 flow_graph()->GetConstant(Smi::Handle(I, Smi::New(adjustment))); 3873 flow_graph()->GetConstant(Smi::Handle(I, Smi::New(adjustment)));
3875 adjusted_length = 3874 adjusted_length =
3876 new(I) BinarySmiOpInstr(Token::kSUB, 3875 new(I) BinarySmiOpInstr(Token::kSUB,
3877 new(I) Value(len_in_bytes), 3876 new(I) Value(len_in_bytes),
3878 new(I) Value(length_adjustment), 3877 new(I) Value(length_adjustment),
3879 call->deopt_id(), call->token_pos()); 3878 call->deopt_id());
3880 *cursor = flow_graph()->AppendTo(*cursor, adjusted_length, call->env(), 3879 *cursor = flow_graph()->AppendTo(*cursor, adjusted_length, call->env(),
3881 FlowGraph::kValue); 3880 FlowGraph::kValue);
3882 } 3881 }
3883 3882
3884 // Check adjusted_length > 0. 3883 // Check adjusted_length > 0.
3885 ConstantInstr* zero = 3884 ConstantInstr* zero =
3886 flow_graph()->GetConstant(Smi::Handle(I, Smi::New(0))); 3885 flow_graph()->GetConstant(Smi::Handle(I, Smi::New(0)));
3887 *cursor = flow_graph()->AppendTo(*cursor, 3886 *cursor = flow_graph()->AppendTo(*cursor,
3888 new(I) CheckArrayBoundInstr( 3887 new(I) CheckArrayBoundInstr(
3889 new(I) Value(adjusted_length), 3888 new(I) Value(adjusted_length),
(...skipping 3800 matching lines...) Expand 10 before | Expand all | Expand 10 after
7690 // cannot have constant values. 7689 // cannot have constant values.
7691 void ConstantPropagator::VisitStoreContext(StoreContextInstr* instr) { } 7690 void ConstantPropagator::VisitStoreContext(StoreContextInstr* instr) { }
7692 7691
7693 7692
7694 void ConstantPropagator::VisitCheckStackOverflow( 7693 void ConstantPropagator::VisitCheckStackOverflow(
7695 CheckStackOverflowInstr* instr) { } 7694 CheckStackOverflowInstr* instr) { }
7696 7695
7697 7696
7698 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) { } 7697 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) { }
7699 7698
7699
7700 void ConstantPropagator::VisitCheckClassId(CheckClassIdInstr* instr) { } 7700 void ConstantPropagator::VisitCheckClassId(CheckClassIdInstr* instr) { }
7701 7701
7702
7702 void ConstantPropagator::VisitGuardFieldClass(GuardFieldClassInstr* instr) { } 7703 void ConstantPropagator::VisitGuardFieldClass(GuardFieldClassInstr* instr) { }
7703 7704
7705
7704 void ConstantPropagator::VisitGuardFieldLength(GuardFieldLengthInstr* instr) { } 7706 void ConstantPropagator::VisitGuardFieldLength(GuardFieldLengthInstr* instr) { }
7705 7707
7708
7706 void ConstantPropagator::VisitCheckSmi(CheckSmiInstr* instr) { } 7709 void ConstantPropagator::VisitCheckSmi(CheckSmiInstr* instr) { }
7707 7710
7708 7711
7709 void ConstantPropagator::VisitCheckEitherNonSmi( 7712 void ConstantPropagator::VisitCheckEitherNonSmi(
7710 CheckEitherNonSmiInstr* instr) { } 7713 CheckEitherNonSmiInstr* instr) { }
7711 7714
7712 7715
7713 void ConstantPropagator::VisitCheckArrayBound(CheckArrayBoundInstr* instr) { } 7716 void ConstantPropagator::VisitCheckArrayBound(CheckArrayBoundInstr* instr) { }
7714 7717
7715 7718
7719 void ConstantPropagator::VisitDeoptimize(DeoptimizeInstr* instr) {
7720 // TODO(vegorov) remove all code after DeoptimizeInstr as dead.
7721 }
7722
7723
7716 // -------------------------------------------------------------------------- 7724 // --------------------------------------------------------------------------
7717 // Analysis of definitions. Compute the constant value. If it has changed 7725 // Analysis of definitions. Compute the constant value. If it has changed
7718 // and the definition has input uses, add the definition to the definition 7726 // and the definition has input uses, add the definition to the definition
7719 // worklist so that the used can be processed. 7727 // worklist so that the used can be processed.
7720 void ConstantPropagator::VisitPhi(PhiInstr* instr) { 7728 void ConstantPropagator::VisitPhi(PhiInstr* instr) {
7721 // Compute the join over all the reachable predecessor values. 7729 // Compute the join over all the reachable predecessor values.
7722 JoinEntryInstr* block = instr->block(); 7730 JoinEntryInstr* block = instr->block();
7723 Object& value = Object::ZoneHandle(I, Unknown()); 7731 Object& value = Object::ZoneHandle(I, Unknown());
7724 for (intptr_t pred_idx = 0; pred_idx < instr->InputCount(); ++pred_idx) { 7732 for (intptr_t pred_idx = 0; pred_idx < instr->InputCount(); ++pred_idx) {
7725 if (reachable_->Contains( 7733 if (reachable_->Contains(
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
8012 if (o.IsNull() || IsNonConstant(o)) { 8020 if (o.IsNull() || IsNonConstant(o)) {
8013 SetValue(instr, non_constant_); 8021 SetValue(instr, non_constant_);
8014 } else if (IsConstant(o)) { 8022 } else if (IsConstant(o)) {
8015 const String& str = String::Cast(o); 8023 const String& str = String::Cast(o);
8016 const intptr_t result = (str.Length() == 1) ? str.CharAt(0) : -1; 8024 const intptr_t result = (str.Length() == 1) ? str.CharAt(0) : -1;
8017 SetValue(instr, Smi::ZoneHandle(I, Smi::New(result))); 8025 SetValue(instr, Smi::ZoneHandle(I, Smi::New(result)));
8018 } 8026 }
8019 } 8027 }
8020 8028
8021 8029
8022
8023
8024 void ConstantPropagator::VisitStringInterpolate(StringInterpolateInstr* instr) { 8030 void ConstantPropagator::VisitStringInterpolate(StringInterpolateInstr* instr) {
8025 SetValue(instr, non_constant_); 8031 SetValue(instr, non_constant_);
8026 return;
8027 } 8032 }
8028 8033
8029 8034
8030 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { 8035 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) {
8031 const Object& array_obj = instr->array()->definition()->constant_value(); 8036 const Object& array_obj = instr->array()->definition()->constant_value();
8032 const Object& index_obj = instr->index()->definition()->constant_value(); 8037 const Object& index_obj = instr->index()->definition()->constant_value();
8033 if (IsNonConstant(array_obj) || IsNonConstant(index_obj)) { 8038 if (IsNonConstant(array_obj) || IsNonConstant(index_obj)) {
8034 SetValue(instr, non_constant_); 8039 SetValue(instr, non_constant_);
8035 } else if (IsConstant(array_obj) && IsConstant(index_obj)) { 8040 } else if (IsConstant(array_obj) && IsConstant(index_obj)) {
8036 // Need index to be Smi and array to be either String or an immutable array. 8041 // Need index to be Smi and array to be either String or an immutable array.
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
8258 AllocateUninitializedContextInstr* instr) { 8263 AllocateUninitializedContextInstr* instr) {
8259 SetValue(instr, non_constant_); 8264 SetValue(instr, non_constant_);
8260 } 8265 }
8261 8266
8262 8267
8263 void ConstantPropagator::VisitCloneContext(CloneContextInstr* instr) { 8268 void ConstantPropagator::VisitCloneContext(CloneContextInstr* instr) {
8264 SetValue(instr, non_constant_); 8269 SetValue(instr, non_constant_);
8265 } 8270 }
8266 8271
8267 8272
8268 void ConstantPropagator::HandleBinaryOp(Definition* instr, 8273 void ConstantPropagator::VisitBinaryIntegerOp(BinaryIntegerOpInstr* binary_op) {
8269 Token::Kind op_kind, 8274 const Object& left = binary_op->left()->definition()->constant_value();
8270 const Value& left_val, 8275 const Object& right = binary_op->right()->definition()->constant_value();
8271 const Value& right_val) { 8276 if (IsConstant(left) && IsConstant(right)) {
8272 const Object& left = left_val.definition()->constant_value();
8273 const Object& right = right_val.definition()->constant_value();
8274 if (IsNonConstant(left) || IsNonConstant(right)) {
8275 // TODO(srdjan): Add arithmetic simplifications, e.g, add with 0.
8276 SetValue(instr, non_constant_);
8277 } else if (IsConstant(left) && IsConstant(right)) {
8278 if (left.IsInteger() && right.IsInteger()) { 8277 if (left.IsInteger() && right.IsInteger()) {
8279 const Integer& left_int = Integer::Cast(left); 8278 const Integer& left_int = Integer::Cast(left);
8280 const Integer& right_int = Integer::Cast(right); 8279 const Integer& right_int = Integer::Cast(right);
8281 switch (op_kind) { 8280 const Integer& result =
8282 case Token::kTRUNCDIV: 8281 Integer::Handle(I, binary_op->Evaluate(left_int, right_int));
8283 case Token::kMOD: 8282 if (!result.IsNull()) {
8284 // Check right value for zero. 8283 SetValue(binary_op, Integer::ZoneHandle(I, result.raw()));
8285 if (right_int.AsInt64Value() == 0) { 8284 return;
8286 SetValue(instr, non_constant_);
8287 break;
8288 }
8289 // Fall through.
8290 case Token::kADD:
8291 case Token::kSUB:
8292 case Token::kMUL: {
8293 Instance& result = Integer::ZoneHandle(I,
8294 left_int.ArithmeticOp(op_kind, right_int));
8295 if (result.IsNull()) {
8296 // TODO(regis): A bigint operation is required. Invoke dart?
8297 // Punt for now.
8298 SetValue(instr, non_constant_);
8299 break;
8300 }
8301 result = result.CheckAndCanonicalize(NULL);
8302 ASSERT(!result.IsNull());
8303 SetValue(instr, result);
8304 break;
8305 }
8306 case Token::kSHL:
8307 case Token::kSHR:
8308 if (left.IsSmi() &&
8309 right.IsSmi() &&
8310 (Smi::Cast(right).Value() >= 0)) {
8311 Instance& result = Integer::ZoneHandle(I,
8312 Smi::Cast(left_int).ShiftOp(op_kind, Smi::Cast(right_int)));
8313 result = result.CheckAndCanonicalize(NULL);
8314 ASSERT(!result.IsNull());
8315 SetValue(instr, result);
8316 } else {
8317 SetValue(instr, non_constant_);
8318 }
8319 break;
8320 case Token::kBIT_AND:
8321 case Token::kBIT_OR:
8322 case Token::kBIT_XOR: {
8323 Instance& result = Integer::ZoneHandle(I,
8324 left_int.BitOp(op_kind, right_int));
8325 result = result.CheckAndCanonicalize(NULL);
8326 ASSERT(!result.IsNull());
8327 SetValue(instr, result);
8328 break;
8329 }
8330 case Token::kDIV:
8331 SetValue(instr, non_constant_);
8332 break;
8333 default:
8334 UNREACHABLE();
8335 } 8285 }
8336 } else {
8337 // TODO(kmillikin): support other types.
8338 SetValue(instr, non_constant_);
8339 } 8286 }
8340 } 8287 }
8341 }
8342 8288
8343 8289 SetValue(binary_op, non_constant_);
8344 void ConstantPropagator::TruncateInteger(Definition* defn, int64_t mask) {
8345 const Object& value = defn->constant_value();
8346 if (IsNonConstant(value)) {
8347 return;
8348 }
8349 ASSERT(IsConstant(value));
8350 if (!value.IsInteger()) {
8351 return;
8352 }
8353 const Integer& value_int = Integer::Cast(value);
8354 int64_t truncated = value_int.AsInt64Value() & mask;
8355 Instance& result = Integer::ZoneHandle(I, Integer::New(truncated));
8356 result = result.CheckAndCanonicalize(NULL);
8357 ASSERT(!result.IsNull());
8358 SetValue(defn, result);
8359 } 8290 }
8360 8291
8361 8292
8362 void ConstantPropagator::VisitBinarySmiOp(BinarySmiOpInstr* instr) { 8293 void ConstantPropagator::VisitBinarySmiOp(BinarySmiOpInstr* instr) {
8363 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right()); 8294 VisitBinaryIntegerOp(instr);
8364 } 8295 }
8365 8296
8366 8297
8367 void ConstantPropagator::VisitBinaryInt32Op(BinaryInt32OpInstr* instr) { 8298 void ConstantPropagator::VisitBinaryInt32Op(BinaryInt32OpInstr* instr) {
8368 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right()); 8299 VisitBinaryIntegerOp(instr);
8300 }
8301
8302
8303 void ConstantPropagator::VisitBinaryUint32Op(BinaryUint32OpInstr* instr) {
8304 VisitBinaryIntegerOp(instr);
8305 }
8306
8307
8308 void ConstantPropagator::VisitShiftUint32Op(ShiftUint32OpInstr* instr) {
8309 VisitBinaryIntegerOp(instr);
8310 }
8311
8312
8313 void ConstantPropagator::VisitBinaryMintOp(BinaryMintOpInstr* instr) {
8314 VisitBinaryIntegerOp(instr);
8315 }
8316
8317
8318 void ConstantPropagator::VisitShiftMintOp(ShiftMintOpInstr* instr) {
8319 VisitBinaryIntegerOp(instr);
8369 } 8320 }
8370 8321
8371 8322
8372 void ConstantPropagator::VisitBoxInteger(BoxIntegerInstr* instr) { 8323 void ConstantPropagator::VisitBoxInteger(BoxIntegerInstr* instr) {
8373 // TODO(kmillikin): Handle box operation. 8324 // TODO(kmillikin): Handle box operation.
8374 SetValue(instr, non_constant_); 8325 SetValue(instr, non_constant_);
8375 } 8326 }
8376 8327
8377 8328
8378 void ConstantPropagator::VisitUnboxInteger(UnboxIntegerInstr* instr) { 8329 void ConstantPropagator::VisitUnboxInteger(UnboxIntegerInstr* instr) {
8379 // TODO(kmillikin): Handle unbox operation. 8330 // TODO(kmillikin): Handle unbox operation.
8380 SetValue(instr, non_constant_); 8331 SetValue(instr, non_constant_);
8381 } 8332 }
8382 8333
8383 8334
8384 void ConstantPropagator::VisitBinaryMintOp(BinaryMintOpInstr* instr) {
8385 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right());
8386 }
8387
8388
8389 void ConstantPropagator::VisitShiftMintOp(ShiftMintOpInstr* instr) {
8390 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right());
8391 }
8392
8393
8394 void ConstantPropagator::VisitUnaryMintOp(UnaryMintOpInstr* instr) { 8335 void ConstantPropagator::VisitUnaryMintOp(UnaryMintOpInstr* instr) {
8395 // TODO(kmillikin): Handle unary operations. 8336 // TODO(kmillikin): Handle unary operations.
8396 SetValue(instr, non_constant_); 8337 SetValue(instr, non_constant_);
8397 } 8338 }
8398 8339
8399 8340
8400 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) { 8341 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) {
8401 const Object& value = instr->value()->definition()->constant_value(); 8342 const Object& value = instr->value()->definition()->constant_value();
8402 if (IsNonConstant(value)) { 8343 if (IsNonConstant(value)) {
8403 SetValue(instr, non_constant_); 8344 SetValue(instr, non_constant_);
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
8859 SetValue(instr, non_constant_); 8800 SetValue(instr, non_constant_);
8860 } 8801 }
8861 8802
8862 8803
8863 void ConstantPropagator::VisitUnboxedIntConverter( 8804 void ConstantPropagator::VisitUnboxedIntConverter(
8864 UnboxedIntConverterInstr* instr) { 8805 UnboxedIntConverterInstr* instr) {
8865 SetValue(instr, non_constant_); 8806 SetValue(instr, non_constant_);
8866 } 8807 }
8867 8808
8868 8809
8869 void ConstantPropagator::VisitBinaryUint32Op(BinaryUint32OpInstr* instr) {
8870 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right());
8871 TruncateInteger(instr, static_cast<int64_t>(0xFFFFFFFF));
8872 }
8873
8874
8875 void ConstantPropagator::VisitShiftUint32Op(ShiftUint32OpInstr* instr) {
8876 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right());
8877 TruncateInteger(instr, static_cast<int64_t>(0xFFFFFFFF));
8878 }
8879
8880
8881 void ConstantPropagator::VisitUnaryUint32Op(UnaryUint32OpInstr* instr) { 8810 void ConstantPropagator::VisitUnaryUint32Op(UnaryUint32OpInstr* instr) {
8882 // TODO(kmillikin): Handle unary operations. 8811 // TODO(kmillikin): Handle unary operations.
8883 SetValue(instr, non_constant_); 8812 SetValue(instr, non_constant_);
8884 } 8813 }
8885 8814
8886 8815
8887 void ConstantPropagator::Analyze() { 8816 void ConstantPropagator::Analyze() {
8888 GraphEntryInstr* entry = graph_->graph_entry(); 8817 GraphEntryInstr* entry = graph_->graph_entry();
8889 reachable_->Add(entry->preorder_number()); 8818 reachable_->Add(entry->preorder_number());
8890 block_worklist_.Add(entry); 8819 block_worklist_.Add(entry);
(...skipping 1202 matching lines...) Expand 10 before | Expand all | Expand 10 after
10093 10022
10094 // Insert materializations at environment uses. 10023 // Insert materializations at environment uses.
10095 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 10024 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
10096 CreateMaterializationAt( 10025 CreateMaterializationAt(
10097 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); 10026 exits_collector_.exits()[i], alloc, alloc->cls(), *slots);
10098 } 10027 }
10099 } 10028 }
10100 10029
10101 10030
10102 } // namespace dart 10031 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698