1 //===-- AArch64A57FPLoadBalancing.cpp - Balance FP ops statically on A57---===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // For best-case performance on Cortex-A57, we should try to use a balanced
10 // mix of odd and even D-registers when performing a critical sequence of
11 // independent, non-quadword FP/ASIMD floating-point multiply or
12 // multiply-accumulate operations.
13 //
14 // This pass attempts to detect situations where the register allocation may
15 // adversely affect this load balancing and to change the registers used so as
16 // to better utilize the CPU.
17 //
18 // Ideally we'd just take each multiply or multiply-accumulate in turn and
19 // allocate it alternating even or odd registers. However, multiply-accumulates
20 // are most efficiently performed in the same functional unit as their
21 // accumulation operand. Therefore this pass tries to find maximal sequences
22 // ("Chains") of multiply-accumulates linked via their accumulation operand,
23 // and assign them all the same "color" (oddness/evenness).
24 //
25 // This optimization affects S-register and D-register floating point
26 // multiplies and FMADD/FMAs, as well as vector (floating point only) muls and
27 // FMADD/FMA. Q register instructions (and 128-bit vector instructions) are
28 // not affected.
29 //===----------------------------------------------------------------------===//
30 
31 #include "AArch64.h"
32 #include "AArch64InstrInfo.h"
33 #include "AArch64Subtarget.h"
34 #include "llvm/ADT/BitVector.h"
35 #include "llvm/ADT/EquivalenceClasses.h"
36 #include "llvm/CodeGen/MachineFunction.h"
37 #include "llvm/CodeGen/MachineFunctionPass.h"
38 #include "llvm/CodeGen/MachineInstr.h"
39 #include "llvm/CodeGen/MachineInstrBuilder.h"
40 #include "llvm/CodeGen/MachineRegisterInfo.h"
41 #include "llvm/CodeGen/RegisterClassInfo.h"
42 #include "llvm/CodeGen/RegisterScavenging.h"
43 #include "llvm/Support/CommandLine.h"
44 #include "llvm/Support/Debug.h"
45 #include "llvm/Support/raw_ostream.h"
46 using namespace llvm;
47 
48 #define DEBUG_TYPE "aarch64-a57-fp-load-balancing"
49 
50 // Enforce the algorithm to use the scavenged register even when the original
51 // destination register is the correct color. Used for testing.
52 static cl::opt<bool>
53 TransformAll("aarch64-a57-fp-load-balancing-force-all",
54              cl::desc("Always modify dest registers regardless of color"),
55              cl::init(false), cl::Hidden);
56 
57 // Never use the balance information obtained from chains - return a specific
58 // color always. Used for testing.
59 static cl::opt<unsigned>
60 OverrideBalance("aarch64-a57-fp-load-balancing-override",
61               cl::desc("Ignore balance information, always return "
62                        "(1: Even, 2: Odd)."),
63               cl::init(0), cl::Hidden);
64 
65 //===----------------------------------------------------------------------===//
66 // Helper functions
67 
68 // Is the instruction a type of multiply on 64-bit (or 32-bit) FPRs?
69 static bool isMul(MachineInstr *MI) {
70   switch (MI->getOpcode()) {
71   case AArch64::FMULSrr:
72   case AArch64::FNMULSrr:
73   case AArch64::FMULDrr:
74   case AArch64::FNMULDrr:
75     return true;
76   default:
77     return false;
78   }
79 }
80 
81 // Is the instruction a type of FP multiply-accumulate on 64-bit (or 32-bit) FPRs?
82 static bool isMla(MachineInstr *MI) {
83   switch (MI->getOpcode()) {
84   case AArch64::FMSUBSrrr:
85   case AArch64::FMADDSrrr:
86   case AArch64::FNMSUBSrrr:
87   case AArch64::FNMADDSrrr:
88   case AArch64::FMSUBDrrr:
89   case AArch64::FMADDDrrr:
90   case AArch64::FNMSUBDrrr:
91   case AArch64::FNMADDDrrr:
92     return true;
93   default:
94     return false;
95   }
96 }
97 
98 namespace llvm {
99 static void initializeAArch64A57FPLoadBalancingPass(PassRegistry &);
100 }
101 
102 //===----------------------------------------------------------------------===//
103 
104 namespace {
105 /// A "color", which is either even or odd. Yes, these aren't really colors
106 /// but the algorithm is conceptually doing two-color graph coloring.
107 enum class Color { Even, Odd };
108 #ifndef NDEBUG
109 static const char *ColorNames[2] = { "Even", "Odd" };
110 #endif
111 
112 class Chain;
113 
114 class AArch64A57FPLoadBalancing : public MachineFunctionPass {
115   MachineRegisterInfo *MRI;
116   const TargetRegisterInfo *TRI;
117   RegisterClassInfo RCI;
118 
119 public:
120   static char ID;
121   explicit AArch64A57FPLoadBalancing() : MachineFunctionPass(ID) {
122     initializeAArch64A57FPLoadBalancingPass(*PassRegistry::getPassRegistry());
123   }
124 
125   bool runOnMachineFunction(MachineFunction &F) override;
126 
127   MachineFunctionProperties getRequiredProperties() const override {
128     return MachineFunctionProperties().set(
129         MachineFunctionProperties::Property::AllVRegsAllocated);
130   }
131 
132   const char *getPassName() const override {
133     return "A57 FP Anti-dependency breaker";
134   }
135 
136   void getAnalysisUsage(AnalysisUsage &AU) const override {
137     AU.setPreservesCFG();
138     MachineFunctionPass::getAnalysisUsage(AU);
139   }
140 
141 private:
142   bool runOnBasicBlock(MachineBasicBlock &MBB);
143   bool colorChainSet(std::vector<Chain*> GV, MachineBasicBlock &MBB,
144                      int &Balance);
145   bool colorChain(Chain *G, Color C, MachineBasicBlock &MBB);
146   int scavengeRegister(Chain *G, Color C, MachineBasicBlock &MBB);
147   void scanInstruction(MachineInstr *MI, unsigned Idx,
148                        std::map<unsigned, Chain*> &Active,
149                        std::vector<std::unique_ptr<Chain>> &AllChains);
150   void maybeKillChain(MachineOperand &MO, unsigned Idx,
151                       std::map<unsigned, Chain*> &RegChains);
152   Color getColor(unsigned Register);
153   Chain *getAndEraseNext(Color PreferredColor, std::vector<Chain*> &L);
154 };
155 }
156 
157 char AArch64A57FPLoadBalancing::ID = 0;
158 
159 INITIALIZE_PASS_BEGIN(AArch64A57FPLoadBalancing, DEBUG_TYPE,
160                       "AArch64 A57 FP Load-Balancing", false, false)
161 INITIALIZE_PASS_END(AArch64A57FPLoadBalancing, DEBUG_TYPE,
162                     "AArch64 A57 FP Load-Balancing", false, false)
163 
164 namespace {
165 /// A Chain is a sequence of instructions that are linked together by
166 /// an accumulation operand. For example:
167 ///
168 ///   fmul d0<def>, ?
169 ///   fmla d1<def>, ?, ?, d0<kill>
170 ///   fmla d2<def>, ?, ?, d1<kill>
171 ///
172 /// There may be other instructions interleaved in the sequence that
173 /// do not belong to the chain. These other instructions must not use
174 /// the "chain" register at any point.
175 ///
176 /// We currently only support chains where the "chain" operand is killed
177 /// at each link in the chain for simplicity.
178 /// A chain has three important instructions - Start, Last and Kill.
179 ///   * The start instruction is the first instruction in the chain.
180 ///   * Last is the final instruction in the chain.
181 ///   * Kill may or may not be defined. If defined, Kill is the instruction
182 ///     where the outgoing value of the Last instruction is killed.
183 ///     This information is important as if we know the outgoing value is
184 ///     killed with no intervening uses, we can safely change its register.
185 ///
186 /// Without a kill instruction, we must assume the outgoing value escapes
187 /// beyond our model and either must not change its register or must
188 /// create a fixup FMOV to keep the old register value consistent.
189 ///
190 class Chain {
191 public:
192   /// The important (marker) instructions.
193   MachineInstr *StartInst, *LastInst, *KillInst;
194   /// The index, from the start of the basic block, that each marker
195   /// appears. These are stored so we can do quick interval tests.
196   unsigned StartInstIdx, LastInstIdx, KillInstIdx;
197   /// All instructions in the chain.
198   std::set<MachineInstr*> Insts;
199   /// True if KillInst cannot be modified. If this is true,
200   /// we cannot change LastInst's outgoing register.
201   /// This will be true for tied values and regmasks.
202   bool KillIsImmutable;
203   /// The "color" of LastInst. This will be the preferred chain color,
204   /// as changing intermediate nodes is easy but changing the last
205   /// instruction can be more tricky.
206   Color LastColor;
207 
208   Chain(MachineInstr *MI, unsigned Idx, Color C)
209       : StartInst(MI), LastInst(MI), KillInst(nullptr),
210         StartInstIdx(Idx), LastInstIdx(Idx), KillInstIdx(0),
211         LastColor(C) {
212     Insts.insert(MI);
213   }
214 
215   /// Add a new instruction into the chain. The instruction's dest operand
216   /// has the given color.
217   void add(MachineInstr *MI, unsigned Idx, Color C) {
218     LastInst = MI;
219     LastInstIdx = Idx;
220     LastColor = C;
221     assert((KillInstIdx == 0 || LastInstIdx < KillInstIdx) &&
222            "Chain: broken invariant. A Chain can only be killed after its last "
223            "def");
224 
225     Insts.insert(MI);
226   }
227 
228   /// Return true if MI is a member of the chain.
229   bool contains(MachineInstr *MI) { return Insts.count(MI) > 0; }
230 
231   /// Return the number of instructions in the chain.
232   unsigned size() const {
233     return Insts.size();
234   }
235 
236   /// Inform the chain that its last active register (the dest register of
237   /// LastInst) is killed by MI with no intervening uses or defs.
238   void setKill(MachineInstr *MI, unsigned Idx, bool Immutable) {
239     KillInst = MI;
240     KillInstIdx = Idx;
241     KillIsImmutable = Immutable;
242     assert((KillInstIdx == 0 || LastInstIdx < KillInstIdx) &&
243            "Chain: broken invariant. A Chain can only be killed after its last "
244            "def");
245   }
246 
247   /// Return the first instruction in the chain.
248   MachineInstr *getStart() const { return StartInst; }
249   /// Return the last instruction in the chain.
250   MachineInstr *getLast() const { return LastInst; }
251   /// Return the "kill" instruction (as set with setKill()) or NULL.
252   MachineInstr *getKill() const { return KillInst; }
253   /// Return an instruction that can be used as an iterator for the end
254   /// of the chain. This is the maximum of KillInst (if set) and LastInst.
255   MachineBasicBlock::iterator getEnd() const {
256     return ++MachineBasicBlock::iterator(KillInst ? KillInst : LastInst);
257   }
258 
259   /// Can the Kill instruction (assuming one exists) be modified?
260   bool isKillImmutable() const { return KillIsImmutable; }
261 
262   /// Return the preferred color of this chain.
263   Color getPreferredColor() {
264     if (OverrideBalance != 0)
265       return OverrideBalance == 1 ? Color::Even : Color::Odd;
266     return LastColor;
267   }
268 
269   /// Return true if this chain (StartInst..KillInst) overlaps with Other.
270   bool rangeOverlapsWith(const Chain &Other) const {
271     unsigned End = KillInst ? KillInstIdx : LastInstIdx;
272     unsigned OtherEnd = Other.KillInst ?
273       Other.KillInstIdx : Other.LastInstIdx;
274 
275     return StartInstIdx <= OtherEnd && Other.StartInstIdx <= End;
276   }
277 
278   /// Return true if this chain starts before Other.
279   bool startsBefore(const Chain *Other) const {
280     return StartInstIdx < Other->StartInstIdx;
281   }
282 
283   /// Return true if the group will require a fixup MOV at the end.
284   bool requiresFixup() const {
285     return (getKill() && isKillImmutable()) || !getKill();
286   }
287 
288   /// Return a simple string representation of the chain.
289   std::string str() const {
290     std::string S;
291     raw_string_ostream OS(S);
292 
293     OS << "{";
294     StartInst->print(OS, /* SkipOpers= */true);
295     OS << " -> ";
296     LastInst->print(OS, /* SkipOpers= */true);
297     if (KillInst) {
298       OS << " (kill @ ";
299       KillInst->print(OS, /* SkipOpers= */true);
300       OS << ")";
301     }
302     OS << "}";
303 
304     return OS.str();
305   }
306 
307 };
308 
309 } // end anonymous namespace
310 
311 //===----------------------------------------------------------------------===//
312 
313 bool AArch64A57FPLoadBalancing::runOnMachineFunction(MachineFunction &F) {
314   if (skipFunction(*F.getFunction()))
315     return false;
316 
317   if (!F.getSubtarget<AArch64Subtarget>().balanceFPOps())
318     return false;
319 
320   bool Changed = false;
321   DEBUG(dbgs() << "***** AArch64A57FPLoadBalancing *****\n");
322 
323   MRI = &F.getRegInfo();
324   TRI = F.getRegInfo().getTargetRegisterInfo();
325   RCI.runOnMachineFunction(F);
326 
327   for (auto &MBB : F) {
328     Changed |= runOnBasicBlock(MBB);
329   }
330 
331   return Changed;
332 }
333 
334 bool AArch64A57FPLoadBalancing::runOnBasicBlock(MachineBasicBlock &MBB) {
335   bool Changed = false;
336   DEBUG(dbgs() << "Running on MBB: " << MBB << " - scanning instructions...\n");
337 
338   // First, scan the basic block producing a set of chains.
339 
340   // The currently "active" chains - chains that can be added to and haven't
341   // been killed yet. This is keyed by register - all chains can only have one
342   // "link" register between each inst in the chain.
343   std::map<unsigned, Chain*> ActiveChains;
344   std::vector<std::unique_ptr<Chain>> AllChains;
345   unsigned Idx = 0;
346   for (auto &MI : MBB)
347     scanInstruction(&MI, Idx++, ActiveChains, AllChains);
348 
349   DEBUG(dbgs() << "Scan complete, "<< AllChains.size() << " chains created.\n");
350 
351   // Group the chains into disjoint sets based on their liveness range. This is
352   // a poor-man's version of graph coloring. Ideally we'd create an interference
353   // graph and perform full-on graph coloring on that, but;
354   //   (a) That's rather heavyweight for only two colors.
355   //   (b) We expect multiple disjoint interference regions - in practice the live
356   //       range of chains is quite small and they are clustered between loads
357   //       and stores.
358   EquivalenceClasses<Chain*> EC;
359   for (auto &I : AllChains)
360     EC.insert(I.get());
361 
362   for (auto &I : AllChains)
363     for (auto &J : AllChains)
364       if (I != J && I->rangeOverlapsWith(*J))
365         EC.unionSets(I.get(), J.get());
366   DEBUG(dbgs() << "Created " << EC.getNumClasses() << " disjoint sets.\n");
367 
368   // Now we assume that every member of an equivalence class interferes
369   // with every other member of that class, and with no members of other classes.
370 
371   // Convert the EquivalenceClasses to a simpler set of sets.
372   std::vector<std::vector<Chain*> > V;
373   for (auto I = EC.begin(), E = EC.end(); I != E; ++I) {
374     std::vector<Chain*> Cs(EC.member_begin(I), EC.member_end());
375     if (Cs.empty()) continue;
376     V.push_back(std::move(Cs));
377   }
378 
379   // Now we have a set of sets, order them by start address so
380   // we can iterate over them sequentially.
381   std::sort(V.begin(), V.end(),
382             [](const std::vector<Chain*> &A,
383                const std::vector<Chain*> &B) {
384       return A.front()->startsBefore(B.front());
385     });
386 
387   // As we only have two colors, we can track the global (BB-level) balance of
388   // odds versus evens. We aim to keep this near zero to keep both execution
389   // units fed.
390   // Positive means we're even-heavy, negative we're odd-heavy.
391   //
392   // FIXME: If chains have interdependencies, for example:
393   //   mul r0, r1, r2
394   //   mul r3, r0, r1
395   // We do not model this and may color each one differently, assuming we'll
396   // get ILP when we obviously can't. This hasn't been seen to be a problem
397   // in practice so far, so we simplify the algorithm by ignoring it.
398   int Parity = 0;
399 
400   for (auto &I : V)
401     Changed |= colorChainSet(std::move(I), MBB, Parity);
402 
403   return Changed;
404 }
405 
406 Chain *AArch64A57FPLoadBalancing::getAndEraseNext(Color PreferredColor,
407                                                   std::vector<Chain*> &L) {
408   if (L.empty())
409     return nullptr;
410 
411   // We try and get the best candidate from L to color next, given that our
412   // preferred color is "PreferredColor". L is ordered from larger to smaller
413   // chains. It is beneficial to color the large chains before the small chains,
414   // but if we can't find a chain of the maximum length with the preferred color,
415   // we fuzz the size and look for slightly smaller chains before giving up and
416   // returning a chain that must be recolored.
417 
418   // FIXME: Does this need to be configurable?
419   const unsigned SizeFuzz = 1;
420   unsigned MinSize = L.front()->size() - SizeFuzz;
421   for (auto I = L.begin(), E = L.end(); I != E; ++I) {
422     if ((*I)->size() <= MinSize) {
423       // We've gone past the size limit. Return the previous item.
424       Chain *Ch = *--I;
425       L.erase(I);
426       return Ch;
427     }
428 
429     if ((*I)->getPreferredColor() == PreferredColor) {
430       Chain *Ch = *I;
431       L.erase(I);
432       return Ch;
433     }
434   }
435 
436   // Bailout case - just return the first item.
437   Chain *Ch = L.front();
438   L.erase(L.begin());
439   return Ch;
440 }
441 
442 bool AArch64A57FPLoadBalancing::colorChainSet(std::vector<Chain*> GV,
443                                               MachineBasicBlock &MBB,
444                                               int &Parity) {
445   bool Changed = false;
446   DEBUG(dbgs() << "colorChainSet(): #sets=" << GV.size() << "\n");
447 
448   // Sort by descending size order so that we allocate the most important
449   // sets first.
450   // Tie-break equivalent sizes by sorting chains requiring fixups before
451   // those without fixups. The logic here is that we should look at the
452   // chains that we cannot change before we look at those we can,
453   // so the parity counter is updated and we know what color we should
454   // change them to!
455   // Final tie-break with instruction order so pass output is stable (i.e. not
456   // dependent on malloc'd pointer values).
457   std::sort(GV.begin(), GV.end(), [](const Chain *G1, const Chain *G2) {
458       if (G1->size() != G2->size())
459         return G1->size() > G2->size();
460       if (G1->requiresFixup() != G2->requiresFixup())
461         return G1->requiresFixup() > G2->requiresFixup();
462       // Make sure startsBefore() produces a stable final order.
463       assert((G1 == G2 || (G1->startsBefore(G2) ^ G2->startsBefore(G1))) &&
464              "Starts before not total order!");
465       return G1->startsBefore(G2);
466     });
467 
468   Color PreferredColor = Parity < 0 ? Color::Even : Color::Odd;
469   while (Chain *G = getAndEraseNext(PreferredColor, GV)) {
470     // Start off by assuming we'll color to our own preferred color.
471     Color C = PreferredColor;
472     if (Parity == 0)
473       // But if we really don't care, use the chain's preferred color.
474       C = G->getPreferredColor();
475 
476     DEBUG(dbgs() << " - Parity=" << Parity << ", Color="
477           << ColorNames[(int)C] << "\n");
478 
479     // If we'll need a fixup FMOV, don't bother. Testing has shown that this
480     // happens infrequently and when it does it has at least a 50% chance of
481     // slowing code down instead of speeding it up.
482     if (G->requiresFixup() && C != G->getPreferredColor()) {
483       C = G->getPreferredColor();
484       DEBUG(dbgs() << " - " << G->str() << " - not worthwhile changing; "
485             "color remains " << ColorNames[(int)C] << "\n");
486     }
487 
488     Changed |= colorChain(G, C, MBB);
489 
490     Parity += (C == Color::Even) ? G->size() : -G->size();
491     PreferredColor = Parity < 0 ? Color::Even : Color::Odd;
492   }
493 
494   return Changed;
495 }
496 
497 int AArch64A57FPLoadBalancing::scavengeRegister(Chain *G, Color C,
498                                                 MachineBasicBlock &MBB) {
499   RegScavenger RS;
500   RS.enterBasicBlock(MBB);
501   RS.forward(MachineBasicBlock::iterator(G->getStart()));
502 
503   // Can we find an appropriate register that is available throughout the life
504   // of the chain?
505   unsigned RegClassID = G->getStart()->getDesc().OpInfo[0].RegClass;
506   BitVector AvailableRegs = RS.getRegsAvailable(TRI->getRegClass(RegClassID));
507   for (MachineBasicBlock::iterator I = G->getStart(), E = G->getEnd();
508        I != E; ++I) {
509     RS.forward(I);
510     AvailableRegs &= RS.getRegsAvailable(TRI->getRegClass(RegClassID));
511 
512     // Remove any registers clobbered by a regmask or any def register that is
513     // immediately dead.
514     for (auto J : I->operands()) {
515       if (J.isRegMask())
516         AvailableRegs.clearBitsNotInMask(J.getRegMask());
517 
518       if (J.isReg() && J.isDef()) {
519         MCRegAliasIterator AI(J.getReg(), TRI, /*IncludeSelf=*/true);
520         if (J.isDead())
521           for (; AI.isValid(); ++AI)
522             AvailableRegs.reset(*AI);
523 #ifndef NDEBUG
524         else
525           for (; AI.isValid(); ++AI)
526             assert(!AvailableRegs[*AI] &&
527                    "Non-dead def should have been removed by now!");
528 #endif
529       }
530     }
531   }
532 
533   // Make sure we allocate in-order, to get the cheapest registers first.
534   auto Ord = RCI.getOrder(TRI->getRegClass(RegClassID));
535   for (auto Reg : Ord) {
536     if (!AvailableRegs[Reg])
537       continue;
538     if (C == getColor(Reg))
539       return Reg;
540   }
541 
542   return -1;
543 }
544 
545 bool AArch64A57FPLoadBalancing::colorChain(Chain *G, Color C,
546                                            MachineBasicBlock &MBB) {
547   bool Changed = false;
548   DEBUG(dbgs() << " - colorChain(" << G->str() << ", "
549         << ColorNames[(int)C] << ")\n");
550 
551   // Try and obtain a free register of the right class. Without a register
552   // to play with we cannot continue.
553   int Reg = scavengeRegister(G, C, MBB);
554   if (Reg == -1) {
555     DEBUG(dbgs() << "Scavenging (thus coloring) failed!\n");
556     return false;
557   }
558   DEBUG(dbgs() << " - Scavenged register: " << TRI->getName(Reg) << "\n");
559 
560   std::map<unsigned, unsigned> Substs;
561   for (MachineBasicBlock::iterator I = G->getStart(), E = G->getEnd();
562        I != E; ++I) {
563     if (!G->contains(I) &&
564         (&*I != G->getKill() || G->isKillImmutable()))
565       continue;
566 
567     // I is a member of G, or I is a mutable instruction that kills G.
568 
569     std::vector<unsigned> ToErase;
570     for (auto &U : I->operands()) {
571       if (U.isReg() && U.isUse() && Substs.find(U.getReg()) != Substs.end()) {
572         unsigned OrigReg = U.getReg();
573         U.setReg(Substs[OrigReg]);
574         if (U.isKill())
575           // Don't erase straight away, because there may be other operands
576           // that also reference this substitution!
577           ToErase.push_back(OrigReg);
578       } else if (U.isRegMask()) {
579         for (auto J : Substs) {
580           if (U.clobbersPhysReg(J.first))
581             ToErase.push_back(J.first);
582         }
583       }
584     }
585     // Now it's safe to remove the substs identified earlier.
586     for (auto J : ToErase)
587       Substs.erase(J);
588 
589     // Only change the def if this isn't the last instruction.
590     if (&*I != G->getKill()) {
591       MachineOperand &MO = I->getOperand(0);
592 
593       bool Change = TransformAll || getColor(MO.getReg()) != C;
594       if (G->requiresFixup() && &*I == G->getLast())
595         Change = false;
596 
597       if (Change) {
598         Substs[MO.getReg()] = Reg;
599         MO.setReg(Reg);
600 
601         Changed = true;
602       }
603     }
604   }
605   assert(Substs.size() == 0 && "No substitutions should be left active!");
606 
607   if (G->getKill()) {
608     DEBUG(dbgs() << " - Kill instruction seen.\n");
609   } else {
610     // We didn't have a kill instruction, but we didn't seem to need to change
611     // the destination register anyway.
612     DEBUG(dbgs() << " - Destination register not changed.\n");
613   }
614   return Changed;
615 }
616 
617 void AArch64A57FPLoadBalancing::scanInstruction(
618     MachineInstr *MI, unsigned Idx, std::map<unsigned, Chain *> &ActiveChains,
619     std::vector<std::unique_ptr<Chain>> &AllChains) {
620   // Inspect "MI", updating ActiveChains and AllChains.
621 
622   if (isMul(MI)) {
623 
624     for (auto &I : MI->uses())
625       maybeKillChain(I, Idx, ActiveChains);
626     for (auto &I : MI->defs())
627       maybeKillChain(I, Idx, ActiveChains);
628 
629     // Create a new chain. Multiplies don't require forwarding so can go on any
630     // unit.
631     unsigned DestReg = MI->getOperand(0).getReg();
632 
633     DEBUG(dbgs() << "New chain started for register "
634           << TRI->getName(DestReg) << " at " << *MI);
635 
636     auto G = llvm::make_unique<Chain>(MI, Idx, getColor(DestReg));
637     ActiveChains[DestReg] = G.get();
638     AllChains.push_back(std::move(G));
639 
640   } else if (isMla(MI)) {
641 
642     // It is beneficial to keep MLAs on the same functional unit as their
643     // accumulator operand.
644     unsigned DestReg  = MI->getOperand(0).getReg();
645     unsigned AccumReg = MI->getOperand(3).getReg();
646 
647     maybeKillChain(MI->getOperand(1), Idx, ActiveChains);
648     maybeKillChain(MI->getOperand(2), Idx, ActiveChains);
649     if (DestReg != AccumReg)
650       maybeKillChain(MI->getOperand(0), Idx, ActiveChains);
651 
652     if (ActiveChains.find(AccumReg) != ActiveChains.end()) {
653       DEBUG(dbgs() << "Chain found for accumulator register "
654             << TRI->getName(AccumReg) << " in MI " << *MI);
655 
656       // For simplicity we only chain together sequences of MULs/MLAs where the
657       // accumulator register is killed on each instruction. This means we don't
658       // need to track other uses of the registers we want to rewrite.
659       //
660       // FIXME: We could extend to handle the non-kill cases for more coverage.
661       if (MI->getOperand(3).isKill()) {
662         // Add to chain.
663         DEBUG(dbgs() << "Instruction was successfully added to chain.\n");
664         ActiveChains[AccumReg]->add(MI, Idx, getColor(DestReg));
665         // Handle cases where the destination is not the same as the accumulator.
666         if (DestReg != AccumReg) {
667           ActiveChains[DestReg] = ActiveChains[AccumReg];
668           ActiveChains.erase(AccumReg);
669         }
670         return;
671       }
672 
673       DEBUG(dbgs() << "Cannot add to chain because accumulator operand wasn't "
674             << "marked <kill>!\n");
675       maybeKillChain(MI->getOperand(3), Idx, ActiveChains);
676     }
677 
678     DEBUG(dbgs() << "Creating new chain for dest register "
679           << TRI->getName(DestReg) << "\n");
680     auto G = llvm::make_unique<Chain>(MI, Idx, getColor(DestReg));
681     ActiveChains[DestReg] = G.get();
682     AllChains.push_back(std::move(G));
683 
684   } else {
685 
686     // Non-MUL or MLA instruction. Invalidate any chain in the uses or defs
687     // lists.
688     for (auto &I : MI->uses())
689       maybeKillChain(I, Idx, ActiveChains);
690     for (auto &I : MI->defs())
691       maybeKillChain(I, Idx, ActiveChains);
692 
693   }
694 }
695 
696 void AArch64A57FPLoadBalancing::
697 maybeKillChain(MachineOperand &MO, unsigned Idx,
698                std::map<unsigned, Chain*> &ActiveChains) {
699   // Given an operand and the set of active chains (keyed by register),
700   // determine if a chain should be ended and remove from ActiveChains.
701   MachineInstr *MI = MO.getParent();
702 
703   if (MO.isReg()) {
704 
705     // If this is a KILL of a current chain, record it.
706     if (MO.isKill() && ActiveChains.find(MO.getReg()) != ActiveChains.end()) {
707       DEBUG(dbgs() << "Kill seen for chain " << TRI->getName(MO.getReg())
708             << "\n");
709       ActiveChains[MO.getReg()]->setKill(MI, Idx, /*Immutable=*/MO.isTied());
710     }
711     ActiveChains.erase(MO.getReg());
712 
713   } else if (MO.isRegMask()) {
714 
715     for (auto I = ActiveChains.begin(), E = ActiveChains.end();
716          I != E;) {
717       if (MO.clobbersPhysReg(I->first)) {
718         DEBUG(dbgs() << "Kill (regmask) seen for chain "
719               << TRI->getName(I->first) << "\n");
720         I->second->setKill(MI, Idx, /*Immutable=*/true);
721         ActiveChains.erase(I++);
722       } else
723         ++I;
724     }
725 
726   }
727 }
728 
729 Color AArch64A57FPLoadBalancing::getColor(unsigned Reg) {
730   if ((TRI->getEncodingValue(Reg) % 2) == 0)
731     return Color::Even;
732   else
733     return Color::Odd;
734 }
735 
736 // Factory function used by AArch64TargetMachine to add the pass to the passmanager.
737 FunctionPass *llvm::createAArch64A57FPLoadBalancing() {
738   return new AArch64A57FPLoadBalancing();
739 }
740