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

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

Issue 2894953002: Support inlining of calls where type arguments are passed to generic functions. (Closed)
Patch Set: Created 3 years, 7 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/flow_graph.h ('k') | runtime/vm/flow_graph_inliner.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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.h" 5 #include "vm/flow_graph.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/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 673
674 return assigned_vars_; 674 return assigned_vars_;
675 } 675 }
676 676
677 // Returns true if the value set by the given store reaches any load from the 677 // Returns true if the value set by the given store reaches any load from the
678 // same local variable. 678 // same local variable.
679 bool IsStoreAlive(BlockEntryInstr* block, StoreLocalInstr* store) { 679 bool IsStoreAlive(BlockEntryInstr* block, StoreLocalInstr* store) {
680 if (store->local().Equals(*flow_graph_->CurrentContextVar())) { 680 if (store->local().Equals(*flow_graph_->CurrentContextVar())) {
681 return true; 681 return true;
682 } 682 }
683 if ((flow_graph_->FunctionTypeArgsVar() != NULL) &&
Vyacheslav Egorov (Google) 2017/05/22 11:23:21 Is this a mutable variable? I thought it's just
regis 2017/05/22 17:51:08 It is invariable with one exception: if the generi
regis 2017/05/22 18:02:42 I suppose I could use the SpecialParameterInstr on
Vyacheslav Egorov (Google) 2017/05/22 18:39:43 I think there is no problem. I think the best way
684 store->local().Equals(*flow_graph_->FunctionTypeArgsVar())) {
685 return true;
686 }
683 687
684 if (store->is_dead()) { 688 if (store->is_dead()) {
685 return false; 689 return false;
686 } 690 }
687 if (store->is_last()) { 691 if (store->is_last()) {
688 const intptr_t index = store->local().BitIndexIn(num_non_copied_params_); 692 const intptr_t index = store->local().BitIndexIn(num_non_copied_params_);
689 return GetLiveOutSet(block)->Contains(index); 693 return GetLiveOutSet(block)->Contains(index);
690 } 694 }
691 695
692 return true; 696 return true;
693 } 697 }
694 698
695 // Returns true if the given load is the last for the local and the value 699 // Returns true if the given load is the last for the local and the value
696 // of the local will not flow into another one. 700 // of the local will not flow into another one.
697 bool IsLastLoad(BlockEntryInstr* block, LoadLocalInstr* load) { 701 bool IsLastLoad(BlockEntryInstr* block, LoadLocalInstr* load) {
698 if (load->local().Equals(*flow_graph_->CurrentContextVar())) { 702 if (load->local().Equals(*flow_graph_->CurrentContextVar())) {
699 return false; 703 return false;
700 } 704 }
705 if ((flow_graph_->FunctionTypeArgsVar() != NULL) &&
706 load->local().Equals(*flow_graph_->FunctionTypeArgsVar())) {
707 return false;
708 }
701 const intptr_t index = load->local().BitIndexIn(num_non_copied_params_); 709 const intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
702 return load->is_last() && !GetLiveOutSet(block)->Contains(index); 710 return load->is_last() && !GetLiveOutSet(block)->Contains(index);
703 } 711 }
704 712
705 private: 713 private:
706 virtual void ComputeInitialSets(); 714 virtual void ComputeInitialSets();
707 715
708 const FlowGraph* flow_graph_; 716 const FlowGraph* flow_graph_;
709 const intptr_t num_non_copied_params_; 717 const intptr_t num_non_copied_params_;
710 GrowableArray<BitVector*> assigned_vars_; 718 GrowableArray<BitVector*> assigned_vars_;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 kill->Add(index); 773 kill->Add(index);
766 } 774 }
767 live_in->Remove(index); 775 live_in->Remove(index);
768 continue; 776 continue;
769 } 777 }
770 } 778 }
771 } 779 }
772 } 780 }
773 781
774 782
775 void FlowGraph::ComputeSSA( 783 void FlowGraph::ComputeSSA(intptr_t next_virtual_register_number,
776 intptr_t next_virtual_register_number, 784 ZoneGrowableArray<Definition*>* inlining_parameters,
777 ZoneGrowableArray<Definition*>* inlining_parameters) { 785 Definition* inlining_type_args) {
778 ASSERT((next_virtual_register_number == 0) || (inlining_parameters != NULL)); 786 ASSERT((next_virtual_register_number == 0) || (inlining_parameters != NULL));
779 current_ssa_temp_index_ = next_virtual_register_number; 787 current_ssa_temp_index_ = next_virtual_register_number;
780 GrowableArray<BitVector*> dominance_frontier; 788 GrowableArray<BitVector*> dominance_frontier;
781 ComputeDominators(&dominance_frontier); 789 ComputeDominators(&dominance_frontier);
782 790
783 VariableLivenessAnalysis variable_liveness(this); 791 VariableLivenessAnalysis variable_liveness(this);
784 variable_liveness.Analyze(); 792 variable_liveness.Analyze();
785 793
786 GrowableArray<PhiInstr*> live_phis; 794 GrowableArray<PhiInstr*> live_phis;
787 795
788 InsertPhis(preorder_, variable_liveness.ComputeAssignedVars(), 796 InsertPhis(preorder_, variable_liveness.ComputeAssignedVars(),
789 dominance_frontier, &live_phis); 797 dominance_frontier, &live_phis);
790 798
791 799
792 // Rename uses to reference inserted phis where appropriate. 800 // Rename uses to reference inserted phis where appropriate.
793 // Collect phis that reach a non-environment use. 801 // Collect phis that reach a non-environment use.
794 Rename(&live_phis, &variable_liveness, inlining_parameters); 802 Rename(&live_phis, &variable_liveness, inlining_parameters,
803 inlining_type_args);
795 804
796 // Propagate alive mark transitively from alive phis and then remove 805 // Propagate alive mark transitively from alive phis and then remove
797 // non-live ones. 806 // non-live ones.
798 RemoveDeadPhis(&live_phis); 807 RemoveDeadPhis(&live_phis);
799 } 808 }
800 809
801 810
802 // Compute immediate dominators and the dominance frontier for each basic 811 // Compute immediate dominators and the dominance frontier for each basic
803 // block. As a side effect of the algorithm, sets the immediate dominator 812 // block. As a side effect of the algorithm, sets the immediate dominator
804 // of each basic block. 813 // of each basic block.
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 } 981 }
973 } 982 }
974 } 983 }
975 } 984 }
976 } 985 }
977 } 986 }
978 987
979 988
980 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, 989 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis,
981 VariableLivenessAnalysis* variable_liveness, 990 VariableLivenessAnalysis* variable_liveness,
982 ZoneGrowableArray<Definition*>* inlining_parameters) { 991 ZoneGrowableArray<Definition*>* inlining_parameters,
992 Definition* inlining_type_args) {
983 GraphEntryInstr* entry = graph_entry(); 993 GraphEntryInstr* entry = graph_entry();
984 994
985 // Initial renaming environment. 995 // Initial renaming environment.
986 GrowableArray<Definition*> env(variable_count()); 996 GrowableArray<Definition*> env(variable_count());
987 997
988 // Add global constants to the initial definitions. 998 // Add global constants to the initial definitions.
989 constant_null_ = GetConstant(Object::ZoneHandle()); 999 constant_null_ = GetConstant(Object::ZoneHandle());
990 constant_dead_ = GetConstant(Symbols::OptimizedOut()); 1000 constant_dead_ = GetConstant(Symbols::OptimizedOut());
991 constant_empty_context_ = GetConstant(Object::empty_context()); 1001 constant_empty_context_ = GetConstant(Object::empty_context());
992 1002
(...skipping 15 matching lines...) Expand all
1008 ParameterInstr* param = new (zone()) ParameterInstr(i, entry); 1018 ParameterInstr* param = new (zone()) ParameterInstr(i, entry);
1009 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. 1019 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
1010 AddToInitialDefinitions(param); 1020 AddToInitialDefinitions(param);
1011 env.Add(param); 1021 env.Add(param);
1012 } 1022 }
1013 } 1023 }
1014 1024
1015 // Initialize all locals in the renaming environment For OSR, the locals have 1025 // Initialize all locals in the renaming environment For OSR, the locals have
1016 // already been handled as parameters. 1026 // already been handled as parameters.
1017 if (!IsCompiledForOsr()) { 1027 if (!IsCompiledForOsr()) {
1028 const intptr_t type_args_env_index =
1029 (FunctionTypeArgsVar() != NULL) ? FunctionTypeArgsEnvIndex() : -1;
1018 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { 1030 for (intptr_t i = parameter_count(); i < variable_count(); ++i) {
1019 if (i == CurrentContextEnvIndex()) { 1031 if (i == type_args_env_index) {
Vyacheslav Egorov (Google) 2017/05/22 11:23:21 I think a better way would be to mimic what we do
regis 2017/05/22 17:51:08 Thank you for the suggestion. Let me try that.
1032 if (inlining_type_args != NULL) {
1033 AllocateSSAIndexes(inlining_type_args);
1034 AddToInitialDefinitions(inlining_type_args);
1035 env.Add(inlining_type_args);
1036 } else {
1037 // TODO(regis): For now, initialize local variable to null.
1038 // Where do we check for a passed type args? If not passed in, must
1039 // set to vector of dynamic of the proper length.
1040 // Do we need a FunctionTypeArgsInstr?
1041 env.Add(constant_null());
1042 }
1043 } else if (i == CurrentContextEnvIndex()) {
1020 if (function().IsClosureFunction()) { 1044 if (function().IsClosureFunction()) {
1021 CurrentContextInstr* context = new CurrentContextInstr(); 1045 CurrentContextInstr* context = new CurrentContextInstr();
1022 context->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. 1046 context->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
1023 AddToInitialDefinitions(context); 1047 AddToInitialDefinitions(context);
1024 env.Add(context); 1048 env.Add(context);
1025 } else { 1049 } else {
1026 env.Add(constant_empty_context()); 1050 env.Add(constant_empty_context());
1027 } 1051 }
1028 } else { 1052 } else {
1029 env.Add(constant_null()); 1053 env.Add(constant_null());
(...skipping 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after
2312 Representation rep, 2336 Representation rep,
2313 intptr_t cid) { 2337 intptr_t cid) {
2314 ExtractNthOutputInstr* extract = 2338 ExtractNthOutputInstr* extract =
2315 new (Z) ExtractNthOutputInstr(new (Z) Value(instr), index, rep, cid); 2339 new (Z) ExtractNthOutputInstr(new (Z) Value(instr), index, rep, cid);
2316 instr->ReplaceUsesWith(extract); 2340 instr->ReplaceUsesWith(extract);
2317 InsertAfter(instr, extract, NULL, FlowGraph::kValue); 2341 InsertAfter(instr, extract, NULL, FlowGraph::kValue);
2318 } 2342 }
2319 2343
2320 2344
2321 } // namespace dart 2345 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698