xref: /aosp_15_r20/external/llvm/lib/Target/X86/X86FixupBWInsts.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- X86FixupBWInsts.cpp - Fixup Byte or Word instructions -----------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker /// \file
10*9880d681SAndroid Build Coastguard Worker /// This file defines the pass that looks through the machine instructions
11*9880d681SAndroid Build Coastguard Worker /// late in the compilation, and finds byte or word instructions that
12*9880d681SAndroid Build Coastguard Worker /// can be profitably replaced with 32 bit instructions that give equivalent
13*9880d681SAndroid Build Coastguard Worker /// results for the bits of the results that are used. There are two possible
14*9880d681SAndroid Build Coastguard Worker /// reasons to do this.
15*9880d681SAndroid Build Coastguard Worker ///
16*9880d681SAndroid Build Coastguard Worker /// One reason is to avoid false-dependences on the upper portions
17*9880d681SAndroid Build Coastguard Worker /// of the registers.  Only instructions that have a destination register
18*9880d681SAndroid Build Coastguard Worker /// which is not in any of the source registers can be affected by this.
19*9880d681SAndroid Build Coastguard Worker /// Any instruction where one of the source registers is also the destination
20*9880d681SAndroid Build Coastguard Worker /// register is unaffected, because it has a true dependence on the source
21*9880d681SAndroid Build Coastguard Worker /// register already.  So, this consideration primarily affects load
22*9880d681SAndroid Build Coastguard Worker /// instructions and register-to-register moves.  It would
23*9880d681SAndroid Build Coastguard Worker /// seem like cmov(s) would also be affected, but because of the way cmov is
24*9880d681SAndroid Build Coastguard Worker /// really implemented by most machines as reading both the destination and
25*9880d681SAndroid Build Coastguard Worker /// and source regsters, and then "merging" the two based on a condition,
26*9880d681SAndroid Build Coastguard Worker /// it really already should be considered as having a true dependence on the
27*9880d681SAndroid Build Coastguard Worker /// destination register as well.
28*9880d681SAndroid Build Coastguard Worker ///
29*9880d681SAndroid Build Coastguard Worker /// The other reason to do this is for potential code size savings.  Word
30*9880d681SAndroid Build Coastguard Worker /// operations need an extra override byte compared to their 32 bit
31*9880d681SAndroid Build Coastguard Worker /// versions. So this can convert many word operations to their larger
32*9880d681SAndroid Build Coastguard Worker /// size, saving a byte in encoding. This could introduce partial register
33*9880d681SAndroid Build Coastguard Worker /// dependences where none existed however.  As an example take:
34*9880d681SAndroid Build Coastguard Worker ///   orw  ax, $0x1000
35*9880d681SAndroid Build Coastguard Worker ///   addw ax, $3
36*9880d681SAndroid Build Coastguard Worker /// now if this were to get transformed into
37*9880d681SAndroid Build Coastguard Worker ///   orw  ax, $1000
38*9880d681SAndroid Build Coastguard Worker ///   addl eax, $3
39*9880d681SAndroid Build Coastguard Worker /// because the addl encodes shorter than the addw, this would introduce
40*9880d681SAndroid Build Coastguard Worker /// a use of a register that was only partially written earlier.  On older
41*9880d681SAndroid Build Coastguard Worker /// Intel processors this can be quite a performance penalty, so this should
42*9880d681SAndroid Build Coastguard Worker /// probably only be done when it can be proven that a new partial dependence
43*9880d681SAndroid Build Coastguard Worker /// wouldn't be created, or when your know a newer processor is being
44*9880d681SAndroid Build Coastguard Worker /// targeted, or when optimizing for minimum code size.
45*9880d681SAndroid Build Coastguard Worker ///
46*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker #include "X86.h"
49*9880d681SAndroid Build Coastguard Worker #include "X86InstrInfo.h"
50*9880d681SAndroid Build Coastguard Worker #include "X86Subtarget.h"
51*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
52*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LivePhysRegs.h"
53*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
54*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
55*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineLoopInfo.h"
56*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
57*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
58*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
59*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
60*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
61*9880d681SAndroid Build Coastguard Worker using namespace llvm;
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker #define FIXUPBW_DESC "X86 Byte/Word Instruction Fixup"
64*9880d681SAndroid Build Coastguard Worker #define FIXUPBW_NAME "x86-fixup-bw-insts"
65*9880d681SAndroid Build Coastguard Worker 
66*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE FIXUPBW_NAME
67*9880d681SAndroid Build Coastguard Worker 
68*9880d681SAndroid Build Coastguard Worker // Option to allow this optimization pass to have fine-grained control.
69*9880d681SAndroid Build Coastguard Worker // This is turned off by default so as not to affect a large number of
70*9880d681SAndroid Build Coastguard Worker // existing lit tests.
71*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
72*9880d681SAndroid Build Coastguard Worker     FixupBWInsts("fixup-byte-word-insts",
73*9880d681SAndroid Build Coastguard Worker                  cl::desc("Change byte and word instructions to larger sizes"),
74*9880d681SAndroid Build Coastguard Worker                  cl::init(true), cl::Hidden);
75*9880d681SAndroid Build Coastguard Worker 
76*9880d681SAndroid Build Coastguard Worker namespace {
77*9880d681SAndroid Build Coastguard Worker class FixupBWInstPass : public MachineFunctionPass {
78*9880d681SAndroid Build Coastguard Worker   /// Loop over all of the instructions in the basic block replacing applicable
79*9880d681SAndroid Build Coastguard Worker   /// byte or word instructions with better alternatives.
80*9880d681SAndroid Build Coastguard Worker   void processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB);
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker   /// This sets the \p SuperDestReg to the 32 bit super reg of the original
83*9880d681SAndroid Build Coastguard Worker   /// destination register of the MachineInstr passed in. It returns true if
84*9880d681SAndroid Build Coastguard Worker   /// that super register is dead just prior to \p OrigMI, and false if not.
85*9880d681SAndroid Build Coastguard Worker   bool getSuperRegDestIfDead(MachineInstr *OrigMI,
86*9880d681SAndroid Build Coastguard Worker                              unsigned &SuperDestReg) const;
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker   /// Change the MachineInstr \p MI into the equivalent extending load to 32 bit
89*9880d681SAndroid Build Coastguard Worker   /// register if it is safe to do so.  Return the replacement instruction if
90*9880d681SAndroid Build Coastguard Worker   /// OK, otherwise return nullptr.
91*9880d681SAndroid Build Coastguard Worker   MachineInstr *tryReplaceLoad(unsigned New32BitOpcode, MachineInstr *MI) const;
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker   /// Change the MachineInstr \p MI into the equivalent 32-bit copy if it is
94*9880d681SAndroid Build Coastguard Worker   /// safe to do so.  Return the replacement instruction if OK, otherwise return
95*9880d681SAndroid Build Coastguard Worker   /// nullptr.
96*9880d681SAndroid Build Coastguard Worker   MachineInstr *tryReplaceCopy(MachineInstr *MI) const;
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker   // Change the MachineInstr \p MI into an eqivalent 32 bit instruction if
99*9880d681SAndroid Build Coastguard Worker   // possible.  Return the replacement instruction if OK, return nullptr
100*9880d681SAndroid Build Coastguard Worker   // otherwise. Set WasCandidate to true or false depending on whether the
101*9880d681SAndroid Build Coastguard Worker   // MI was a candidate for this sort of transformation.
102*9880d681SAndroid Build Coastguard Worker   MachineInstr *tryReplaceInstr(MachineInstr *MI, MachineBasicBlock &MBB,
103*9880d681SAndroid Build Coastguard Worker                                 bool &WasCandidate) const;
104*9880d681SAndroid Build Coastguard Worker public:
105*9880d681SAndroid Build Coastguard Worker   static char ID;
106*9880d681SAndroid Build Coastguard Worker 
getPassName() const107*9880d681SAndroid Build Coastguard Worker   const char *getPassName() const override {
108*9880d681SAndroid Build Coastguard Worker     return FIXUPBW_DESC;
109*9880d681SAndroid Build Coastguard Worker   }
110*9880d681SAndroid Build Coastguard Worker 
FixupBWInstPass()111*9880d681SAndroid Build Coastguard Worker   FixupBWInstPass() : MachineFunctionPass(ID) {
112*9880d681SAndroid Build Coastguard Worker     initializeFixupBWInstPassPass(*PassRegistry::getPassRegistry());
113*9880d681SAndroid Build Coastguard Worker   }
114*9880d681SAndroid Build Coastguard Worker 
getAnalysisUsage(AnalysisUsage & AU) const115*9880d681SAndroid Build Coastguard Worker   void getAnalysisUsage(AnalysisUsage &AU) const override {
116*9880d681SAndroid Build Coastguard Worker     AU.addRequired<MachineLoopInfo>(); // Machine loop info is used to
117*9880d681SAndroid Build Coastguard Worker                                        // guide some heuristics.
118*9880d681SAndroid Build Coastguard Worker     MachineFunctionPass::getAnalysisUsage(AU);
119*9880d681SAndroid Build Coastguard Worker   }
120*9880d681SAndroid Build Coastguard Worker 
121*9880d681SAndroid Build Coastguard Worker   /// Loop over all of the basic blocks, replacing byte and word instructions by
122*9880d681SAndroid Build Coastguard Worker   /// equivalent 32 bit instructions where performance or code size can be
123*9880d681SAndroid Build Coastguard Worker   /// improved.
124*9880d681SAndroid Build Coastguard Worker   bool runOnMachineFunction(MachineFunction &MF) override;
125*9880d681SAndroid Build Coastguard Worker 
getRequiredProperties() const126*9880d681SAndroid Build Coastguard Worker   MachineFunctionProperties getRequiredProperties() const override {
127*9880d681SAndroid Build Coastguard Worker     return MachineFunctionProperties().set(
128*9880d681SAndroid Build Coastguard Worker         MachineFunctionProperties::Property::AllVRegsAllocated);
129*9880d681SAndroid Build Coastguard Worker   }
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker private:
132*9880d681SAndroid Build Coastguard Worker   MachineFunction *MF;
133*9880d681SAndroid Build Coastguard Worker 
134*9880d681SAndroid Build Coastguard Worker   /// Machine instruction info used throughout the class.
135*9880d681SAndroid Build Coastguard Worker   const X86InstrInfo *TII;
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker   /// Local member for function's OptForSize attribute.
138*9880d681SAndroid Build Coastguard Worker   bool OptForSize;
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker   /// Machine loop info used for guiding some heruistics.
141*9880d681SAndroid Build Coastguard Worker   MachineLoopInfo *MLI;
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker   /// Register Liveness information after the current instruction.
144*9880d681SAndroid Build Coastguard Worker   LivePhysRegs LiveRegs;
145*9880d681SAndroid Build Coastguard Worker };
146*9880d681SAndroid Build Coastguard Worker char FixupBWInstPass::ID = 0;
147*9880d681SAndroid Build Coastguard Worker }
148*9880d681SAndroid Build Coastguard Worker 
INITIALIZE_PASS(FixupBWInstPass,FIXUPBW_NAME,FIXUPBW_DESC,false,false)149*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(FixupBWInstPass, FIXUPBW_NAME, FIXUPBW_DESC, false, false)
150*9880d681SAndroid Build Coastguard Worker 
151*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createX86FixupBWInsts() { return new FixupBWInstPass(); }
152*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & MF)153*9880d681SAndroid Build Coastguard Worker bool FixupBWInstPass::runOnMachineFunction(MachineFunction &MF) {
154*9880d681SAndroid Build Coastguard Worker   if (!FixupBWInsts || skipFunction(*MF.getFunction()))
155*9880d681SAndroid Build Coastguard Worker     return false;
156*9880d681SAndroid Build Coastguard Worker 
157*9880d681SAndroid Build Coastguard Worker   this->MF = &MF;
158*9880d681SAndroid Build Coastguard Worker   TII = MF.getSubtarget<X86Subtarget>().getInstrInfo();
159*9880d681SAndroid Build Coastguard Worker   OptForSize = MF.getFunction()->optForSize();
160*9880d681SAndroid Build Coastguard Worker   MLI = &getAnalysis<MachineLoopInfo>();
161*9880d681SAndroid Build Coastguard Worker   LiveRegs.init(&TII->getRegisterInfo());
162*9880d681SAndroid Build Coastguard Worker 
163*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Start X86FixupBWInsts\n";);
164*9880d681SAndroid Build Coastguard Worker 
165*9880d681SAndroid Build Coastguard Worker   // Process all basic blocks.
166*9880d681SAndroid Build Coastguard Worker   for (auto &MBB : MF)
167*9880d681SAndroid Build Coastguard Worker     processBasicBlock(MF, MBB);
168*9880d681SAndroid Build Coastguard Worker 
169*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "End X86FixupBWInsts\n";);
170*9880d681SAndroid Build Coastguard Worker 
171*9880d681SAndroid Build Coastguard Worker   return true;
172*9880d681SAndroid Build Coastguard Worker }
173*9880d681SAndroid Build Coastguard Worker 
174*9880d681SAndroid Build Coastguard Worker // TODO: This method of analysis can miss some legal cases, because the
175*9880d681SAndroid Build Coastguard Worker // super-register could be live into the address expression for a memory
176*9880d681SAndroid Build Coastguard Worker // reference for the instruction, and still be killed/last used by the
177*9880d681SAndroid Build Coastguard Worker // instruction. However, the existing query interfaces don't seem to
178*9880d681SAndroid Build Coastguard Worker // easily allow that to be checked.
179*9880d681SAndroid Build Coastguard Worker //
180*9880d681SAndroid Build Coastguard Worker // What we'd really like to know is whether after OrigMI, the
181*9880d681SAndroid Build Coastguard Worker // only portion of SuperDestReg that is alive is the portion that
182*9880d681SAndroid Build Coastguard Worker // was the destination register of OrigMI.
getSuperRegDestIfDead(MachineInstr * OrigMI,unsigned & SuperDestReg) const183*9880d681SAndroid Build Coastguard Worker bool FixupBWInstPass::getSuperRegDestIfDead(MachineInstr *OrigMI,
184*9880d681SAndroid Build Coastguard Worker                                             unsigned &SuperDestReg) const {
185*9880d681SAndroid Build Coastguard Worker   auto *TRI = &TII->getRegisterInfo();
186*9880d681SAndroid Build Coastguard Worker 
187*9880d681SAndroid Build Coastguard Worker   unsigned OrigDestReg = OrigMI->getOperand(0).getReg();
188*9880d681SAndroid Build Coastguard Worker   SuperDestReg = getX86SubSuperRegister(OrigDestReg, 32);
189*9880d681SAndroid Build Coastguard Worker 
190*9880d681SAndroid Build Coastguard Worker   const auto SubRegIdx = TRI->getSubRegIndex(SuperDestReg, OrigDestReg);
191*9880d681SAndroid Build Coastguard Worker 
192*9880d681SAndroid Build Coastguard Worker   // Make sure that the sub-register that this instruction has as its
193*9880d681SAndroid Build Coastguard Worker   // destination is the lowest order sub-register of the super-register.
194*9880d681SAndroid Build Coastguard Worker   // If it isn't, then the register isn't really dead even if the
195*9880d681SAndroid Build Coastguard Worker   // super-register is considered dead.
196*9880d681SAndroid Build Coastguard Worker   if (SubRegIdx == X86::sub_8bit_hi)
197*9880d681SAndroid Build Coastguard Worker     return false;
198*9880d681SAndroid Build Coastguard Worker 
199*9880d681SAndroid Build Coastguard Worker   if (LiveRegs.contains(SuperDestReg))
200*9880d681SAndroid Build Coastguard Worker     return false;
201*9880d681SAndroid Build Coastguard Worker 
202*9880d681SAndroid Build Coastguard Worker   if (SubRegIdx == X86::sub_8bit) {
203*9880d681SAndroid Build Coastguard Worker     // In the case of byte registers, we also have to check that the upper
204*9880d681SAndroid Build Coastguard Worker     // byte register is also dead. That is considered to be independent of
205*9880d681SAndroid Build Coastguard Worker     // whether the super-register is dead.
206*9880d681SAndroid Build Coastguard Worker     unsigned UpperByteReg =
207*9880d681SAndroid Build Coastguard Worker         getX86SubSuperRegister(SuperDestReg, 8, /*High=*/true);
208*9880d681SAndroid Build Coastguard Worker 
209*9880d681SAndroid Build Coastguard Worker     if (LiveRegs.contains(UpperByteReg))
210*9880d681SAndroid Build Coastguard Worker       return false;
211*9880d681SAndroid Build Coastguard Worker   }
212*9880d681SAndroid Build Coastguard Worker 
213*9880d681SAndroid Build Coastguard Worker   return true;
214*9880d681SAndroid Build Coastguard Worker }
215*9880d681SAndroid Build Coastguard Worker 
tryReplaceLoad(unsigned New32BitOpcode,MachineInstr * MI) const216*9880d681SAndroid Build Coastguard Worker MachineInstr *FixupBWInstPass::tryReplaceLoad(unsigned New32BitOpcode,
217*9880d681SAndroid Build Coastguard Worker                                               MachineInstr *MI) const {
218*9880d681SAndroid Build Coastguard Worker   unsigned NewDestReg;
219*9880d681SAndroid Build Coastguard Worker 
220*9880d681SAndroid Build Coastguard Worker   // We are going to try to rewrite this load to a larger zero-extending
221*9880d681SAndroid Build Coastguard Worker   // load.  This is safe if all portions of the 32 bit super-register
222*9880d681SAndroid Build Coastguard Worker   // of the original destination register, except for the original destination
223*9880d681SAndroid Build Coastguard Worker   // register are dead. getSuperRegDestIfDead checks that.
224*9880d681SAndroid Build Coastguard Worker   if (!getSuperRegDestIfDead(MI, NewDestReg))
225*9880d681SAndroid Build Coastguard Worker     return nullptr;
226*9880d681SAndroid Build Coastguard Worker 
227*9880d681SAndroid Build Coastguard Worker   // Safe to change the instruction.
228*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder MIB =
229*9880d681SAndroid Build Coastguard Worker       BuildMI(*MF, MI->getDebugLoc(), TII->get(New32BitOpcode), NewDestReg);
230*9880d681SAndroid Build Coastguard Worker 
231*9880d681SAndroid Build Coastguard Worker   unsigned NumArgs = MI->getNumOperands();
232*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 1; i < NumArgs; ++i)
233*9880d681SAndroid Build Coastguard Worker     MIB.addOperand(MI->getOperand(i));
234*9880d681SAndroid Build Coastguard Worker 
235*9880d681SAndroid Build Coastguard Worker   MIB->setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
236*9880d681SAndroid Build Coastguard Worker 
237*9880d681SAndroid Build Coastguard Worker   return MIB;
238*9880d681SAndroid Build Coastguard Worker }
239*9880d681SAndroid Build Coastguard Worker 
tryReplaceCopy(MachineInstr * MI) const240*9880d681SAndroid Build Coastguard Worker MachineInstr *FixupBWInstPass::tryReplaceCopy(MachineInstr *MI) const {
241*9880d681SAndroid Build Coastguard Worker   assert(MI->getNumExplicitOperands() == 2);
242*9880d681SAndroid Build Coastguard Worker   auto &OldDest = MI->getOperand(0);
243*9880d681SAndroid Build Coastguard Worker   auto &OldSrc = MI->getOperand(1);
244*9880d681SAndroid Build Coastguard Worker 
245*9880d681SAndroid Build Coastguard Worker   unsigned NewDestReg;
246*9880d681SAndroid Build Coastguard Worker   if (!getSuperRegDestIfDead(MI, NewDestReg))
247*9880d681SAndroid Build Coastguard Worker     return nullptr;
248*9880d681SAndroid Build Coastguard Worker 
249*9880d681SAndroid Build Coastguard Worker   unsigned NewSrcReg = getX86SubSuperRegister(OldSrc.getReg(), 32);
250*9880d681SAndroid Build Coastguard Worker 
251*9880d681SAndroid Build Coastguard Worker   // This is only correct if we access the same subregister index: otherwise,
252*9880d681SAndroid Build Coastguard Worker   // we could try to replace "movb %ah, %al" with "movl %eax, %eax".
253*9880d681SAndroid Build Coastguard Worker   auto *TRI = &TII->getRegisterInfo();
254*9880d681SAndroid Build Coastguard Worker   if (TRI->getSubRegIndex(NewSrcReg, OldSrc.getReg()) !=
255*9880d681SAndroid Build Coastguard Worker       TRI->getSubRegIndex(NewDestReg, OldDest.getReg()))
256*9880d681SAndroid Build Coastguard Worker     return nullptr;
257*9880d681SAndroid Build Coastguard Worker 
258*9880d681SAndroid Build Coastguard Worker   // Safe to change the instruction.
259*9880d681SAndroid Build Coastguard Worker   // Don't set src flags, as we don't know if we're also killing the superreg.
260*9880d681SAndroid Build Coastguard Worker   // However, the superregister might not be defined; make it explicit that
261*9880d681SAndroid Build Coastguard Worker   // we don't care about the higher bits by reading it as Undef, and adding
262*9880d681SAndroid Build Coastguard Worker   // an imp-use on the original subregister.
263*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder MIB =
264*9880d681SAndroid Build Coastguard Worker       BuildMI(*MF, MI->getDebugLoc(), TII->get(X86::MOV32rr), NewDestReg)
265*9880d681SAndroid Build Coastguard Worker           .addReg(NewSrcReg, RegState::Undef)
266*9880d681SAndroid Build Coastguard Worker           .addReg(OldSrc.getReg(), RegState::Implicit);
267*9880d681SAndroid Build Coastguard Worker 
268*9880d681SAndroid Build Coastguard Worker   // Drop imp-defs/uses that would be redundant with the new def/use.
269*9880d681SAndroid Build Coastguard Worker   for (auto &Op : MI->implicit_operands())
270*9880d681SAndroid Build Coastguard Worker     if (Op.getReg() != (Op.isDef() ? NewDestReg : NewSrcReg))
271*9880d681SAndroid Build Coastguard Worker       MIB.addOperand(Op);
272*9880d681SAndroid Build Coastguard Worker 
273*9880d681SAndroid Build Coastguard Worker   return MIB;
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker 
tryReplaceInstr(MachineInstr * MI,MachineBasicBlock & MBB,bool & WasCandidate) const276*9880d681SAndroid Build Coastguard Worker MachineInstr *FixupBWInstPass::tryReplaceInstr(
277*9880d681SAndroid Build Coastguard Worker                   MachineInstr *MI, MachineBasicBlock &MBB,
278*9880d681SAndroid Build Coastguard Worker                   bool &WasCandidate) const {
279*9880d681SAndroid Build Coastguard Worker   MachineInstr *NewMI = nullptr;
280*9880d681SAndroid Build Coastguard Worker   WasCandidate = false;
281*9880d681SAndroid Build Coastguard Worker 
282*9880d681SAndroid Build Coastguard Worker   // See if this is an instruction of the type we are currently looking for.
283*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
284*9880d681SAndroid Build Coastguard Worker 
285*9880d681SAndroid Build Coastguard Worker   case X86::MOV8rm:
286*9880d681SAndroid Build Coastguard Worker     // Only replace 8 bit loads with the zero extending versions if
287*9880d681SAndroid Build Coastguard Worker     // in an inner most loop and not optimizing for size. This takes
288*9880d681SAndroid Build Coastguard Worker     // an extra byte to encode, and provides limited performance upside.
289*9880d681SAndroid Build Coastguard Worker     if (MachineLoop *ML = MLI->getLoopFor(&MBB)) {
290*9880d681SAndroid Build Coastguard Worker       if (ML->begin() == ML->end() && !OptForSize) {
291*9880d681SAndroid Build Coastguard Worker         NewMI = tryReplaceLoad(X86::MOVZX32rm8, MI);
292*9880d681SAndroid Build Coastguard Worker         WasCandidate = true;
293*9880d681SAndroid Build Coastguard Worker       }
294*9880d681SAndroid Build Coastguard Worker     }
295*9880d681SAndroid Build Coastguard Worker     break;
296*9880d681SAndroid Build Coastguard Worker 
297*9880d681SAndroid Build Coastguard Worker   case X86::MOV16rm:
298*9880d681SAndroid Build Coastguard Worker     // Always try to replace 16 bit load with 32 bit zero extending.
299*9880d681SAndroid Build Coastguard Worker     // Code size is the same, and there is sometimes a perf advantage
300*9880d681SAndroid Build Coastguard Worker     // from eliminating a false dependence on the upper portion of
301*9880d681SAndroid Build Coastguard Worker     // the register.
302*9880d681SAndroid Build Coastguard Worker     NewMI = tryReplaceLoad(X86::MOVZX32rm16, MI);
303*9880d681SAndroid Build Coastguard Worker     WasCandidate = true;
304*9880d681SAndroid Build Coastguard Worker     break;
305*9880d681SAndroid Build Coastguard Worker 
306*9880d681SAndroid Build Coastguard Worker   case X86::MOV8rr:
307*9880d681SAndroid Build Coastguard Worker   case X86::MOV16rr:
308*9880d681SAndroid Build Coastguard Worker     // Always try to replace 8/16 bit copies with a 32 bit copy.
309*9880d681SAndroid Build Coastguard Worker     // Code size is either less (16) or equal (8), and there is sometimes a
310*9880d681SAndroid Build Coastguard Worker     // perf advantage from eliminating a false dependence on the upper portion
311*9880d681SAndroid Build Coastguard Worker     // of the register.
312*9880d681SAndroid Build Coastguard Worker     NewMI = tryReplaceCopy(MI);
313*9880d681SAndroid Build Coastguard Worker     WasCandidate = true;
314*9880d681SAndroid Build Coastguard Worker     break;
315*9880d681SAndroid Build Coastguard Worker 
316*9880d681SAndroid Build Coastguard Worker   default:
317*9880d681SAndroid Build Coastguard Worker     // nothing to do here.
318*9880d681SAndroid Build Coastguard Worker     break;
319*9880d681SAndroid Build Coastguard Worker   }
320*9880d681SAndroid Build Coastguard Worker 
321*9880d681SAndroid Build Coastguard Worker   return NewMI;
322*9880d681SAndroid Build Coastguard Worker }
323*9880d681SAndroid Build Coastguard Worker 
processBasicBlock(MachineFunction & MF,MachineBasicBlock & MBB)324*9880d681SAndroid Build Coastguard Worker void FixupBWInstPass::processBasicBlock(MachineFunction &MF,
325*9880d681SAndroid Build Coastguard Worker                                         MachineBasicBlock &MBB) {
326*9880d681SAndroid Build Coastguard Worker 
327*9880d681SAndroid Build Coastguard Worker   // This algorithm doesn't delete the instructions it is replacing
328*9880d681SAndroid Build Coastguard Worker   // right away.  By leaving the existing instructions in place, the
329*9880d681SAndroid Build Coastguard Worker   // register liveness information doesn't change, and this makes the
330*9880d681SAndroid Build Coastguard Worker   // analysis that goes on be better than if the replaced instructions
331*9880d681SAndroid Build Coastguard Worker   // were immediately removed.
332*9880d681SAndroid Build Coastguard Worker   //
333*9880d681SAndroid Build Coastguard Worker   // This algorithm always creates a replacement instruction
334*9880d681SAndroid Build Coastguard Worker   // and notes that and the original in a data structure, until the
335*9880d681SAndroid Build Coastguard Worker   // whole BB has been analyzed.  This keeps the replacement instructions
336*9880d681SAndroid Build Coastguard Worker   // from making it seem as if the larger register might be live.
337*9880d681SAndroid Build Coastguard Worker   SmallVector<std::pair<MachineInstr *, MachineInstr *>, 8> MIReplacements;
338*9880d681SAndroid Build Coastguard Worker 
339*9880d681SAndroid Build Coastguard Worker   // Start computing liveness for this block. We iterate from the end to be able
340*9880d681SAndroid Build Coastguard Worker   // to update this for each instruction.
341*9880d681SAndroid Build Coastguard Worker   LiveRegs.clear();
342*9880d681SAndroid Build Coastguard Worker   // We run after PEI, so we need to AddPristinesAndCSRs.
343*9880d681SAndroid Build Coastguard Worker   LiveRegs.addLiveOuts(MBB);
344*9880d681SAndroid Build Coastguard Worker 
345*9880d681SAndroid Build Coastguard Worker   bool WasCandidate = false;
346*9880d681SAndroid Build Coastguard Worker 
347*9880d681SAndroid Build Coastguard Worker   for (auto I = MBB.rbegin(); I != MBB.rend(); ++I) {
348*9880d681SAndroid Build Coastguard Worker     MachineInstr *MI = &*I;
349*9880d681SAndroid Build Coastguard Worker 
350*9880d681SAndroid Build Coastguard Worker     MachineInstr *NewMI = tryReplaceInstr(MI, MBB, WasCandidate);
351*9880d681SAndroid Build Coastguard Worker 
352*9880d681SAndroid Build Coastguard Worker     // Add this to replacements if it was a candidate, even if NewMI is
353*9880d681SAndroid Build Coastguard Worker     // nullptr.  We will revisit that in a bit.
354*9880d681SAndroid Build Coastguard Worker     if (WasCandidate) {
355*9880d681SAndroid Build Coastguard Worker       MIReplacements.push_back(std::make_pair(MI, NewMI));
356*9880d681SAndroid Build Coastguard Worker     }
357*9880d681SAndroid Build Coastguard Worker 
358*9880d681SAndroid Build Coastguard Worker     // We're done with this instruction, update liveness for the next one.
359*9880d681SAndroid Build Coastguard Worker     LiveRegs.stepBackward(*MI);
360*9880d681SAndroid Build Coastguard Worker   }
361*9880d681SAndroid Build Coastguard Worker 
362*9880d681SAndroid Build Coastguard Worker   while (!MIReplacements.empty()) {
363*9880d681SAndroid Build Coastguard Worker     MachineInstr *MI = MIReplacements.back().first;
364*9880d681SAndroid Build Coastguard Worker     MachineInstr *NewMI = MIReplacements.back().second;
365*9880d681SAndroid Build Coastguard Worker     MIReplacements.pop_back();
366*9880d681SAndroid Build Coastguard Worker     if (NewMI) {
367*9880d681SAndroid Build Coastguard Worker       MBB.insert(MI, NewMI);
368*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
369*9880d681SAndroid Build Coastguard Worker     }
370*9880d681SAndroid Build Coastguard Worker   }
371*9880d681SAndroid Build Coastguard Worker }
372