@@ -120,7 +120,122 @@ private void removePhis() {
120120 }
121121
122122 private void sequenceParallelCopies () {
123+ for (var block : function .getBlocks ()) {
124+ var pcopy = parallelCopies .get (block );
125+ if (pcopy .pCopyBegin != null )
126+ sequenceParallelCopy (block ,pcopy .pCopyBegin );
127+ if (pcopy .pCopyEnd != null )
128+ sequenceParallelCopy (block ,pcopy .pCopyEnd );
129+ }
130+ }
131+
132+ private void replaceInstruction (BasicBlock block , Instruction .ParallelCopyInstruction pcopy , ArrayList <Instruction > instructions ) {
133+ block .replaceInstruction (pcopy , instructions );
134+ }
135+
136+ static final class Copy {
137+ Operand src ;
138+ Operand dest ;
139+ boolean removed = false ;
140+
141+ public Copy (Operand src , Operand dest ) {
142+ this .src = src ;
143+ this .dest = dest ;
144+ }
145+ }
146+
147+ List <Copy > getCopies (Instruction .ParallelCopyInstruction pcopy ) {
148+ List <Copy > copies = new ArrayList <>();
149+ for (int i = 0 ; i < pcopy .sourceOperands .size (); i ++) {
150+ var src = pcopy .sourceOperands .get (i );
151+ var dest = pcopy .destOperands .get (i );
152+ if (src instanceof Operand .RegisterOperand srcR && dest instanceof Operand .RegisterOperand destR ) {
153+ if (srcR .reg .id == destR .reg .id )
154+ continue ;
155+ }
156+ copies .add (new Copy (src ,dest ));
157+ }
158+ return copies ;
159+ }
160+
161+ private void sequenceParallelCopy (BasicBlock block , Instruction .ParallelCopyInstruction pcopy ) {
162+ var copyInstructions = new ArrayList <Instruction >();
163+ var copies = getCopies (pcopy );
164+
165+ while (copies .size () > 0 ) {
166+ boolean progress = false ;
167+
168+ for (var copy : copies ) {
169+ boolean cycle = false ;
170+ for (int i = 0 ; i < copies .size (); i ++) {
171+ if (copy .removed == true )
172+ continue ;
173+ if (copy .src .equals (copies .get (i ).dest )) {
174+ cycle = true ;
175+ break ;
176+ }
177+ }
178+ if (!cycle ) {
179+ copyInstructions .add (new Instruction .Move (copy .src ,copy .dest ));
180+ copy .removed = true ;
181+ progress = true ;
182+ }
183+ }
184+
185+ copies .removeIf (c ->c .removed );
186+ if (progress )
187+ continue ;
188+
189+ var copy = copies .removeFirst ();
190+ var temp = new Operand .RegisterOperand (function .registerPool .newTempReg (copy .src .type ));
191+ copyInstructions .add (new Instruction .Move (copy .src ,temp ));
192+ copies .add (new Copy (copy .dest ,temp ));
193+ }
194+ replaceInstruction (block ,pcopy ,copyInstructions );
195+ }
123196
197+ private void sequenceParallelCopyX (BasicBlock block , Instruction .ParallelCopyInstruction pcopy ) {
198+ var copyInstructions = new ArrayList <Instruction >();
199+ var ready = new ArrayList <Operand >();
200+ var toDo = new ArrayList <Operand >();
201+ var directPred = new HashMap <Operand ,Operand >();
202+ var loc = new HashMap <Operand ,Operand >();
203+ for (int i = 0 ; i <pcopy .sourceOperands .size (); i ++) {
204+ var a = pcopy .sourceOperands .get (i );
205+ var b = pcopy .destOperands .get (i );
206+ if (a .equals (b ))
207+ continue ;
208+ loc .put (a ,a );
209+ directPred .put (b ,a );
210+ toDo .add (b );
211+ }
212+ for (int i = 0 ; i <pcopy .sourceOperands .size (); i ++) {
213+ var a = pcopy .sourceOperands .get (i );
214+ var b = pcopy .destOperands .get (i );
215+ if (a == b )
216+ continue ;
217+ if (loc .get (b ) == null )
218+ ready .add (b );
219+ }
220+ while (!toDo .isEmpty ()) {
221+ while (!ready .isEmpty ()) {
222+ var b = ready .removeLast ();
223+ var a = directPred .get (b );
224+ var c = loc .get (a );
225+ copyInstructions .add (new Instruction .Move (c ,b ));
226+ loc .put (a ,b );
227+ if (a == c && directPred .get (a ) != null )
228+ ready .add (a );
229+ }
230+ var b = toDo .removeLast ();
231+ if (b == loc .get (directPred .get (b ))) {
232+ var n = new Operand .RegisterOperand (function .registerPool .newTempReg (b .type ));
233+ copyInstructions .add (new Instruction .Move (b ,n ));
234+ loc .put (b ,n );
235+ ready .add (b );
236+ }
237+ }
238+ replaceInstruction (block ,pcopy ,copyInstructions );
124239 }
125240
126241 static final class PCopy {
0 commit comments