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
;
40 typedef DenseMap
<unsigned, const MachineInstr
*> RegMap
;
42 bool InsertMoves(MachineBasicBlock
&MBB
);
44 char NEONMoveFixPass::ID
= 0;
47 static bool inNEONDomain(unsigned Domain
, bool isA8
) {
48 return (Domain
& ARMII::DomainNEON
) ||
49 (isA8
&& (Domain
& ARMII::DomainNEONA8
));
52 bool NEONMoveFixPass::InsertMoves(MachineBasicBlock
&MBB
) {
54 bool Modified
= false;
56 // Walk over MBB tracking the def points of the registers.
57 MachineBasicBlock::iterator MII
= MBB
.begin(), E
= MBB
.end();
58 MachineBasicBlock::iterator NextMII
;
59 for (; MII
!= E
; MII
= NextMII
) {
60 NextMII
= llvm::next(MII
);
61 MachineInstr
*MI
= &*MII
;
63 if (MI
->getOpcode() == ARM::VMOVD
&&
64 !TII
->isPredicated(MI
)) {
65 unsigned SrcReg
= MI
->getOperand(1).getReg();
66 // If we do not find an instruction defining the reg, this means the
67 // register should be live-in for this BB. It's always to better to use
68 // NEON reg-reg moves.
69 unsigned Domain
= ARMII::DomainNEON
;
70 RegMap::iterator DefMI
= Defs
.find(SrcReg
);
71 if (DefMI
!= Defs
.end()) {
72 Domain
= DefMI
->second
->getDesc().TSFlags
& ARMII::DomainMask
;
73 // Instructions in general domain are subreg accesses.
74 // Map them to NEON reg-reg moves.
75 if (Domain
== ARMII::DomainGeneral
)
76 Domain
= ARMII::DomainNEON
;
79 if (inNEONDomain(Domain
, isA8
)) {
80 // Convert VMOVD to VMOVDneon
81 unsigned DestReg
= MI
->getOperand(0).getReg();
83 DEBUG({errs() << "vmov convert: "; MI
->dump();});
85 // It's safe to ignore imp-defs / imp-uses here, since:
86 // - We're running late, no intelligent condegen passes should be run
88 // - The imp-defs / imp-uses are superregs only, we don't care about
90 AddDefaultPred(BuildMI(MBB
, *MI
, MI
->getDebugLoc(),
91 TII
->get(ARM::VMOVDneon
), DestReg
).addReg(SrcReg
));
93 MachineBasicBlock::iterator I
= prior(NextMII
);
96 DEBUG({errs() << " into: "; MI
->dump();});
101 assert((Domain
& ARMII::DomainVFP
) && "Invalid domain!");
106 // Update def information.
107 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
108 const MachineOperand
& MO
= MI
->getOperand(i
);
109 if (!MO
.isReg() || !MO
.isDef())
111 unsigned MOReg
= MO
.getReg();
114 // Catch aliases as well.
115 for (const unsigned *R
= TRI
->getAliasSet(MOReg
); *R
; ++R
)
123 bool NEONMoveFixPass::runOnMachineFunction(MachineFunction
&Fn
) {
124 ARMFunctionInfo
*AFI
= Fn
.getInfo
<ARMFunctionInfo
>();
125 const TargetMachine
&TM
= Fn
.getTarget();
127 if (AFI
->isThumb1OnlyFunction())
130 TRI
= TM
.getRegisterInfo();
131 TII
= static_cast<const ARMBaseInstrInfo
*>(TM
.getInstrInfo());
132 isA8
= TM
.getSubtarget
<ARMSubtarget
>().isCortexA8();
134 bool Modified
= false;
135 for (MachineFunction::iterator MFI
= Fn
.begin(), E
= Fn
.end(); MFI
!= E
;
137 MachineBasicBlock
&MBB
= *MFI
;
138 Modified
|= InsertMoves(MBB
);
144 /// createNEONMoveFixPass - Returns an instance of the NEON reg-reg moves fix
146 FunctionPass
*llvm::createNEONMoveFixPass() {
147 return new NEONMoveFixPass();