| OLD | NEW |
| 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/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 void Instruction::UnuseAllInputs() { | 797 void Instruction::UnuseAllInputs() { |
| 798 for (intptr_t i = InputCount() - 1; i >= 0; --i) { | 798 for (intptr_t i = InputCount() - 1; i >= 0; --i) { |
| 799 InputAt(i)->RemoveFromUseList(); | 799 InputAt(i)->RemoveFromUseList(); |
| 800 } | 800 } |
| 801 for (Environment::DeepIterator it(env()); !it.Done(); it.Advance()) { | 801 for (Environment::DeepIterator it(env()); !it.Done(); it.Advance()) { |
| 802 it.CurrentValue()->RemoveFromUseList(); | 802 it.CurrentValue()->RemoveFromUseList(); |
| 803 } | 803 } |
| 804 } | 804 } |
| 805 | 805 |
| 806 | 806 |
| 807 void Instruction::InheritDeoptTargetAfter(Instruction* other) { | 807 void Instruction::InheritDeoptTargetAfter(Isolate* isolate, |
| 808 Instruction* other) { |
| 808 ASSERT(other->env() != NULL); | 809 ASSERT(other->env() != NULL); |
| 809 deopt_id_ = Isolate::ToDeoptAfter(other->deopt_id_); | 810 deopt_id_ = Isolate::ToDeoptAfter(other->deopt_id_); |
| 810 other->env()->DeepCopyTo(this); | 811 other->env()->DeepCopyTo(isolate, this); |
| 811 env()->set_deopt_id(deopt_id_); | 812 env()->set_deopt_id(deopt_id_); |
| 812 } | 813 } |
| 813 | 814 |
| 814 | 815 |
| 815 void Instruction::InheritDeoptTarget(Instruction* other) { | 816 void Instruction::InheritDeoptTarget(Isolate* isolate, Instruction* other) { |
| 816 ASSERT(other->env() != NULL); | 817 ASSERT(other->env() != NULL); |
| 817 deopt_id_ = other->deopt_id_; | 818 deopt_id_ = other->deopt_id_; |
| 818 other->env()->DeepCopyTo(this); | 819 other->env()->DeepCopyTo(isolate, this); |
| 819 env()->set_deopt_id(deopt_id_); | 820 env()->set_deopt_id(deopt_id_); |
| 820 } | 821 } |
| 821 | 822 |
| 822 | 823 |
| 823 void BranchInstr::InheritDeoptTarget(Instruction* other) { | 824 void BranchInstr::InheritDeoptTarget(Isolate* isolate, Instruction* other) { |
| 824 ASSERT(env() == NULL); | 825 ASSERT(env() == NULL); |
| 825 Instruction::InheritDeoptTarget(other); | 826 Instruction::InheritDeoptTarget(isolate, other); |
| 826 comparison()->SetDeoptId(GetDeoptId()); | 827 comparison()->SetDeoptId(GetDeoptId()); |
| 827 } | 828 } |
| 828 | 829 |
| 829 | 830 |
| 830 void Definition::ReplaceWith(Definition* other, | 831 void Definition::ReplaceWith(Definition* other, |
| 831 ForwardInstructionIterator* iterator) { | 832 ForwardInstructionIterator* iterator) { |
| 832 // Record other's input uses. | 833 // Record other's input uses. |
| 833 for (intptr_t i = other->InputCount() - 1; i >= 0; --i) { | 834 for (intptr_t i = other->InputCount() - 1; i >= 0; --i) { |
| 834 Value* input = other->InputAt(i); | 835 Value* input = other->InputAt(i); |
| 835 input->definition()->AddInputUse(input); | 836 input->definition()->AddInputUse(input); |
| (...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1859 } | 1860 } |
| 1860 | 1861 |
| 1861 Definition* left_defn = left->definition(); | 1862 Definition* left_defn = left->definition(); |
| 1862 return left_defn->IsBinarySmiOp() && | 1863 return left_defn->IsBinarySmiOp() && |
| 1863 (left_defn->AsBinarySmiOp()->op_kind() == Token::kBIT_AND) && | 1864 (left_defn->AsBinarySmiOp()->op_kind() == Token::kBIT_AND) && |
| 1864 left_defn->HasOnlyUse(left); | 1865 left_defn->HasOnlyUse(left); |
| 1865 } | 1866 } |
| 1866 | 1867 |
| 1867 | 1868 |
| 1868 Instruction* BranchInstr::Canonicalize(FlowGraph* flow_graph) { | 1869 Instruction* BranchInstr::Canonicalize(FlowGraph* flow_graph) { |
| 1870 Isolate* isolate = flow_graph->isolate(); |
| 1869 // Only handle strict-compares. | 1871 // Only handle strict-compares. |
| 1870 if (comparison()->IsStrictCompare()) { | 1872 if (comparison()->IsStrictCompare()) { |
| 1871 bool negated = false; | 1873 bool negated = false; |
| 1872 Definition* replacement = | 1874 Definition* replacement = |
| 1873 CanonicalizeStrictCompare(comparison()->AsStrictCompare(), &negated); | 1875 CanonicalizeStrictCompare(comparison()->AsStrictCompare(), &negated); |
| 1874 if (replacement == comparison()) { | 1876 if (replacement == comparison()) { |
| 1875 return this; | 1877 return this; |
| 1876 } | 1878 } |
| 1877 ComparisonInstr* comp = replacement->AsComparison(); | 1879 ComparisonInstr* comp = replacement->AsComparison(); |
| 1878 if ((comp == NULL) || comp->CanDeoptimize()) { | 1880 if ((comp == NULL) || comp->CanDeoptimize()) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1918 if (RecognizeTestPattern(comparison()->left(), comparison()->right())) { | 1920 if (RecognizeTestPattern(comparison()->left(), comparison()->right())) { |
| 1919 bit_and = comparison()->left()->definition()->AsBinarySmiOp(); | 1921 bit_and = comparison()->left()->definition()->AsBinarySmiOp(); |
| 1920 } else if (RecognizeTestPattern(comparison()->right(), | 1922 } else if (RecognizeTestPattern(comparison()->right(), |
| 1921 comparison()->left())) { | 1923 comparison()->left())) { |
| 1922 bit_and = comparison()->right()->definition()->AsBinarySmiOp(); | 1924 bit_and = comparison()->right()->definition()->AsBinarySmiOp(); |
| 1923 } | 1925 } |
| 1924 if (bit_and != NULL) { | 1926 if (bit_and != NULL) { |
| 1925 if (FLAG_trace_optimization) { | 1927 if (FLAG_trace_optimization) { |
| 1926 OS::Print("Merging test smi v%" Pd "\n", bit_and->ssa_temp_index()); | 1928 OS::Print("Merging test smi v%" Pd "\n", bit_and->ssa_temp_index()); |
| 1927 } | 1929 } |
| 1928 TestSmiInstr* test = new TestSmiInstr(comparison()->token_pos(), | 1930 TestSmiInstr* test = new TestSmiInstr( |
| 1929 comparison()->kind(), | 1931 comparison()->token_pos(), |
| 1930 bit_and->left()->Copy(), | 1932 comparison()->kind(), |
| 1931 bit_and->right()->Copy()); | 1933 bit_and->left()->Copy(isolate), |
| 1934 bit_and->right()->Copy(isolate)); |
| 1932 ASSERT(!CanDeoptimize()); | 1935 ASSERT(!CanDeoptimize()); |
| 1933 RemoveEnvironment(); | 1936 RemoveEnvironment(); |
| 1934 flow_graph->CopyDeoptTarget(this, bit_and); | 1937 flow_graph->CopyDeoptTarget(this, bit_and); |
| 1935 SetComparison(test); | 1938 SetComparison(test); |
| 1936 bit_and->RemoveFromGraph(); | 1939 bit_and->RemoveFromGraph(); |
| 1937 } | 1940 } |
| 1938 } | 1941 } |
| 1939 return this; | 1942 return this; |
| 1940 } | 1943 } |
| 1941 | 1944 |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2336 void AssertAssignableInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2339 void AssertAssignableInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2337 compiler->GenerateAssertAssignable(token_pos(), | 2340 compiler->GenerateAssertAssignable(token_pos(), |
| 2338 deopt_id(), | 2341 deopt_id(), |
| 2339 dst_type(), | 2342 dst_type(), |
| 2340 dst_name(), | 2343 dst_name(), |
| 2341 locs()); | 2344 locs()); |
| 2342 ASSERT(locs()->in(0).reg() == locs()->out(0).reg()); | 2345 ASSERT(locs()->in(0).reg() == locs()->out(0).reg()); |
| 2343 } | 2346 } |
| 2344 | 2347 |
| 2345 | 2348 |
| 2346 Environment* Environment::From(const GrowableArray<Definition*>& definitions, | 2349 Environment* Environment::From(Isolate* isolate, |
| 2350 const GrowableArray<Definition*>& definitions, |
| 2347 intptr_t fixed_parameter_count, | 2351 intptr_t fixed_parameter_count, |
| 2348 const Code& code) { | 2352 const Code& code) { |
| 2349 Environment* env = | 2353 Environment* env = |
| 2350 new Environment(definitions.length(), | 2354 new(isolate) Environment(definitions.length(), |
| 2351 fixed_parameter_count, | 2355 fixed_parameter_count, |
| 2352 Isolate::kNoDeoptId, | 2356 Isolate::kNoDeoptId, |
| 2353 code, | 2357 code, |
| 2354 NULL); | 2358 NULL); |
| 2355 for (intptr_t i = 0; i < definitions.length(); ++i) { | 2359 for (intptr_t i = 0; i < definitions.length(); ++i) { |
| 2356 env->values_.Add(new Value(definitions[i])); | 2360 env->values_.Add(new(isolate) Value(definitions[i])); |
| 2357 } | 2361 } |
| 2358 return env; | 2362 return env; |
| 2359 } | 2363 } |
| 2360 | 2364 |
| 2361 | 2365 |
| 2362 Environment* Environment::DeepCopy(intptr_t length) const { | 2366 Environment* Environment::DeepCopy(Isolate* isolate, intptr_t length) const { |
| 2363 ASSERT(length <= values_.length()); | 2367 ASSERT(length <= values_.length()); |
| 2364 Environment* copy = | 2368 Environment* copy = |
| 2365 new Environment(length, | 2369 new(isolate) Environment( |
| 2366 fixed_parameter_count_, | 2370 length, |
| 2367 deopt_id_, | 2371 fixed_parameter_count_, |
| 2368 code_, | 2372 deopt_id_, |
| 2369 (outer_ == NULL) ? NULL : outer_->DeepCopy()); | 2373 code_, |
| 2374 (outer_ == NULL) ? NULL : outer_->DeepCopy(isolate)); |
| 2370 if (locations_ != NULL) { | 2375 if (locations_ != NULL) { |
| 2371 Location* new_locations = | 2376 Location* new_locations = isolate->current_zone()->Alloc<Location>(length); |
| 2372 Isolate::Current()->current_zone()->Alloc<Location>(length); | |
| 2373 copy->set_locations(new_locations); | 2377 copy->set_locations(new_locations); |
| 2374 } | 2378 } |
| 2375 for (intptr_t i = 0; i < length; ++i) { | 2379 for (intptr_t i = 0; i < length; ++i) { |
| 2376 copy->values_.Add(values_[i]->Copy()); | 2380 copy->values_.Add(values_[i]->Copy(isolate)); |
| 2377 if (locations_ != NULL) { | 2381 if (locations_ != NULL) { |
| 2378 copy->locations_[i] = locations_[i].Copy(); | 2382 copy->locations_[i] = locations_[i].Copy(); |
| 2379 } | 2383 } |
| 2380 } | 2384 } |
| 2381 return copy; | 2385 return copy; |
| 2382 } | 2386 } |
| 2383 | 2387 |
| 2384 | 2388 |
| 2385 // Copies the environment and updates the environment use lists. | 2389 // Copies the environment and updates the environment use lists. |
| 2386 void Environment::DeepCopyTo(Instruction* instr) const { | 2390 void Environment::DeepCopyTo(Isolate* isolate, Instruction* instr) const { |
| 2387 for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) { | 2391 for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) { |
| 2388 it.CurrentValue()->RemoveFromUseList(); | 2392 it.CurrentValue()->RemoveFromUseList(); |
| 2389 } | 2393 } |
| 2390 | 2394 |
| 2391 Environment* copy = DeepCopy(); | 2395 Environment* copy = DeepCopy(isolate); |
| 2392 instr->SetEnvironment(copy); | 2396 instr->SetEnvironment(copy); |
| 2393 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { | 2397 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { |
| 2394 Value* value = it.CurrentValue(); | 2398 Value* value = it.CurrentValue(); |
| 2395 value->definition()->AddEnvUse(value); | 2399 value->definition()->AddEnvUse(value); |
| 2396 } | 2400 } |
| 2397 } | 2401 } |
| 2398 | 2402 |
| 2399 | 2403 |
| 2400 // Copies the environment as outer on an inlined instruction and updates the | 2404 // Copies the environment as outer on an inlined instruction and updates the |
| 2401 // environment use lists. | 2405 // environment use lists. |
| 2402 void Environment::DeepCopyToOuter(Instruction* instr) const { | 2406 void Environment::DeepCopyToOuter(Isolate* isolate, Instruction* instr) const { |
| 2403 // Create a deep copy removing caller arguments from the environment. | 2407 // Create a deep copy removing caller arguments from the environment. |
| 2404 ASSERT(this != NULL); | 2408 ASSERT(this != NULL); |
| 2405 ASSERT(instr->env()->outer() == NULL); | 2409 ASSERT(instr->env()->outer() == NULL); |
| 2406 intptr_t argument_count = instr->env()->fixed_parameter_count(); | 2410 intptr_t argument_count = instr->env()->fixed_parameter_count(); |
| 2407 Environment* copy = DeepCopy(values_.length() - argument_count); | 2411 Environment* copy = DeepCopy(isolate, values_.length() - argument_count); |
| 2408 instr->env()->outer_ = copy; | 2412 instr->env()->outer_ = copy; |
| 2409 intptr_t use_index = instr->env()->Length(); // Start index after inner. | 2413 intptr_t use_index = instr->env()->Length(); // Start index after inner. |
| 2410 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { | 2414 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { |
| 2411 Value* value = it.CurrentValue(); | 2415 Value* value = it.CurrentValue(); |
| 2412 value->set_instruction(instr); | 2416 value->set_instruction(instr); |
| 2413 value->set_use_index(use_index++); | 2417 value->set_use_index(use_index++); |
| 2414 value->definition()->AddEnvUse(value); | 2418 value->definition()->AddEnvUse(value); |
| 2415 } | 2419 } |
| 2416 } | 2420 } |
| 2417 | 2421 |
| (...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3450 case Token::kTRUNCDIV: return 0; | 3454 case Token::kTRUNCDIV: return 0; |
| 3451 case Token::kMOD: return 1; | 3455 case Token::kMOD: return 1; |
| 3452 default: UNIMPLEMENTED(); return -1; | 3456 default: UNIMPLEMENTED(); return -1; |
| 3453 } | 3457 } |
| 3454 } | 3458 } |
| 3455 | 3459 |
| 3456 | 3460 |
| 3457 #undef __ | 3461 #undef __ |
| 3458 | 3462 |
| 3459 } // namespace dart | 3463 } // namespace dart |
| OLD | NEW |