1 //===-- NEONMoveFix.cpp - Convert vfp reg-reg moves into neon ---*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #define DEBUG_TYPE "neon-mov-fix"
12 #include "ARMMachineFunctionInfo.h"
13 #include "ARMInstrInfo.h"
14 #include "llvm/CodeGen/MachineInstr.h"
15 #include "llvm/CodeGen/MachineInstrBuilder.h"
16 #include "llvm/CodeGen/MachineFunctionPass.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/raw_ostream.h"
22 STATISTIC(NumVMovs, "Number of reg-reg moves converted");
25 struct NEONMoveFixPass : public MachineFunctionPass {
27 NEONMoveFixPass() : MachineFunctionPass(&ID) {}
29 virtual bool runOnMachineFunction(MachineFunction &Fn);
31 virtual const char *getPassName() const {
32 return "NEON reg-reg move conversion";
36 const TargetRegisterInfo *TRI;
37 const ARMBaseInstrInfo *TII;
38 const ARMSubtarget *Subtarget;
40 typedef DenseMap<unsigned, const MachineInstr*> RegMap;
42 bool InsertMoves(MachineBasicBlock &MBB);
44 char NEONMoveFixPass::ID = 0;
47 bool NEONMoveFixPass::InsertMoves(MachineBasicBlock &MBB) {
49 bool Modified = false;
51 // Walk over MBB tracking the def points of the registers.
52 MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
53 MachineBasicBlock::iterator NextMII;
54 for (; MII != E; MII = NextMII) {
56 MachineInstr *MI = &*MII;
58 if (MI->getOpcode() == ARM::FCPYD &&
59 !TII->isPredicated(MI)) {
60 unsigned SrcReg = MI->getOperand(1).getReg();
61 // If we do not found an instruction defining the reg, this means the
62 // register should be live-in for this BB. It's always to better to use
63 // NEON reg-reg moves.
64 unsigned Domain = ARMII::DomainNEON;
65 RegMap::iterator DefMI = Defs.find(SrcReg);
66 if (DefMI != Defs.end()) {
67 Domain = DefMI->second->getDesc().TSFlags & ARMII::DomainMask;
68 // Instructions in general domain are subreg accesses.
69 // Map them to NEON reg-reg moves.
70 if (Domain == ARMII::DomainGeneral)
71 Domain = ARMII::DomainNEON;
74 if ((Domain & ARMII::DomainNEON) && Subtarget->hasNEON()) {
75 // Convert FCPYD to VMOVD.
76 unsigned DestReg = MI->getOperand(0).getReg();
78 DEBUG({errs() << "vmov convert: "; MI->dump();});
80 // It's safe to ignore imp-defs / imp-uses here, since:
81 // - We're running late, no intelligent condegen passes should be run
83 // - The imp-defs / imp-uses are superregs only, we don't care about
85 BuildMI(MBB, *MI, MI->getDebugLoc(),
86 TII->get(ARM::VMOVD), DestReg).addReg(SrcReg);
88 MachineBasicBlock::iterator I = prior(NextMII);
91 DEBUG({errs() << " into: "; MI->dump();});
96 assert((Domain & ARMII::DomainVFP ||
97 !Subtarget->hasNEON()) && "Invalid domain!");
102 // Update def information.
103 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
104 const MachineOperand& MO = MI->getOperand(i);
105 if (!MO.isReg() || !MO.isDef())
107 unsigned MOReg = MO.getReg();
110 // Catch subregs as well.
111 for (const unsigned *R = TRI->getSubRegisters(MOReg); *R; ++R)
119 bool NEONMoveFixPass::runOnMachineFunction(MachineFunction &Fn) {
120 ARMFunctionInfo *AFI = Fn.getInfo<ARMFunctionInfo>();
121 const TargetMachine &TM = Fn.getTarget();
123 if (AFI->isThumbFunction())
126 TRI = TM.getRegisterInfo();
127 Subtarget = &TM.getSubtarget<ARMSubtarget>();
128 TII = static_cast<const ARMBaseInstrInfo*>(TM.getInstrInfo());
130 bool Modified = false;
131 for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
133 MachineBasicBlock &MBB = *MFI;
134 Modified |= InsertMoves(MBB);
140 /// createNEONMoveFixPass - Returns an instance of the NEON reg-reg moves fix
142 FunctionPass *llvm::createNEONMoveFixPass() {
143 return new NEONMoveFixPass();