@@ -60,8 +60,6 @@ abstract class OptimizationPhase {
6060class SsaOptimizerTask extends CompilerTask {
6161 final CompilerOptions _options;
6262
63- Map <HInstruction , Range > ranges = {};
64-
6563 final Map <MemberEntity , OptimizationTestLog > loggersForTesting = {};
6664
6765 SsaOptimizerTask (super .measurer, this ._options);
@@ -78,90 +76,112 @@ class SsaOptimizerTask extends CompilerTask {
7876 CodegenRegistry registry,
7977 SsaMetrics metrics,
8078 ) {
81- void runPhase (OptimizationPhase phase) {
82- measureSubtask (phase.name, () => phase.visitGraph (graph));
83- codegen.tracer.traceGraph (phase.name, graph);
84- assert (graph.isValid (), 'Graph not valid after ${phase .name }' );
85- assert (
86- phase.validPostcondition (graph),
87- 'Graph does not satisfy phase postcondition after ${phase .name }' ,
88- );
89- }
79+ final workItem = SsaOptimizerWorkItem (
80+ this ,
81+ member,
82+ graph,
83+ codegen,
84+ closedWorld,
85+ globalInferenceResults,
86+ registry,
87+ metrics,
88+ );
89+ workItem.optimize ();
90+ }
91+ }
9092
91- SsaCodeMotion codeMotion;
92- SsaLoadElimination loadElimination;
93+ class SsaOptimizerWorkItem {
94+ final SsaOptimizerTask task;
95+
96+ final MemberEntity member;
97+ final HGraph graph;
98+ final CodegenInputs codegen;
99+ final JClosedWorld closedWorld;
100+ final GlobalTypeInferenceResults globalInferenceResults;
101+ final CodegenRegistry registry;
102+ final SsaMetrics metrics;
103+
104+ late final OptimizationTestLog ? log = retainDataForTesting
105+ ? task.loggersForTesting[member] = OptimizationTestLog (
106+ closedWorld.dartTypes,
107+ )
108+ : null ;
109+
110+ late final TypeRecipeDomain typeRecipeDomain = TypeRecipeDomainImpl (
111+ closedWorld.dartTypes,
112+ );
93113
94- TypeRecipeDomain typeRecipeDomain = TypeRecipeDomainImpl (
95- closedWorld.dartTypes,
114+ Map <HInstruction , Range > ranges = {};
115+
116+ SsaOptimizerWorkItem (
117+ this .task,
118+ this .member,
119+ this .graph,
120+ this .codegen,
121+ this .closedWorld,
122+ this .globalInferenceResults,
123+ this .registry,
124+ this .metrics,
125+ );
126+
127+ void runPhase (OptimizationPhase phase) {
128+ task.measureSubtask (phase.name, () => phase.visitGraph (graph));
129+ codegen.tracer.traceGraph (phase.name, graph);
130+ assert (graph.isValid (), 'Graph not valid after ${phase .name }' );
131+ assert (
132+ phase.validPostcondition (graph),
133+ 'Graph does not satisfy phase postcondition after ${phase .name }' ,
96134 );
135+ }
97136
98- OptimizationTestLog ? log;
99- if (retainDataForTesting) {
100- log = loggersForTesting[member] = OptimizationTestLog (
101- closedWorld.dartTypes,
102- );
103- }
137+ SsaInstructionSimplifier simplifierPhase ({
138+ bool beforeTypePropagation = false ,
139+ }) {
140+ return SsaInstructionSimplifier (
141+ globalInferenceResults,
142+ task._options,
143+ closedWorld,
144+ typeRecipeDomain,
145+ registry,
146+ log,
147+ metrics,
148+ beforeTypePropagation: beforeTypePropagation,
149+ );
150+ }
104151
105- measure (() {
152+ SsaTypePropagator typePropagatorPhase () {
153+ return SsaTypePropagator (
154+ globalInferenceResults,
155+ closedWorld.commonElements,
156+ closedWorld,
157+ log,
158+ );
159+ }
160+
161+ void optimize () {
162+ SsaCodeMotion codeMotion;
163+ SsaLoadElimination loadElimination;
164+
165+ task.measure (() {
106166 List <OptimizationPhase > phases = [
107167 // Run trivial instruction simplification first to optimize some
108168 // patterns useful for type conversion.
109- SsaInstructionSimplifier (
110- globalInferenceResults,
111- _options,
112- closedWorld,
113- typeRecipeDomain,
114- registry,
115- log,
116- metrics,
117- beforeTypePropagation: true ,
118- ),
169+ simplifierPhase (beforeTypePropagation: true ),
119170 SsaTypeConversionInserter (closedWorld),
120171 SsaRedundantPhiEliminator (),
121172 SsaDeadPhiEliminator (),
122- SsaTypePropagator (
123- globalInferenceResults,
124- closedWorld.commonElements,
125- closedWorld,
126- log,
127- ),
173+ typePropagatorPhase (),
128174 // After type propagation, more instructions can be simplified.
129- SsaInstructionSimplifier (
130- globalInferenceResults,
131- _options,
132- closedWorld,
133- typeRecipeDomain,
134- registry,
135- log,
136- metrics,
137- ),
138- SsaInstructionSimplifier (
139- globalInferenceResults,
140- _options,
141- closedWorld,
142- typeRecipeDomain,
143- registry,
144- log,
145- metrics,
146- ),
147- SsaTypePropagator (
148- globalInferenceResults,
149- closedWorld.commonElements,
150- closedWorld,
151- log,
152- ),
175+ simplifierPhase (),
176+ simplifierPhase (),
177+ typePropagatorPhase (),
153178 // Run a dead code eliminator before LICM because dead
154179 // interceptors are often in the way of LICM'able instructions.
155180 SsaDeadCodeEliminator (closedWorld, this ),
156181 SsaGlobalValueNumberer (closedWorld.abstractValueDomain),
157182 // After GVN, some instructions might need their type to be
158183 // updated because they now have different inputs.
159- SsaTypePropagator (
160- globalInferenceResults,
161- closedWorld.commonElements,
162- closedWorld,
163- log,
164- ),
184+ typePropagatorPhase (),
165185 codeMotion = SsaCodeMotion (closedWorld.abstractValueDomain),
166186 loadElimination = SsaLoadElimination (closedWorld),
167187 SsaRedundantPhiEliminator (),
@@ -171,29 +191,16 @@ class SsaOptimizerTask extends CompilerTask {
171191 // controlled by a test on the value, so redo 'conversion insertion' to
172192 // learn from the refined type.
173193 SsaTypeConversionInserter (closedWorld),
174- SsaTypePropagator (
175- globalInferenceResults,
176- closedWorld.commonElements,
177- closedWorld,
178- log,
179- ),
194+ typePropagatorPhase (),
180195 SsaValueRangeAnalyzer (closedWorld, this , codegen.tracer),
181196 // Previous optimizations may have generated new
182197 // opportunities for instruction simplification.
183- SsaInstructionSimplifier (
184- globalInferenceResults,
185- _options,
186- closedWorld,
187- typeRecipeDomain,
188- registry,
189- log,
190- metrics,
191- ),
198+ simplifierPhase (),
192199 ];
193200 phases.forEach (runPhase);
194201
195- // Simplifying interceptors is just an optimization, it is required for
196- // implementation correctness because the code generator assumes it is
202+ // Simplifying interceptors is not just an optimization, it is required
203+ // for implementation correctness because the code generator assumes it is
197204 // always performed to compute the intercepted classes sets.
198205 runPhase (SsaSimplifyInterceptors (closedWorld, member.enclosingClass));
199206
@@ -204,46 +211,20 @@ class SsaOptimizerTask extends CompilerTask {
204211 dce.newGvnCandidates ||
205212 loadElimination.newGvnCandidates) {
206213 phases = [
207- SsaTypePropagator (
208- globalInferenceResults,
209- closedWorld.commonElements,
210- closedWorld,
211- log,
212- ),
214+ typePropagatorPhase (),
213215 SsaGlobalValueNumberer (closedWorld.abstractValueDomain),
214216 SsaCodeMotion (closedWorld.abstractValueDomain),
215217 SsaValueRangeAnalyzer (closedWorld, this , codegen.tracer),
216- SsaInstructionSimplifier (
217- globalInferenceResults,
218- _options,
219- closedWorld,
220- typeRecipeDomain,
221- registry,
222- log,
223- metrics,
224- ),
218+ simplifierPhase (),
225219 SsaSimplifyInterceptors (closedWorld, member.enclosingClass),
226220 SsaDeadCodeEliminator (closedWorld, this ),
227221 ];
228222 } else {
229223 phases = [
230- SsaTypePropagator (
231- globalInferenceResults,
232- closedWorld.commonElements,
233- closedWorld,
234- log,
235- ),
224+ typePropagatorPhase (),
236225 // Run the simplifier to remove unneeded type checks inserted by
237226 // type propagation.
238- SsaInstructionSimplifier (
239- globalInferenceResults,
240- _options,
241- closedWorld,
242- typeRecipeDomain,
243- registry,
244- log,
245- metrics,
246- ),
227+ simplifierPhase (),
247228 ];
248229 }
249230 phases.forEach (runPhase);
@@ -1028,6 +1009,8 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
10281009 resultMask,
10291010 const < DartType > [],
10301011 );
1012+ _updateInvocationAttributes (tagInstruction, commonElements.setArrayType);
1013+
10311014 // 'Linear typing' trick: [tagInstruction] is the only use of the
10321015 // [splitInstruction], so it becomes the sole alias.
10331016 // TODO(sra): Build this knowledge into alias analysis.
@@ -1073,15 +1056,7 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
10731056 node.element = method;
10741057 }
10751058
1076- node.sideEffects.restrictTo (
1077- _globalInferenceResults.inferredData.getSideEffectsOfElement (element),
1078- );
1079- if (_closedWorld.annotationsData.allowCSE (element)) {
1080- node.allowCSE = true ;
1081- }
1082- if (_closedWorld.annotationsData.allowDCE (element)) {
1083- node.allowDCE = true ;
1084- }
1059+ _updateInvocationAttributes (node, method);
10851060
10861061 return node;
10871062 }
@@ -2091,15 +2066,7 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
20912066 if (_nativeData.isNativeMember (member)) {
20922067 return tryInlineNativeGetter (node, member) ?? node;
20932068 }
2094- node.sideEffects.restrictTo (
2095- _globalInferenceResults.inferredData.getSideEffectsOfElement (member),
2096- );
2097- if (_closedWorld.annotationsData.allowCSE (member)) {
2098- node.allowCSE = true ;
2099- }
2100- if (_closedWorld.annotationsData.allowDCE (member)) {
2101- node.allowDCE = true ;
2102- }
2069+ _updateInvocationAttributes (node, member);
21032070 }
21042071 }
21052072
@@ -2113,6 +2080,18 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
21132080 return node;
21142081 }
21152082
2083+ void _updateInvocationAttributes (HInvoke node, FunctionEntity member) {
2084+ node.sideEffects.restrictTo (
2085+ _globalInferenceResults.inferredData.getSideEffectsOfElement (member),
2086+ );
2087+ if (_closedWorld.annotationsData.allowCSE (member)) {
2088+ node.allowCSE = true ;
2089+ }
2090+ if (_closedWorld.annotationsData.allowDCE (member)) {
2091+ node.allowDCE = true ;
2092+ }
2093+ }
2094+
21162095 HFieldGet _directFieldGet (
21172096 HInstruction receiver,
21182097 FieldEntity field,
@@ -3197,13 +3176,13 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
31973176 final String name = "SsaDeadCodeEliminator" ;
31983177
31993178 final JClosedWorld closedWorld;
3200- final SsaOptimizerTask optimizer ;
3179+ final SsaOptimizerWorkItem workItem ;
32013180 late final HGraph _graph;
32023181 Map <HInstruction , bool > trivialDeadStoreReceivers = Maplet ();
32033182 bool eliminatedSideEffects = false ;
32043183 bool newGvnCandidates = false ;
32053184
3206- SsaDeadCodeEliminator (this .closedWorld, this .optimizer );
3185+ SsaDeadCodeEliminator (this .closedWorld, this .workItem );
32073186
32083187 AbstractValueDomain get _abstractValueDomain =>
32093188 closedWorld.abstractValueDomain;
@@ -3261,7 +3240,7 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
32613240 }
32623241
32633242 void _computeLiveness () {
3264- var analyzer = SsaLiveBlockAnalyzer (_graph, closedWorld, optimizer );
3243+ var analyzer = SsaLiveBlockAnalyzer (_graph, closedWorld, workItem );
32653244 analyzer.analyze ();
32663245 for (HBasicBlock block in _graph.blocks) {
32673246 block.isLive = analyzer.isLiveBlock (block);
@@ -3511,15 +3490,15 @@ class SsaLiveBlockAnalyzer extends HBaseVisitor<void> {
35113490 final HGraph graph;
35123491 final Set <HBasicBlock > live = {};
35133492 final List <HBasicBlock > worklist = [];
3514- final SsaOptimizerTask optimizer ;
3493+ final SsaOptimizerWorkItem workItem ;
35153494 final JClosedWorld closedWorld;
35163495
3517- SsaLiveBlockAnalyzer (this .graph, this .closedWorld, this .optimizer );
3496+ SsaLiveBlockAnalyzer (this .graph, this .closedWorld, this .workItem );
35183497
35193498 AbstractValueDomain get _abstractValueDomain =>
35203499 closedWorld.abstractValueDomain;
35213500
3522- Map <HInstruction , Range > get ranges => optimizer .ranges;
3501+ Map <HInstruction , Range > get ranges => workItem .ranges;
35233502
35243503 bool isLiveBlock (HBasicBlock block) => live.contains (block);
35253504
0 commit comments