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
;
39 typedef DenseMap
<unsigned, const MachineInstr
*> RegMap
;
41 bool InsertMoves(MachineBasicBlock
&MBB
);
43 char NEONMoveFixPass::ID
= 0;
46 bool NEONMoveFixPass::InsertMoves(MachineBasicBlock
&MBB
) {
48 bool Modified
= false;
50 // Walk over MBB tracking the def points of the registers.
51 MachineBasicBlock::iterator MII
= MBB
.begin(), E
= MBB
.end();
52 MachineBasicBlock::iterator NextMII
;
53 for (; MII
!= E
; MII
= NextMII
) {
54 NextMII
= llvm::next(MII
);
55 MachineInstr
*MI
= &*MII
;
57 if (MI
->getOpcode() == ARM::VMOVD
&&
58 !TII
->isPredicated(MI
)) {
59 unsigned SrcReg
= MI
->getOperand(1).getReg();
60 // If we do not find an instruction defining the reg, this means the
61 // register should be live-in for this BB. It's always to better to use
62 // NEON reg-reg moves.
63 unsigned Domain
= ARMII::DomainNEON
;
64 RegMap::iterator DefMI
= Defs
.find(SrcReg
);
65 if (DefMI
!= Defs
.end()) {
66 Domain
= DefMI
->second
->getDesc().TSFlags
& ARMII::DomainMask
;
67 // Instructions in general domain are subreg accesses.
68 // Map them to NEON reg-reg moves.
69 if (Domain
== ARMII::DomainGeneral
)
70 Domain
= ARMII::DomainNEON
;
73 if (Domain
& ARMII::DomainNEON
) {
74 // Convert VMOVD to VMOVDneon
75 unsigned DestReg
= MI
->getOperand(0).getReg();
77 DEBUG({errs() << "vmov convert: "; MI
->dump();});
79 // It's safe to ignore imp-defs / imp-uses here, since:
80 // - We're running late, no intelligent condegen passes should be run
82 // - The imp-defs / imp-uses are superregs only, we don't care about
84 AddDefaultPred(BuildMI(MBB
, *MI
, MI
->getDebugLoc(),
85 TII
->get(ARM::VMOVDneon
), DestReg
).addReg(SrcReg
));
87 MachineBasicBlock::iterator I
= prior(NextMII
);
90 DEBUG({errs() << " into: "; MI
->dump();});
95 assert((Domain
& ARMII::DomainVFP
) && "Invalid domain!");
100 // Update def information.
101 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
102 const MachineOperand
& MO
= MI
->getOperand(i
);
103 if (!MO
.isReg() || !MO
.isDef())
105 unsigned MOReg
= MO
.getReg();
108 // Catch aliases as well.
109 for (const unsigned *R
= TRI
->getAliasSet(MOReg
); *R
; ++R
)
117 bool NEONMoveFixPass::runOnMachineFunction(MachineFunction
&Fn
) {
118 ARMFunctionInfo
*AFI
= Fn
.getInfo
<ARMFunctionInfo
>();
119 const TargetMachine
&TM
= Fn
.getTarget();
121 if (AFI
->isThumb1OnlyFunction())
124 TRI
= TM
.getRegisterInfo();
125 TII
= static_cast<const ARMBaseInstrInfo
*>(TM
.getInstrInfo());
127 bool Modified
= false;
128 for (MachineFunction::iterator MFI
= Fn
.begin(), E
= Fn
.end(); MFI
!= E
;
130 MachineBasicBlock
&MBB
= *MFI
;
131 Modified
|= InsertMoves(MBB
);
137 /// createNEONMoveFixPass - Returns an instance of the NEON reg-reg moves fix
139 FunctionPass
*llvm::createNEONMoveFixPass() {
140 return new NEONMoveFixPass();