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

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

Issue 1858283002: Initial SIMDBC interpreter. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « runtime/vm/instructions_dbc.cc ('k') | runtime/vm/intermediate_language_dbc.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/bootstrap.h" 8 #include "vm/bootstrap.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/constant_propagator.h" 10 #include "vm/constant_propagator.h"
(...skipping 15 matching lines...) Expand all
26 #include "vm/symbols.h" 26 #include "vm/symbols.h"
27 27
28 #include "vm/il_printer.h" 28 #include "vm/il_printer.h"
29 29
30 namespace dart { 30 namespace dart {
31 31
32 DEFINE_FLAG(bool, propagate_ic_data, true, 32 DEFINE_FLAG(bool, propagate_ic_data, true,
33 "Propagate IC data from unoptimized to optimized IC calls."); 33 "Propagate IC data from unoptimized to optimized IC calls.");
34 DEFINE_FLAG(bool, two_args_smi_icd, true, 34 DEFINE_FLAG(bool, two_args_smi_icd, true,
35 "Generate special IC stubs for two args Smi operations"); 35 "Generate special IC stubs for two args Smi operations");
36 DEFINE_FLAG(bool, unbox_numeric_fields, true, 36 DEFINE_FLAG(bool, unbox_numeric_fields, !USING_DBC,
37 "Support unboxed double and float32x4 fields."); 37 "Support unboxed double and float32x4 fields.");
38 DECLARE_FLAG(bool, eliminate_type_checks); 38 DECLARE_FLAG(bool, eliminate_type_checks);
39 DECLARE_FLAG(bool, support_externalizable_strings); 39 DECLARE_FLAG(bool, support_externalizable_strings);
40 40
41 41
42 #if defined(DEBUG) 42 #if defined(DEBUG)
43 void Instruction::CheckField(const Field& field) const { 43 void Instruction::CheckField(const Field& field) const {
44 ASSERT(field.IsZoneHandle()); 44 ASSERT(field.IsZoneHandle());
45 ASSERT(!Compiler::IsBackgroundCompilation() || !field.IsOriginal()); 45 ASSERT(!Compiler::IsBackgroundCompilation() || !field.IsOriginal());
46 } 46 }
(...skipping 2712 matching lines...) Expand 10 before | Expand all | Expand 10 after
2759 LocationSummary* TargetEntryInstr::MakeLocationSummary(Zone* zone, 2759 LocationSummary* TargetEntryInstr::MakeLocationSummary(Zone* zone,
2760 bool optimizing) const { 2760 bool optimizing) const {
2761 UNREACHABLE(); 2761 UNREACHABLE();
2762 return NULL; 2762 return NULL;
2763 } 2763 }
2764 2764
2765 2765
2766 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2766 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2767 __ Bind(compiler->GetJumpLabel(this)); 2767 __ Bind(compiler->GetJumpLabel(this));
2768 if (!compiler->is_optimizing()) { 2768 if (!compiler->is_optimizing()) {
2769 #if !defined(TARGET_ARCH_DBC)
2770 // TODO(vegorov) re-enable edge counters on DBC if we consider them
2771 // beneficial for the quality of the optimized bytecode.
2769 if (compiler->NeedsEdgeCounter(this)) { 2772 if (compiler->NeedsEdgeCounter(this)) {
2770 compiler->EmitEdgeCounter(preorder_number()); 2773 compiler->EmitEdgeCounter(preorder_number());
2771 } 2774 }
2775 #endif
2776
2772 // The deoptimization descriptor points after the edge counter code for 2777 // The deoptimization descriptor points after the edge counter code for
2773 // uniformity with ARM and MIPS, where we can reuse pattern matching 2778 // uniformity with ARM and MIPS, where we can reuse pattern matching
2774 // code that matches backwards from the end of the pattern. 2779 // code that matches backwards from the end of the pattern.
2775 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, 2780 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
2776 GetDeoptId(), 2781 GetDeoptId(),
2777 TokenPosition::kNoSource); 2782 TokenPosition::kNoSource);
2778 } 2783 }
2779 if (HasParallelMove()) { 2784 if (HasParallelMove()) {
2780 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 2785 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
2781 } 2786 }
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
2961 Location::SameAsFirstInput(), 2966 Location::SameAsFirstInput(),
2962 LocationSummary::kNoCall) 2967 LocationSummary::kNoCall)
2963 : LocationSummary::Make(zone, 2968 : LocationSummary::Make(zone,
2964 0, 2969 0,
2965 Location::NoLocation(), 2970 Location::NoLocation(),
2966 LocationSummary::kNoCall); 2971 LocationSummary::kNoCall);
2967 } 2972 }
2968 2973
2969 2974
2970 void DropTempsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2975 void DropTempsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2976 #if defined(TARGET_ARCH_DBC)
2977 // On DBC the action of poping the TOS value and then pushing it
2978 // after all intermediates are poped is folded into a special
2979 // bytecode (DropR). On other architectures this is handled by
2980 // instruction prologue/epilogues.
2981 ASSERT(!compiler->is_optimizing());
2982 if ((InputCount() != 0) && HasTemp()) {
2983 __ DropR(num_temps());
2984 } else {
2985 __ Drop(num_temps() + ((InputCount() != 0) ? 1 : 0));
2986 }
2987 #else
2971 ASSERT(!compiler->is_optimizing()); 2988 ASSERT(!compiler->is_optimizing());
2972 // Assert that register assignment is correct. 2989 // Assert that register assignment is correct.
2973 ASSERT((InputCount() == 0) || (locs()->out(0).reg() == locs()->in(0).reg())); 2990 ASSERT((InputCount() == 0) || (locs()->out(0).reg() == locs()->in(0).reg()));
2974 __ Drop(num_temps()); 2991 __ Drop(num_temps());
2992 #endif // defined(TARGET_ARCH_DBC)
2975 } 2993 }
2976 2994
2977 2995
2978 StrictCompareInstr::StrictCompareInstr(TokenPosition token_pos, 2996 StrictCompareInstr::StrictCompareInstr(TokenPosition token_pos,
2979 Token::Kind kind, 2997 Token::Kind kind,
2980 Value* left, 2998 Value* left,
2981 Value* right, 2999 Value* right,
2982 bool needs_number_check) 3000 bool needs_number_check)
2983 : ComparisonInstr(token_pos, 3001 : ComparisonInstr(token_pos,
2984 kind, 3002 kind,
2985 left, 3003 left,
2986 right, 3004 right,
2987 Thread::Current()->GetNextDeoptId()), 3005 Thread::Current()->GetNextDeoptId()),
2988 needs_number_check_(needs_number_check) { 3006 needs_number_check_(needs_number_check) {
2989 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); 3007 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT));
2990 } 3008 }
2991 3009
2992 3010
2993 LocationSummary* InstanceCallInstr::MakeLocationSummary(Zone* zone, 3011 LocationSummary* InstanceCallInstr::MakeLocationSummary(Zone* zone,
2994 bool optimizing) const { 3012 bool optimizing) const {
2995 return MakeCallSummary(zone); 3013 return MakeCallSummary(zone);
2996 } 3014 }
2997 3015
2998 3016
3017 // DBC does not use specialized inline cache stubs for smi operations.
3018 #if !defined(TARGET_ARCH_DBC)
2999 static const StubEntry* TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) { 3019 static const StubEntry* TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) {
3000 if (!FLAG_two_args_smi_icd) { 3020 if (!FLAG_two_args_smi_icd) {
3001 return 0; 3021 return 0;
3002 } 3022 }
3003 switch (kind) { 3023 switch (kind) {
3004 case Token::kADD: return StubCode::SmiAddInlineCache_entry(); 3024 case Token::kADD: return StubCode::SmiAddInlineCache_entry();
3005 case Token::kSUB: return StubCode::SmiSubInlineCache_entry(); 3025 case Token::kSUB: return StubCode::SmiSubInlineCache_entry();
3006 case Token::kEQ: return StubCode::SmiEqualInlineCache_entry(); 3026 case Token::kEQ: return StubCode::SmiEqualInlineCache_entry();
3007 default: return NULL; 3027 default: return NULL;
3008 } 3028 }
3009 } 3029 }
3030 #endif
3010 3031
3011 3032
3012 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3033 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3013 Zone* zone = compiler->zone(); 3034 Zone* zone = compiler->zone();
3014 const ICData* call_ic_data = NULL; 3035 const ICData* call_ic_data = NULL;
3015 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() || 3036 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() ||
3016 (ic_data() == NULL)) { 3037 (ic_data() == NULL)) {
3017 const Array& arguments_descriptor = 3038 const Array& arguments_descriptor =
3018 Array::Handle(zone, ArgumentsDescriptor::New(ArgumentCount(), 3039 Array::Handle(zone, ArgumentsDescriptor::New(ArgumentCount(),
3019 argument_names())); 3040 argument_names()));
3020 call_ic_data = compiler->GetOrAddInstanceCallICData( 3041 call_ic_data = compiler->GetOrAddInstanceCallICData(
3021 deopt_id(), function_name(), arguments_descriptor, 3042 deopt_id(), function_name(), arguments_descriptor,
3022 checked_argument_count()); 3043 checked_argument_count());
3023 } else { 3044 } else {
3024 call_ic_data = &ICData::ZoneHandle(zone, ic_data()->raw()); 3045 call_ic_data = &ICData::ZoneHandle(zone, ic_data()->raw());
3025 } 3046 }
3047
3048 #if !defined(TARGET_ARCH_DBC)
3026 if (compiler->is_optimizing() && HasICData()) { 3049 if (compiler->is_optimizing() && HasICData()) {
3027 ASSERT(HasICData()); 3050 ASSERT(HasICData());
3028 if (ic_data()->NumberOfUsedChecks() > 0) { 3051 if (ic_data()->NumberOfUsedChecks() > 0) {
3029 const ICData& unary_ic_data = 3052 const ICData& unary_ic_data =
3030 ICData::ZoneHandle(zone, ic_data()->AsUnaryClassChecks()); 3053 ICData::ZoneHandle(zone, ic_data()->AsUnaryClassChecks());
3031 compiler->GenerateInstanceCall(deopt_id(), 3054 compiler->GenerateInstanceCall(deopt_id(),
3032 token_pos(), 3055 token_pos(),
3033 ArgumentCount(), 3056 ArgumentCount(),
3034 locs(), 3057 locs(),
3035 unary_ic_data); 3058 unary_ic_data);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3089 compiler->EmitInstanceCall(*stub_entry, *call_ic_data, ArgumentCount(), 3112 compiler->EmitInstanceCall(*stub_entry, *call_ic_data, ArgumentCount(),
3090 deopt_id(), token_pos(), locs()); 3113 deopt_id(), token_pos(), locs());
3091 } else { 3114 } else {
3092 compiler->GenerateInstanceCall(deopt_id(), 3115 compiler->GenerateInstanceCall(deopt_id(),
3093 token_pos(), 3116 token_pos(),
3094 ArgumentCount(), 3117 ArgumentCount(),
3095 locs(), 3118 locs(),
3096 *call_ic_data); 3119 *call_ic_data);
3097 } 3120 }
3098 } 3121 }
3122 #else
3123 // Emit smi fast path instruction. If fast-path succeeds it skips the next
3124 // instruction otherwise it falls through.
3125 if (function_name().raw() == Symbols::Plus().raw()) {
3126 __ AddTOS();
3127 } else if (function_name().raw() == Symbols::EqualOperator().raw()) {
3128 __ EqualTOS();
3129 } else if (function_name().raw() == Symbols::LAngleBracket().raw()) {
3130 __ LessThanTOS();
3131 } else if (function_name().raw() == Symbols::RAngleBracket().raw()) {
3132 __ GreaterThanTOS();
3133 } else if (function_name().raw() == Symbols::BitAnd().raw()) {
3134 __ BitAndTOS();
3135 } else if (function_name().raw() == Symbols::BitOr().raw()) {
3136 __ BitOrTOS();
3137 } else if (function_name().raw() == Symbols::Star().raw()) {
3138 __ MulTOS();
3139 }
3140
3141 const intptr_t call_ic_data_kidx = __ AddConstant(*call_ic_data);
3142 switch (call_ic_data->NumArgsTested()) {
3143 case 1:
3144 __ InstanceCall(ArgumentCount(), call_ic_data_kidx);
3145 break;
3146 case 2:
3147 __ InstanceCall2(ArgumentCount(), call_ic_data_kidx);
3148 break;
3149 case 3:
3150 __ InstanceCall3(ArgumentCount(), call_ic_data_kidx);
3151 break;
3152 default:
3153 UNIMPLEMENTED();
3154 break;
3155 }
3156 compiler->AddCurrentDescriptor(RawPcDescriptors::kIcCall,
3157 deopt_id(),
3158 token_pos());
3159 #endif // !defined(TARGET_ARCH_DBC)
3099 } 3160 }
3100 3161
3101 3162
3102 bool PolymorphicInstanceCallInstr::HasSingleRecognizedTarget() const { 3163 bool PolymorphicInstanceCallInstr::HasSingleRecognizedTarget() const {
3103 return ic_data().HasOneTarget() && 3164 return ic_data().HasOneTarget() &&
3104 (MethodRecognizer::RecognizeKind( 3165 (MethodRecognizer::RecognizeKind(
3105 Function::Handle(ic_data().GetTargetAt(0))) != 3166 Function::Handle(ic_data().GetTargetAt(0))) !=
3106 MethodRecognizer::kUnknown); 3167 MethodRecognizer::kUnknown);
3107 } 3168 }
3108 3169
3109 3170
3110 bool PolymorphicInstanceCallInstr::HasOnlyDispatcherTargets() const { 3171 bool PolymorphicInstanceCallInstr::HasOnlyDispatcherTargets() const {
3111 for (intptr_t i = 0; i < ic_data().NumberOfChecks(); ++i) { 3172 for (intptr_t i = 0; i < ic_data().NumberOfChecks(); ++i) {
3112 const Function& target = Function::Handle(ic_data().GetTargetAt(i)); 3173 const Function& target = Function::Handle(ic_data().GetTargetAt(i));
3113 if (!target.IsNoSuchMethodDispatcher() && 3174 if (!target.IsNoSuchMethodDispatcher() &&
3114 !target.IsInvokeFieldDispatcher()) { 3175 !target.IsInvokeFieldDispatcher()) {
3115 return false; 3176 return false;
3116 } 3177 }
3117 } 3178 }
3118 return true; 3179 return true;
3119 } 3180 }
3120 3181
3182
3183 // DBC does not support optimizing compiler and thus doesn't emit
3184 // PolymorphicInstanceCallInstr.
3185 #if !defined(TARGET_ARCH_DBC)
3121 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3186 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3122 ASSERT(ic_data().NumArgsTested() == 1); 3187 ASSERT(ic_data().NumArgsTested() == 1);
3123 if (!with_checks()) { 3188 if (!with_checks()) {
3124 ASSERT(ic_data().HasOneTarget()); 3189 ASSERT(ic_data().HasOneTarget());
3125 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); 3190 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0));
3126 compiler->GenerateStaticCall(deopt_id(), 3191 compiler->GenerateStaticCall(deopt_id(),
3127 instance_call()->token_pos(), 3192 instance_call()->token_pos(),
3128 target, 3193 target,
3129 instance_call()->ArgumentCount(), 3194 instance_call()->ArgumentCount(),
3130 instance_call()->argument_names(), 3195 instance_call()->argument_names(),
3131 locs(), 3196 locs(),
3132 ICData::Handle()); 3197 ICData::Handle());
3133 return; 3198 return;
3134 } 3199 }
3135 3200
3136 compiler->EmitPolymorphicInstanceCall(ic_data(), 3201 compiler->EmitPolymorphicInstanceCall(ic_data(),
3137 instance_call()->ArgumentCount(), 3202 instance_call()->ArgumentCount(),
3138 instance_call()->argument_names(), 3203 instance_call()->argument_names(),
3139 deopt_id(), 3204 deopt_id(),
3140 instance_call()->token_pos(), 3205 instance_call()->token_pos(),
3141 locs(), 3206 locs(),
3142 complete()); 3207 complete());
3143 } 3208 }
3209 #endif
3144 3210
3145 3211
3146 LocationSummary* StaticCallInstr::MakeLocationSummary(Zone* zone, 3212 LocationSummary* StaticCallInstr::MakeLocationSummary(Zone* zone,
3147 bool optimizing) const { 3213 bool optimizing) const {
3148 return MakeCallSummary(zone); 3214 return MakeCallSummary(zone);
3149 } 3215 }
3150 3216
3151 3217
3152 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3218 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3219 #if !defined(TARGET_ARCH_DBC)
3153 const ICData* call_ic_data = NULL; 3220 const ICData* call_ic_data = NULL;
3154 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() || 3221 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() ||
3155 (ic_data() == NULL)) { 3222 (ic_data() == NULL)) {
3156 const Array& arguments_descriptor = 3223 const Array& arguments_descriptor =
3157 Array::Handle(ArgumentsDescriptor::New(ArgumentCount(), 3224 Array::Handle(ArgumentsDescriptor::New(ArgumentCount(),
3158 argument_names())); 3225 argument_names()));
3159 MethodRecognizer::Kind recognized_kind = 3226 MethodRecognizer::Kind recognized_kind =
3160 MethodRecognizer::RecognizeKind(function()); 3227 MethodRecognizer::RecognizeKind(function());
3161 int num_args_checked = 0; 3228 int num_args_checked = 0;
3162 switch (recognized_kind) { 3229 switch (recognized_kind) {
(...skipping 12 matching lines...) Expand all
3175 } else { 3242 } else {
3176 call_ic_data = &ICData::ZoneHandle(ic_data()->raw()); 3243 call_ic_data = &ICData::ZoneHandle(ic_data()->raw());
3177 } 3244 }
3178 compiler->GenerateStaticCall(deopt_id(), 3245 compiler->GenerateStaticCall(deopt_id(),
3179 token_pos(), 3246 token_pos(),
3180 function(), 3247 function(),
3181 ArgumentCount(), 3248 ArgumentCount(),
3182 argument_names(), 3249 argument_names(),
3183 locs(), 3250 locs(),
3184 *call_ic_data); 3251 *call_ic_data);
3252 #else
3253 const Array& arguments_descriptor =
3254 (ic_data() == NULL) ?
3255 Array::Handle(ArgumentsDescriptor::New(ArgumentCount(),
3256 argument_names())) :
3257 Array::Handle(ic_data()->arguments_descriptor());
3258 const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor);
3259
3260 __ PushConstant(function());
3261 __ StaticCall(ArgumentCount(), argdesc_kidx);
3262 compiler->AddCurrentDescriptor(RawPcDescriptors::kUnoptStaticCall,
3263 deopt_id(),
3264 token_pos());
3265 #endif // !defined(TARGET_ARCH_DBC)
3185 } 3266 }
3186 3267
3187 3268
3188 void AssertAssignableInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3269 void AssertAssignableInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3189 compiler->GenerateAssertAssignable(token_pos(), 3270 compiler->GenerateAssertAssignable(token_pos(),
3190 deopt_id(), 3271 deopt_id(),
3191 dst_type(), 3272 dst_type(),
3192 dst_name(), 3273 dst_name(),
3193 locs()); 3274 locs());
3275
3276 // DBC does not use LocationSummaries in the same way as other architectures.
3277 #if !defined(TARGET_ARCH_DBC)
3194 ASSERT(locs()->in(0).reg() == locs()->out(0).reg()); 3278 ASSERT(locs()->in(0).reg() == locs()->out(0).reg());
3279 #endif
3195 } 3280 }
3196 3281
3197 3282
3198 LocationSummary* DeoptimizeInstr::MakeLocationSummary(Zone* zone, 3283 LocationSummary* DeoptimizeInstr::MakeLocationSummary(Zone* zone,
3199 bool opt) const { 3284 bool opt) const {
3200 return new(zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall); 3285 return new(zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);
3201 } 3286 }
3202 3287
3203 3288
3204 void DeoptimizeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3289 void DeoptimizeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3295 intptr_t use_index = instr->env()->Length(); // Start index after inner. 3380 intptr_t use_index = instr->env()->Length(); // Start index after inner.
3296 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { 3381 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) {
3297 Value* value = it.CurrentValue(); 3382 Value* value = it.CurrentValue();
3298 value->set_instruction(instr); 3383 value->set_instruction(instr);
3299 value->set_use_index(use_index++); 3384 value->set_use_index(use_index++);
3300 value->definition()->AddEnvUse(value); 3385 value->definition()->AddEnvUse(value);
3301 } 3386 }
3302 } 3387 }
3303 3388
3304 3389
3305 static bool BindsToSmiConstant(Value* value) {
3306 return value->BindsToConstant() && value->BoundConstant().IsSmi();
3307 }
3308
3309
3310 ComparisonInstr* EqualityCompareInstr::CopyWithNewOperands(Value* new_left, 3390 ComparisonInstr* EqualityCompareInstr::CopyWithNewOperands(Value* new_left,
3311 Value* new_right) { 3391 Value* new_right) {
3312 return new EqualityCompareInstr(token_pos(), 3392 return new EqualityCompareInstr(token_pos(),
3313 kind(), 3393 kind(),
3314 new_left, 3394 new_left,
3315 new_right, 3395 new_right,
3316 operation_cid(), 3396 operation_cid(),
3317 deopt_id()); 3397 deopt_id());
3318 } 3398 }
3319 3399
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3367 } 3447 }
3368 for (intptr_t i = 0; i < cid_results().length(); i++) { 3448 for (intptr_t i = 0; i < cid_results().length(); i++) {
3369 if (cid_results()[i] != other_instr->cid_results()[i]) { 3449 if (cid_results()[i] != other_instr->cid_results()[i]) {
3370 return false; 3450 return false;
3371 } 3451 }
3372 } 3452 }
3373 return true; 3453 return true;
3374 } 3454 }
3375 3455
3376 3456
3457 #if !defined(TARGET_ARCH_DBC)
3458 static bool BindsToSmiConstant(Value* value) {
3459 return value->BindsToConstant() && value->BoundConstant().IsSmi();
3460 }
3461 #endif
3462
3463
3377 bool IfThenElseInstr::Supports(ComparisonInstr* comparison, 3464 bool IfThenElseInstr::Supports(ComparisonInstr* comparison,
3378 Value* v1, 3465 Value* v1,
3379 Value* v2) { 3466 Value* v2) {
3467 #if !defined(TARGET_ARCH_DBC)
3380 bool is_smi_result = BindsToSmiConstant(v1) && BindsToSmiConstant(v2); 3468 bool is_smi_result = BindsToSmiConstant(v1) && BindsToSmiConstant(v2);
3381 if (comparison->IsStrictCompare()) { 3469 if (comparison->IsStrictCompare()) {
3382 // Strict comparison with number checks calls a stub and is not supported 3470 // Strict comparison with number checks calls a stub and is not supported
3383 // by if-conversion. 3471 // by if-conversion.
3384 return is_smi_result 3472 return is_smi_result
3385 && !comparison->AsStrictCompare()->needs_number_check(); 3473 && !comparison->AsStrictCompare()->needs_number_check();
3386 } 3474 }
3387 if (comparison->operation_cid() != kSmiCid) { 3475 if (comparison->operation_cid() != kSmiCid) {
3388 // Non-smi comparisons are not supported by if-conversion. 3476 // Non-smi comparisons are not supported by if-conversion.
3389 return false; 3477 return false;
3390 } 3478 }
3391 return is_smi_result; 3479 return is_smi_result;
3480 #else
3481 return false;
3482 #endif // !defined(TARGET_ARCH_DBC)
3392 } 3483 }
3393 3484
3394 3485
3395 bool PhiInstr::IsRedundant() const { 3486 bool PhiInstr::IsRedundant() const {
3396 ASSERT(InputCount() > 1); 3487 ASSERT(InputCount() > 1);
3397 Definition* first = InputAt(0)->definition(); 3488 Definition* first = InputAt(0)->definition();
3398 for (intptr_t i = 1; i < InputCount(); ++i) { 3489 for (intptr_t i = 1; i < InputCount(); ++i) {
3399 Definition* def = InputAt(i)->definition(); 3490 Definition* def = InputAt(i)->definition();
3400 if (def != first) return false; 3491 if (def != first) return false;
3401 } 3492 }
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
3753 set_native_c_function(native_function); 3844 set_native_c_function(native_function);
3754 function().SetIsNativeAutoSetupScope(auto_setup_scope); 3845 function().SetIsNativeAutoSetupScope(auto_setup_scope);
3755 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); 3846 Dart_NativeEntryResolver resolver = library.native_entry_resolver();
3756 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); 3847 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver);
3757 set_is_bootstrap_native(is_bootstrap_native); 3848 set_is_bootstrap_native(is_bootstrap_native);
3758 } 3849 }
3759 3850
3760 #undef __ 3851 #undef __
3761 3852
3762 } // namespace dart 3853 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/instructions_dbc.cc ('k') | runtime/vm/intermediate_language_dbc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698