Jia Liu | b22310f | 2012-02-18 12:03:15 +0000 | [diff] [blame] | 1 | //===-- X86InstrInfo.h - X86 Instruction Information ------------*- C++ -*-===// |
Misha Brukman | c88330a | 2005-04-21 23:38:14 +0000 | [diff] [blame] | 2 | // |
John Criswell | 29265fe | 2003-10-21 15:17:13 +0000 | [diff] [blame] | 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
Chris Lattner | f3ebc3f | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
Misha Brukman | c88330a | 2005-04-21 23:38:14 +0000 | [diff] [blame] | 7 | // |
John Criswell | 29265fe | 2003-10-21 15:17:13 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 9 | // |
Chris Lattner | b4d58d7 | 2003-01-14 22:00:31 +0000 | [diff] [blame] | 10 | // This file contains the X86 implementation of the TargetInstrInfo class. |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Benjamin Kramer | a7c40ef | 2014-08-13 16:26:38 +0000 | [diff] [blame] | 14 | #ifndef LLVM_LIB_TARGET_X86_X86INSTRINFO_H |
| 15 | #define LLVM_LIB_TARGET_X86_X86INSTRINFO_H |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 16 | |
Craig Topper | c6d4efa | 2014-03-19 06:53:25 +0000 | [diff] [blame] | 17 | #include "MCTargetDesc/X86BaseInfo.h" |
Vyacheslav Klochkov | 6daefcf | 2016-08-11 22:07:33 +0000 | [diff] [blame] | 18 | #include "X86InstrFMA3Info.h" |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 19 | #include "X86RegisterInfo.h" |
Dan Gohman | 906152a | 2009-01-05 17:59:02 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/DenseMap.h" |
Craig Topper | b25fda9 | 2012-03-17 18:46:09 +0000 | [diff] [blame] | 21 | #include "llvm/Target/TargetInstrInfo.h" |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 22 | |
Evan Cheng | 703a0fb | 2011-07-01 17:57:27 +0000 | [diff] [blame] | 23 | #define GET_INSTRINFO_HEADER |
| 24 | #include "X86GenInstrInfo.inc" |
| 25 | |
Brian Gaeke | 960707c | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 26 | namespace llvm { |
Hans Wennborg | 4ae5119 | 2016-03-25 01:10:56 +0000 | [diff] [blame] | 27 | class MachineInstrBuilder; |
Evan Cheng | 11b0a5d | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 28 | class X86RegisterInfo; |
Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 29 | class X86Subtarget; |
Brian Gaeke | 960707c | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 30 | |
Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 31 | namespace X86 { |
| 32 | // X86 specific condition code. These correspond to X86_*_COND in |
| 33 | // X86InstrInfo.td. They must be kept in synch. |
Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 34 | enum CondCode { |
| 35 | COND_A = 0, |
| 36 | COND_AE = 1, |
| 37 | COND_B = 2, |
| 38 | COND_BE = 3, |
| 39 | COND_E = 4, |
| 40 | COND_G = 5, |
| 41 | COND_GE = 6, |
| 42 | COND_L = 7, |
| 43 | COND_LE = 8, |
| 44 | COND_NE = 9, |
| 45 | COND_NO = 10, |
| 46 | COND_NP = 11, |
| 47 | COND_NS = 12, |
| 48 | COND_O = 13, |
| 49 | COND_P = 14, |
| 50 | COND_S = 15, |
| 51 | LAST_VALID_COND = COND_S, |
Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 52 | |
Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 53 | // Artificial condition codes. These are used by AnalyzeBranch |
| 54 | // to indicate a block terminated with two conditional branches that together |
| 55 | // form a compound condition. They occur in code using FCMP_OEQ or FCMP_UNE, |
| 56 | // which can't be represented on x86 with a single condition. These |
| 57 | // are never used in MachineInstrs and are inverses of one another. |
| 58 | COND_NE_OR_P, |
| 59 | COND_E_AND_NP, |
Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 60 | |
Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 61 | COND_INVALID |
| 62 | }; |
Andrew Trick | 27c079e | 2011-03-05 06:31:54 +0000 | [diff] [blame] | 63 | |
Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 64 | // Turn condition code into conditional branch opcode. |
| 65 | unsigned GetCondBranchFromCond(CondCode CC); |
Andrew Trick | 27c079e | 2011-03-05 06:31:54 +0000 | [diff] [blame] | 66 | |
Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 67 | /// \brief Return a set opcode for the given condition and whether it has |
| 68 | /// a memory operand. |
| 69 | unsigned getSETFromCond(CondCode CC, bool HasMemoryOperand = false); |
Juergen Ributzka | 2da1bbc | 2014-06-16 23:58:24 +0000 | [diff] [blame] | 70 | |
Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 71 | /// \brief Return a cmov opcode for the given condition, register size in |
| 72 | /// bytes, and operand type. |
| 73 | unsigned getCMovFromCond(CondCode CC, unsigned RegBytes, |
| 74 | bool HasMemoryOperand = false); |
Juergen Ributzka | 6ef06f9 | 2014-06-23 21:55:36 +0000 | [diff] [blame] | 75 | |
Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 76 | // Turn CMov opcode into condition code. |
| 77 | CondCode getCondFromCMovOpc(unsigned Opc); |
Michael Liao | 3237662 | 2012-09-20 03:06:15 +0000 | [diff] [blame] | 78 | |
Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 79 | /// GetOppositeBranchCondition - Return the inverse of the specified cond, |
| 80 | /// e.g. turning COND_E to COND_NE. |
| 81 | CondCode GetOppositeBranchCondition(CondCode CC); |
Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 82 | } // end namespace X86; |
Chris Lattner | 3a897f3 | 2006-10-21 05:52:40 +0000 | [diff] [blame] | 83 | |
Chris Lattner | 377f1d5 | 2009-07-10 06:06:17 +0000 | [diff] [blame] | 84 | |
Chris Lattner | ca9d784 | 2009-07-10 06:29:59 +0000 | [diff] [blame] | 85 | /// isGlobalStubReference - Return true if the specified TargetFlag operand is |
Chris Lattner | 377f1d5 | 2009-07-10 06:06:17 +0000 | [diff] [blame] | 86 | /// a reference to a stub for a global, not the global itself. |
Chris Lattner | ca9d784 | 2009-07-10 06:29:59 +0000 | [diff] [blame] | 87 | inline static bool isGlobalStubReference(unsigned char TargetFlag) { |
| 88 | switch (TargetFlag) { |
Chris Lattner | 377f1d5 | 2009-07-10 06:06:17 +0000 | [diff] [blame] | 89 | case X86II::MO_DLLIMPORT: // dllimport stub. |
| 90 | case X86II::MO_GOTPCREL: // rip-relative GOT reference. |
| 91 | case X86II::MO_GOT: // normal GOT reference. |
| 92 | case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Normal $non_lazy_ptr ref. |
| 93 | case X86II::MO_DARWIN_NONLAZY: // Normal $non_lazy_ptr ref. |
Chris Lattner | 377f1d5 | 2009-07-10 06:06:17 +0000 | [diff] [blame] | 94 | return true; |
| 95 | default: |
| 96 | return false; |
| 97 | } |
| 98 | } |
Chris Lattner | d3f32c7 | 2009-07-10 07:33:30 +0000 | [diff] [blame] | 99 | |
| 100 | /// isGlobalRelativeToPICBase - Return true if the specified global value |
| 101 | /// reference is relative to a 32-bit PIC base (X86ISD::GlobalBaseReg). If this |
| 102 | /// is true, the addressing mode has the PIC base register added in (e.g. EBX). |
| 103 | inline static bool isGlobalRelativeToPICBase(unsigned char TargetFlag) { |
| 104 | switch (TargetFlag) { |
| 105 | case X86II::MO_GOTOFF: // isPICStyleGOT: local global. |
| 106 | case X86II::MO_GOT: // isPICStyleGOT: other global. |
| 107 | case X86II::MO_PIC_BASE_OFFSET: // Darwin local global. |
| 108 | case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Darwin/32 external global. |
Eric Christopher | b0e1a45 | 2010-06-03 04:07:48 +0000 | [diff] [blame] | 109 | case X86II::MO_TLVP: // ??? Pretty sure.. |
Chris Lattner | d3f32c7 | 2009-07-10 07:33:30 +0000 | [diff] [blame] | 110 | return true; |
| 111 | default: |
| 112 | return false; |
| 113 | } |
| 114 | } |
Andrew Trick | 27c079e | 2011-03-05 06:31:54 +0000 | [diff] [blame] | 115 | |
Anton Korobeynikov | 4e9dfe8 | 2008-06-28 11:07:54 +0000 | [diff] [blame] | 116 | inline static bool isScale(const MachineOperand &MO) { |
Dan Gohman | 0d1e9a8 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 117 | return MO.isImm() && |
Anton Korobeynikov | 4e9dfe8 | 2008-06-28 11:07:54 +0000 | [diff] [blame] | 118 | (MO.getImm() == 1 || MO.getImm() == 2 || |
| 119 | MO.getImm() == 4 || MO.getImm() == 8); |
| 120 | } |
| 121 | |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 122 | inline static bool isLeaMem(const MachineInstr &MI, unsigned Op) { |
| 123 | if (MI.getOperand(Op).isFI()) |
| 124 | return true; |
| 125 | return Op + X86::AddrSegmentReg <= MI.getNumOperands() && |
| 126 | MI.getOperand(Op + X86::AddrBaseReg).isReg() && |
| 127 | isScale(MI.getOperand(Op + X86::AddrScaleAmt)) && |
| 128 | MI.getOperand(Op + X86::AddrIndexReg).isReg() && |
| 129 | (MI.getOperand(Op + X86::AddrDisp).isImm() || |
| 130 | MI.getOperand(Op + X86::AddrDisp).isGlobal() || |
| 131 | MI.getOperand(Op + X86::AddrDisp).isCPI() || |
| 132 | MI.getOperand(Op + X86::AddrDisp).isJTI()); |
Anton Korobeynikov | 4e9dfe8 | 2008-06-28 11:07:54 +0000 | [diff] [blame] | 133 | } |
| 134 | |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 135 | inline static bool isMem(const MachineInstr &MI, unsigned Op) { |
| 136 | if (MI.getOperand(Op).isFI()) |
| 137 | return true; |
| 138 | return Op + X86::AddrNumOperands <= MI.getNumOperands() && |
| 139 | MI.getOperand(Op + X86::AddrSegmentReg).isReg() && isLeaMem(MI, Op); |
Rafael Espindola | 3b2df10 | 2009-04-08 21:14:34 +0000 | [diff] [blame] | 140 | } |
| 141 | |
Craig Topper | ec82847 | 2014-03-31 06:53:13 +0000 | [diff] [blame] | 142 | class X86InstrInfo final : public X86GenInstrInfo { |
Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 143 | X86Subtarget &Subtarget; |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 144 | const X86RegisterInfo RI; |
Andrew Trick | 27c079e | 2011-03-05 06:31:54 +0000 | [diff] [blame] | 145 | |
Craig Topper | 9eadcfd | 2012-06-01 05:34:01 +0000 | [diff] [blame] | 146 | /// RegOp2MemOpTable3Addr, RegOp2MemOpTable0, RegOp2MemOpTable1, |
| 147 | /// RegOp2MemOpTable2, RegOp2MemOpTable3 - Load / store folding opcode maps. |
Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 148 | /// |
Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 149 | typedef DenseMap<unsigned, |
Craig Topper | e012ede | 2016-04-30 17:59:49 +0000 | [diff] [blame] | 150 | std::pair<uint16_t, uint16_t> > RegOp2MemOpTableType; |
Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 151 | RegOp2MemOpTableType RegOp2MemOpTable2Addr; |
| 152 | RegOp2MemOpTableType RegOp2MemOpTable0; |
| 153 | RegOp2MemOpTableType RegOp2MemOpTable1; |
| 154 | RegOp2MemOpTableType RegOp2MemOpTable2; |
Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 155 | RegOp2MemOpTableType RegOp2MemOpTable3; |
Robert Khasanov | 79fb729 | 2014-12-18 12:28:22 +0000 | [diff] [blame] | 156 | RegOp2MemOpTableType RegOp2MemOpTable4; |
Andrew Trick | 27c079e | 2011-03-05 06:31:54 +0000 | [diff] [blame] | 157 | |
Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 158 | /// MemOp2RegOpTable - Load / store unfolding opcode map. |
| 159 | /// |
Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 160 | typedef DenseMap<unsigned, |
Craig Topper | e012ede | 2016-04-30 17:59:49 +0000 | [diff] [blame] | 161 | std::pair<uint16_t, uint16_t> > MemOp2RegOpTableType; |
Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 162 | MemOp2RegOpTableType MemOp2RegOpTable; |
| 163 | |
Craig Topper | d9c7d0d | 2012-06-23 04:58:41 +0000 | [diff] [blame] | 164 | static void AddTableEntry(RegOp2MemOpTableType &R2MTable, |
| 165 | MemOp2RegOpTableType &M2RTable, |
Craig Topper | e012ede | 2016-04-30 17:59:49 +0000 | [diff] [blame] | 166 | uint16_t RegOp, uint16_t MemOp, uint16_t Flags); |
Jakob Stoklund Olesen | 49e121d | 2010-03-25 17:25:00 +0000 | [diff] [blame] | 167 | |
Juergen Ributzka | d12ccbd | 2013-11-19 00:57:56 +0000 | [diff] [blame] | 168 | virtual void anchor(); |
| 169 | |
Sanjoy Das | 6b34a46 | 2015-06-15 18:44:21 +0000 | [diff] [blame] | 170 | bool AnalyzeBranchImpl(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, |
| 171 | MachineBasicBlock *&FBB, |
| 172 | SmallVectorImpl<MachineOperand> &Cond, |
| 173 | SmallVectorImpl<MachineInstr *> &CondBranches, |
| 174 | bool AllowModify) const; |
| 175 | |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 176 | public: |
Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 177 | explicit X86InstrInfo(X86Subtarget &STI); |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 178 | |
Chris Lattner | b4d58d7 | 2003-01-14 22:00:31 +0000 | [diff] [blame] | 179 | /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 180 | /// such, whenever a client has an instance of instruction info, it should |
| 181 | /// always be able to get register info as well (through this method). |
| 182 | /// |
Craig Topper | f5e3b0b | 2014-03-09 07:58:15 +0000 | [diff] [blame] | 183 | const X86RegisterInfo &getRegisterInfo() const { return RI; } |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 184 | |
Serge Pavlov | 49acf9c | 2017-04-13 14:10:52 +0000 | [diff] [blame] | 185 | /// Returns the stack pointer adjustment that happens inside the frame |
| 186 | /// setup..destroy sequence (e.g. by pushes, or inside the callee). |
| 187 | int64_t getFrameAdjustment(const MachineInstr &I) const { |
| 188 | assert(isFrameInstr(I)); |
Serge Pavlov | d526b13 | 2017-05-09 13:35:13 +0000 | [diff] [blame^] | 189 | if (isFrameSetup(I)) |
| 190 | return I.getOperand(2).getImm(); |
Serge Pavlov | 49acf9c | 2017-04-13 14:10:52 +0000 | [diff] [blame] | 191 | return I.getOperand(1).getImm(); |
| 192 | } |
| 193 | |
| 194 | /// Sets the stack pointer adjustment made inside the frame made up by this |
| 195 | /// instruction. |
| 196 | void setFrameAdjustment(MachineInstr &I, int64_t V) const { |
| 197 | assert(isFrameInstr(I)); |
Serge Pavlov | d526b13 | 2017-05-09 13:35:13 +0000 | [diff] [blame^] | 198 | if (isFrameSetup(I)) |
| 199 | I.getOperand(2).setImm(V); |
| 200 | else |
| 201 | I.getOperand(1).setImm(V); |
Serge Pavlov | 49acf9c | 2017-04-13 14:10:52 +0000 | [diff] [blame] | 202 | } |
| 203 | |
Michael Kuperstein | 13fbd45 | 2015-02-01 16:56:04 +0000 | [diff] [blame] | 204 | /// getSPAdjust - This returns the stack pointer adjustment made by |
| 205 | /// this instruction. For x86, we need to handle more complex call |
| 206 | /// sequences involving PUSHes. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 207 | int getSPAdjust(const MachineInstr &MI) const override; |
Michael Kuperstein | 13fbd45 | 2015-02-01 16:56:04 +0000 | [diff] [blame] | 208 | |
Evan Cheng | 30bebff | 2010-01-13 00:30:23 +0000 | [diff] [blame] | 209 | /// isCoalescableExtInstr - Return true if the instruction is a "coalescable" |
| 210 | /// extension instruction. That is, it's like a copy where it's legal for the |
| 211 | /// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns |
| 212 | /// true, then it's expected the pre-extension value is available as a subreg |
| 213 | /// of the result register. This also returns the sub-register index in |
| 214 | /// SubIdx. |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 215 | bool isCoalescableExtInstr(const MachineInstr &MI, |
| 216 | unsigned &SrcReg, unsigned &DstReg, |
| 217 | unsigned &SubIdx) const override; |
Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 218 | |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 219 | unsigned isLoadFromStackSlot(const MachineInstr &MI, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 220 | int &FrameIndex) const override; |
David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 221 | /// isLoadFromStackSlotPostFE - Check for post-frame ptr elimination |
| 222 | /// stack locations as well. This uses a heuristic so it isn't |
| 223 | /// reliable for correctness. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 224 | unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 225 | int &FrameIndex) const override; |
David Greene | 70fdd57 | 2009-11-12 20:55:29 +0000 | [diff] [blame] | 226 | |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 227 | unsigned isStoreToStackSlot(const MachineInstr &MI, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 228 | int &FrameIndex) const override; |
David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 229 | /// isStoreToStackSlotPostFE - Check for post-frame ptr elimination |
| 230 | /// stack locations as well. This uses a heuristic so it isn't |
| 231 | /// reliable for correctness. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 232 | unsigned isStoreToStackSlotPostFE(const MachineInstr &MI, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 233 | int &FrameIndex) const override; |
Evan Cheng | ed6e34f | 2008-03-31 20:40:39 +0000 | [diff] [blame] | 234 | |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 235 | bool isReallyTriviallyReMaterializable(const MachineInstr &MI, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 236 | AliasAnalysis *AA) const override; |
Evan Cheng | ed6e34f | 2008-03-31 20:40:39 +0000 | [diff] [blame] | 237 | void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, |
Evan Cheng | 8451744 | 2009-07-16 09:20:10 +0000 | [diff] [blame] | 238 | unsigned DestReg, unsigned SubIdx, |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 239 | const MachineInstr &Orig, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 240 | const TargetRegisterInfo &TRI) const override; |
Evan Cheng | ed6e34f | 2008-03-31 20:40:39 +0000 | [diff] [blame] | 241 | |
Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 242 | /// Given an operand within a MachineInstr, insert preceding code to put it |
| 243 | /// into the right format for a particular kind of LEA instruction. This may |
| 244 | /// involve using an appropriate super-register instead (with an implicit use |
| 245 | /// of the original) or creating a new virtual register and inserting COPY |
| 246 | /// instructions to get the data into the right class. |
| 247 | /// |
| 248 | /// Reference parameters are set to indicate how caller should add this |
| 249 | /// operand to the LEA instruction. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 250 | bool classifyLEAReg(MachineInstr &MI, const MachineOperand &Src, |
| 251 | unsigned LEAOpcode, bool AllowSP, unsigned &NewSrc, |
| 252 | bool &isKill, bool &isUndef, |
Matthias Braun | 7313ca6 | 2016-08-09 01:47:26 +0000 | [diff] [blame] | 253 | MachineOperand &ImplicitOp, LiveVariables *LV) const; |
Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 254 | |
Chris Lattner | b7782d7 | 2005-01-02 02:37:07 +0000 | [diff] [blame] | 255 | /// convertToThreeAddress - This method must be implemented by targets that |
| 256 | /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target |
| 257 | /// may be able to convert a two-address instruction into a true |
| 258 | /// three-address instruction on demand. This allows the X86 target (for |
| 259 | /// example) to convert ADD and SHL instructions into LEA instructions if they |
| 260 | /// would require register copies due to two-addressness. |
| 261 | /// |
| 262 | /// This method returns a null pointer if the transformation cannot be |
| 263 | /// performed, otherwise it returns the new instruction. |
| 264 | /// |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 265 | MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI, |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 266 | MachineInstr &MI, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 267 | LiveVariables *LV) const override; |
Chris Lattner | b7782d7 | 2005-01-02 02:37:07 +0000 | [diff] [blame] | 268 | |
Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 269 | /// Returns true iff the routine could find two commutable operands in the |
| 270 | /// given machine instruction. |
| 271 | /// The 'SrcOpIdx1' and 'SrcOpIdx2' are INPUT and OUTPUT arguments. Their |
| 272 | /// input values can be re-defined in this method only if the input values |
| 273 | /// are not pre-defined, which is designated by the special value |
| 274 | /// 'CommuteAnyOperandIndex' assigned to it. |
| 275 | /// If both of indices are pre-defined and refer to some operands, then the |
| 276 | /// method simply returns true if the corresponding operands are commutable |
| 277 | /// and returns false otherwise. |
Chris Lattner | 2947801 | 2005-01-19 07:11:01 +0000 | [diff] [blame] | 278 | /// |
Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 279 | /// For example, calling this method this way: |
| 280 | /// unsigned Op1 = 1, Op2 = CommuteAnyOperandIndex; |
| 281 | /// findCommutedOpIndices(MI, Op1, Op2); |
| 282 | /// can be interpreted as a query asking to find an operand that would be |
| 283 | /// commutable with the operand#1. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 284 | bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1, |
Lang Hames | c59a2d0 | 2014-04-02 23:57:49 +0000 | [diff] [blame] | 285 | unsigned &SrcOpIdx2) const override; |
| 286 | |
Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 287 | /// Returns true if the routine could find two commutable operands |
Vyacheslav Klochkov | 6daefcf | 2016-08-11 22:07:33 +0000 | [diff] [blame] | 288 | /// in the given FMA instruction \p MI. Otherwise, returns false. |
Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 289 | /// |
| 290 | /// \p SrcOpIdx1 and \p SrcOpIdx2 are INPUT and OUTPUT arguments. |
| 291 | /// The output indices of the commuted operands are returned in these |
| 292 | /// arguments. Also, the input values of these arguments may be preset either |
| 293 | /// to indices of operands that must be commuted or be equal to a special |
| 294 | /// value 'CommuteAnyOperandIndex' which means that the corresponding |
| 295 | /// operand index is not set and this method is free to pick any of |
| 296 | /// available commutable operands. |
Vyacheslav Klochkov | 6daefcf | 2016-08-11 22:07:33 +0000 | [diff] [blame] | 297 | /// The parameter \p FMA3Group keeps the reference to the group of relative |
| 298 | /// FMA3 opcodes including register/memory forms of 132/213/231 opcodes. |
Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 299 | /// |
| 300 | /// For example, calling this method this way: |
| 301 | /// unsigned Idx1 = 1, Idx2 = CommuteAnyOperandIndex; |
Vyacheslav Klochkov | 6daefcf | 2016-08-11 22:07:33 +0000 | [diff] [blame] | 302 | /// findFMA3CommutedOpIndices(MI, Idx1, Idx2, FMA3Group); |
Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 303 | /// can be interpreted as a query asking if the operand #1 can be swapped |
| 304 | /// with any other available operand (e.g. operand #2, operand #3, etc.). |
| 305 | /// |
| 306 | /// The returned FMA opcode may differ from the opcode in the given MI. |
| 307 | /// For example, commuting the operands #1 and #3 in the following FMA |
| 308 | /// FMA213 #1, #2, #3 |
| 309 | /// results into instruction with adjusted opcode: |
| 310 | /// FMA231 #3, #2, #1 |
Vyacheslav Klochkov | 6daefcf | 2016-08-11 22:07:33 +0000 | [diff] [blame] | 311 | bool findFMA3CommutedOpIndices(const MachineInstr &MI, |
Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 312 | unsigned &SrcOpIdx1, |
Vyacheslav Klochkov | 6daefcf | 2016-08-11 22:07:33 +0000 | [diff] [blame] | 313 | unsigned &SrcOpIdx2, |
| 314 | const X86InstrFMA3Group &FMA3Group) const; |
| 315 | |
| 316 | /// Returns an adjusted FMA opcode that must be used in FMA instruction that |
| 317 | /// performs the same computations as the given \p MI but which has the |
| 318 | /// operands \p SrcOpIdx1 and \p SrcOpIdx2 commuted. |
| 319 | /// It may return 0 if it is unsafe to commute the operands. |
| 320 | /// Note that a machine instruction (instead of its opcode) is passed as the |
| 321 | /// first parameter to make it possible to analyze the instruction's uses and |
| 322 | /// commute the first operand of FMA even when it seems unsafe when you look |
| 323 | /// at the opcode. For example, it is Ok to commute the first operand of |
| 324 | /// VFMADD*SD_Int, if ONLY the lowest 64-bit element of the result is used. |
| 325 | /// |
| 326 | /// The returned FMA opcode may differ from the opcode in the given \p MI. |
| 327 | /// For example, commuting the operands #1 and #3 in the following FMA |
| 328 | /// FMA213 #1, #2, #3 |
| 329 | /// results into instruction with adjusted opcode: |
| 330 | /// FMA231 #3, #2, #1 |
| 331 | unsigned getFMA3OpcodeToCommuteOperands(const MachineInstr &MI, |
| 332 | unsigned SrcOpIdx1, |
| 333 | unsigned SrcOpIdx2, |
| 334 | const X86InstrFMA3Group &FMA3Group) const; |
Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 335 | |
Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 336 | // Branch analysis. |
Duncan P. N. Exon Smith | 6307eb5 | 2016-02-23 02:46:52 +0000 | [diff] [blame] | 337 | bool isUnpredicatedTerminator(const MachineInstr &MI) const override; |
Hans Wennborg | a468601 | 2017-02-16 00:04:05 +0000 | [diff] [blame] | 338 | bool isUnconditionalTailCall(const MachineInstr &MI) const override; |
| 339 | bool canMakeTailCallConditional(SmallVectorImpl<MachineOperand> &Cond, |
| 340 | const MachineInstr &TailCall) const override; |
| 341 | void replaceBranchWithTailCall(MachineBasicBlock &MBB, |
| 342 | SmallVectorImpl<MachineOperand> &Cond, |
| 343 | const MachineInstr &TailCall) const override; |
| 344 | |
Jacques Pienaar | 71c30a1 | 2016-07-15 14:41:04 +0000 | [diff] [blame] | 345 | bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 346 | MachineBasicBlock *&FBB, |
| 347 | SmallVectorImpl<MachineOperand> &Cond, |
| 348 | bool AllowModify) const override; |
Sanjoy Das | b666ea3 | 2015-06-15 18:44:14 +0000 | [diff] [blame] | 349 | |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 350 | bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg, |
Chad Rosier | c27a18f | 2016-03-09 16:00:35 +0000 | [diff] [blame] | 351 | int64_t &Offset, |
Sanjoy Das | b666ea3 | 2015-06-15 18:44:14 +0000 | [diff] [blame] | 352 | const TargetRegisterInfo *TRI) const override; |
Jacques Pienaar | 71c30a1 | 2016-07-15 14:41:04 +0000 | [diff] [blame] | 353 | bool analyzeBranchPredicate(MachineBasicBlock &MBB, |
Sanjoy Das | 6b34a46 | 2015-06-15 18:44:21 +0000 | [diff] [blame] | 354 | TargetInstrInfo::MachineBranchPredicate &MBP, |
| 355 | bool AllowModify = false) const override; |
| 356 | |
Matt Arsenault | 1b9fc8e | 2016-09-14 20:43:16 +0000 | [diff] [blame] | 357 | unsigned removeBranch(MachineBasicBlock &MBB, |
Matt Arsenault | a2b036e | 2016-09-14 17:23:48 +0000 | [diff] [blame] | 358 | int *BytesRemoved = nullptr) const override; |
Matt Arsenault | e8e0f5c | 2016-09-14 17:24:15 +0000 | [diff] [blame] | 359 | unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, |
Ahmed Bougacha | c88bf54 | 2015-06-11 19:30:37 +0000 | [diff] [blame] | 360 | MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, |
Matt Arsenault | a2b036e | 2016-09-14 17:23:48 +0000 | [diff] [blame] | 361 | const DebugLoc &DL, |
| 362 | int *BytesAdded = nullptr) const override; |
Ahmed Bougacha | c88bf54 | 2015-06-11 19:30:37 +0000 | [diff] [blame] | 363 | bool canInsertSelect(const MachineBasicBlock&, ArrayRef<MachineOperand> Cond, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 364 | unsigned, unsigned, int&, int&, int&) const override; |
Benjamin Kramer | bdc4956 | 2016-06-12 15:39:02 +0000 | [diff] [blame] | 365 | void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, |
| 366 | const DebugLoc &DL, unsigned DstReg, |
| 367 | ArrayRef<MachineOperand> Cond, unsigned TrueReg, |
| 368 | unsigned FalseReg) const override; |
| 369 | void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, |
| 370 | const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 371 | bool KillSrc) const override; |
| 372 | void storeRegToStackSlot(MachineBasicBlock &MBB, |
| 373 | MachineBasicBlock::iterator MI, |
| 374 | unsigned SrcReg, bool isKill, int FrameIndex, |
| 375 | const TargetRegisterClass *RC, |
| 376 | const TargetRegisterInfo *TRI) const override; |
Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 377 | |
Craig Topper | f5e3b0b | 2014-03-09 07:58:15 +0000 | [diff] [blame] | 378 | void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, |
| 379 | SmallVectorImpl<MachineOperand> &Addr, |
| 380 | const TargetRegisterClass *RC, |
| 381 | MachineInstr::mmo_iterator MMOBegin, |
| 382 | MachineInstr::mmo_iterator MMOEnd, |
| 383 | SmallVectorImpl<MachineInstr*> &NewMIs) const; |
Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 384 | |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 385 | void loadRegFromStackSlot(MachineBasicBlock &MBB, |
| 386 | MachineBasicBlock::iterator MI, |
| 387 | unsigned DestReg, int FrameIndex, |
| 388 | const TargetRegisterClass *RC, |
| 389 | const TargetRegisterInfo *TRI) const override; |
Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 390 | |
Craig Topper | f5e3b0b | 2014-03-09 07:58:15 +0000 | [diff] [blame] | 391 | void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, |
| 392 | SmallVectorImpl<MachineOperand> &Addr, |
| 393 | const TargetRegisterClass *RC, |
| 394 | MachineInstr::mmo_iterator MMOBegin, |
| 395 | MachineInstr::mmo_iterator MMOEnd, |
| 396 | SmallVectorImpl<MachineInstr*> &NewMIs) const; |
Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 397 | |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 398 | bool expandPostRAPseudo(MachineInstr &MI) const override; |
Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 399 | |
Michael Kuperstein | 47eb85a | 2016-11-23 18:33:49 +0000 | [diff] [blame] | 400 | /// Check whether the target can fold a load that feeds a subreg operand |
| 401 | /// (or a subreg operand that feeds a store). |
| 402 | bool isSubregFoldable() const override { return true; } |
| 403 | |
Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 404 | /// foldMemoryOperand - If this target supports it, fold a load or store of |
| 405 | /// the specified stack slot into the specified machine instruction for the |
| 406 | /// specified operand(s). If this is possible, the target should perform the |
| 407 | /// folding and return true, otherwise it should return false. If it folds |
| 408 | /// the instruction, it is likely that the MachineInstruction the iterator |
| 409 | /// references has been changed. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 410 | MachineInstr * |
| 411 | foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, |
| 412 | ArrayRef<unsigned> Ops, |
| 413 | MachineBasicBlock::iterator InsertPt, int FrameIndex, |
| 414 | LiveIntervals *LIS = nullptr) const override; |
Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 415 | |
| 416 | /// foldMemoryOperand - Same as the previous version except it allows folding |
| 417 | /// of any load and store from / to any address, not just from a specific |
| 418 | /// stack slot. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 419 | MachineInstr *foldMemoryOperandImpl( |
| 420 | MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops, |
| 421 | MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI, |
| 422 | LiveIntervals *LIS = nullptr) const override; |
Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 423 | |
Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 424 | /// unfoldMemoryOperand - Separate a single instruction which folded a load or |
| 425 | /// a store or a load and a store into two or more instruction. If this is |
| 426 | /// possible, returns true as well as the new instructions by reference. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 427 | bool |
| 428 | unfoldMemoryOperand(MachineFunction &MF, MachineInstr &MI, unsigned Reg, |
| 429 | bool UnfoldLoad, bool UnfoldStore, |
| 430 | SmallVectorImpl<MachineInstr *> &NewMIs) const override; |
Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 431 | |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 432 | bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, |
| 433 | SmallVectorImpl<SDNode*> &NewNodes) const override; |
Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 434 | |
| 435 | /// getOpcodeAfterMemoryUnfold - Returns the opcode of the would be new |
| 436 | /// instruction after load / store are unfolded from an instruction of the |
| 437 | /// specified opcode. It returns zero if the specified unfolding is not |
Dan Gohman | 49fa51d | 2009-10-30 22:18:41 +0000 | [diff] [blame] | 438 | /// possible. If LoadRegIndex is non-null, it is filled in with the operand |
| 439 | /// index of the operand which will hold the register holding the loaded |
| 440 | /// value. |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 441 | unsigned getOpcodeAfterMemoryUnfold(unsigned Opc, |
| 442 | bool UnfoldLoad, bool UnfoldStore, |
Craig Topper | e73658d | 2014-04-28 04:05:08 +0000 | [diff] [blame] | 443 | unsigned *LoadRegIndex = nullptr) const override; |
Andrew Trick | 27c079e | 2011-03-05 06:31:54 +0000 | [diff] [blame] | 444 | |
Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 445 | /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler |
| 446 | /// to determine if two loads are loading from the same base address. It |
| 447 | /// should only return true if the base pointers are the same and the |
| 448 | /// only differences between the two addresses are the offset. It also returns |
| 449 | /// the offsets by reference. |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 450 | bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1, |
| 451 | int64_t &Offset2) const override; |
Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 452 | |
| 453 | /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to |
Chris Lattner | 0ab5e2c | 2011-04-15 05:18:47 +0000 | [diff] [blame] | 454 | /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads should |
Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 455 | /// be scheduled togther. On some targets if two loads are loading from |
| 456 | /// addresses in the same cache line, it's better if they are scheduled |
| 457 | /// together. This function takes two integers that represent the load offsets |
| 458 | /// from the common base address. It returns true if it decides it's desirable |
| 459 | /// to schedule the two loads together. "NumLoads" is the number of loads that |
| 460 | /// have already been scheduled after Load1. |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 461 | bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, |
| 462 | int64_t Offset1, int64_t Offset2, |
| 463 | unsigned NumLoads) const override; |
Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 464 | |
Hans Wennborg | 9b9a535 | 2017-04-21 21:48:41 +0000 | [diff] [blame] | 465 | void getNoop(MCInst &NopInst) const override; |
Chris Lattner | 6a5e706 | 2010-04-26 23:37:21 +0000 | [diff] [blame] | 466 | |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 467 | bool |
Matt Arsenault | 1b9fc8e | 2016-09-14 20:43:16 +0000 | [diff] [blame] | 468 | reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; |
Chris Lattner | 2947801 | 2005-01-19 07:11:01 +0000 | [diff] [blame] | 469 | |
Evan Cheng | b5f0ec3 | 2009-02-06 17:17:30 +0000 | [diff] [blame] | 470 | /// isSafeToMoveRegClassDefs - Return true if it's safe to move a machine |
| 471 | /// instruction that defines the specified register class. |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 472 | bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const override; |
Evan Cheng | f713722 | 2008-10-27 07:14:50 +0000 | [diff] [blame] | 473 | |
Alexey Volkov | 6226de6 | 2014-05-20 08:55:50 +0000 | [diff] [blame] | 474 | /// isSafeToClobberEFLAGS - Return true if it's safe insert an instruction tha |
| 475 | /// would clobber the EFLAGS condition register. Note the result may be |
| 476 | /// conservative. If it cannot definitely determine the safety after visiting |
| 477 | /// a few instructions in each direction it assumes it's not safe. |
| 478 | bool isSafeToClobberEFLAGS(MachineBasicBlock &MBB, |
| 479 | MachineBasicBlock::iterator I) const; |
| 480 | |
Andrew Kaylor | af083d4 | 2015-08-26 20:36:52 +0000 | [diff] [blame] | 481 | /// True if MI has a condition code def, e.g. EFLAGS, that is |
| 482 | /// not marked dead. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 483 | bool hasLiveCondCodeDef(MachineInstr &MI) const; |
Andrew Kaylor | af083d4 | 2015-08-26 20:36:52 +0000 | [diff] [blame] | 484 | |
Dan Gohman | 6ebe734 | 2008-09-30 00:58:23 +0000 | [diff] [blame] | 485 | /// getGlobalBaseReg - Return a virtual register initialized with the |
| 486 | /// the global base register value. Output instructions required to |
| 487 | /// initialize the register in the function entry block, if necessary. |
Dan Gohman | 2430073 | 2008-09-23 18:22:58 +0000 | [diff] [blame] | 488 | /// |
Dan Gohman | 6ebe734 | 2008-09-30 00:58:23 +0000 | [diff] [blame] | 489 | unsigned getGlobalBaseReg(MachineFunction *MF) const; |
Dan Gohman | 2430073 | 2008-09-23 18:22:58 +0000 | [diff] [blame] | 490 | |
Jakob Stoklund Olesen | b48c994 | 2011-09-27 22:57:18 +0000 | [diff] [blame] | 491 | std::pair<uint16_t, uint16_t> |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 492 | getExecutionDomain(const MachineInstr &MI) const override; |
Jakob Stoklund Olesen | b551aa4 | 2010-03-29 23:24:21 +0000 | [diff] [blame] | 493 | |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 494 | void setExecutionDomain(MachineInstr &MI, unsigned Domain) const override; |
Jakob Stoklund Olesen | 49e121d | 2010-03-25 17:25:00 +0000 | [diff] [blame] | 495 | |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 496 | unsigned |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 497 | getPartialRegUpdateClearance(const MachineInstr &MI, unsigned OpNum, |
| 498 | const TargetRegisterInfo *TRI) const override; |
| 499 | unsigned getUndefRegClearance(const MachineInstr &MI, unsigned &OpNum, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 500 | const TargetRegisterInfo *TRI) const override; |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 501 | void breakPartialRegDependency(MachineInstr &MI, unsigned OpNum, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 502 | const TargetRegisterInfo *TRI) const override; |
Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 503 | |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 504 | MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, |
Chris Lattner | eeba0c7 | 2010-09-05 02:18:34 +0000 | [diff] [blame] | 505 | unsigned OpNum, |
Benjamin Kramer | f1362f6 | 2015-02-28 12:04:00 +0000 | [diff] [blame] | 506 | ArrayRef<MachineOperand> MOs, |
Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 507 | MachineBasicBlock::iterator InsertPt, |
Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 508 | unsigned Size, unsigned Alignment, |
| 509 | bool AllowCommute) const; |
Evan Cheng | 63c7608 | 2010-10-19 18:58:51 +0000 | [diff] [blame] | 510 | |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 511 | bool isHighLatencyDef(int opc) const override; |
Andrew Trick | 641e2d4 | 2011-03-05 08:00:22 +0000 | [diff] [blame] | 512 | |
Matthias Braun | 88e2131 | 2015-06-13 03:42:11 +0000 | [diff] [blame] | 513 | bool hasHighOperandLatency(const TargetSchedModel &SchedModel, |
Evan Cheng | 63c7608 | 2010-10-19 18:58:51 +0000 | [diff] [blame] | 514 | const MachineRegisterInfo *MRI, |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 515 | const MachineInstr &DefMI, unsigned DefIdx, |
| 516 | const MachineInstr &UseMI, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 517 | unsigned UseIdx) const override; |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 518 | |
Sanjay Patel | 08829ba | 2015-06-10 20:32:21 +0000 | [diff] [blame] | 519 | bool useMachineCombiner() const override { |
| 520 | return true; |
| 521 | } |
Chad Rosier | 03a4730 | 2015-09-21 15:09:11 +0000 | [diff] [blame] | 522 | |
| 523 | bool isAssociativeAndCommutative(const MachineInstr &Inst) const override; |
| 524 | |
| 525 | bool hasReassociableOperands(const MachineInstr &Inst, |
| 526 | const MachineBasicBlock *MBB) const override; |
| 527 | |
| 528 | void setSpecialOperandAttr(MachineInstr &OldMI1, MachineInstr &OldMI2, |
| 529 | MachineInstr &NewMI1, |
| 530 | MachineInstr &NewMI2) const override; |
Sanjay Patel | 08829ba | 2015-06-10 20:32:21 +0000 | [diff] [blame] | 531 | |
Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 532 | /// analyzeCompare - For a comparison instruction, return the source registers |
| 533 | /// in SrcReg and SrcReg2 if having two register operands, and the value it |
| 534 | /// compares against in CmpValue. Return true if the comparison instruction |
| 535 | /// can be analyzed. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 536 | bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 537 | unsigned &SrcReg2, int &CmpMask, |
| 538 | int &CmpValue) const override; |
Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 539 | |
| 540 | /// optimizeCompareInstr - Check if there exists an earlier instruction that |
| 541 | /// operates on the same source operands and sets flags in the same way as |
| 542 | /// Compare; remove Compare if possible. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 543 | bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 544 | unsigned SrcReg2, int CmpMask, int CmpValue, |
| 545 | const MachineRegisterInfo *MRI) const override; |
Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 546 | |
Manman Ren | 5759d01 | 2012-08-02 00:56:42 +0000 | [diff] [blame] | 547 | /// optimizeLoadInstr - Try to remove the load by folding it to a register |
| 548 | /// operand at the use. We fold the load instructions if and only if the |
Manman Ren | ba8122c | 2012-08-02 19:37:32 +0000 | [diff] [blame] | 549 | /// def and use are in the same BB. We only look at one load and see |
| 550 | /// whether it can be folded into MI. FoldAsLoadDefReg is the virtual register |
| 551 | /// defined by the load we are trying to fold. DefMI returns the machine |
| 552 | /// instruction that defines FoldAsLoadDefReg, and the function returns |
| 553 | /// the machine instruction generated due to folding. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 554 | MachineInstr *optimizeLoadInstr(MachineInstr &MI, |
Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 555 | const MachineRegisterInfo *MRI, |
| 556 | unsigned &FoldAsLoadDefReg, |
| 557 | MachineInstr *&DefMI) const override; |
Manman Ren | 5759d01 | 2012-08-02 00:56:42 +0000 | [diff] [blame] | 558 | |
Alex Lorenz | 49873a8 | 2015-08-06 00:44:07 +0000 | [diff] [blame] | 559 | std::pair<unsigned, unsigned> |
| 560 | decomposeMachineOperandsTargetFlags(unsigned TF) const override; |
| 561 | |
| 562 | ArrayRef<std::pair<unsigned, const char *>> |
| 563 | getSerializableDirectMachineOperandTargetFlags() const override; |
| 564 | |
Jessica Paquette | 596f483 | 2017-03-06 21:31:18 +0000 | [diff] [blame] | 565 | unsigned getOutliningBenefit(size_t SequenceSize, |
Jessica Paquette | c984e21 | 2017-03-13 18:39:33 +0000 | [diff] [blame] | 566 | size_t Occurrences, |
| 567 | bool CanBeTailCall) const override; |
Jessica Paquette | 596f483 | 2017-03-06 21:31:18 +0000 | [diff] [blame] | 568 | |
| 569 | bool isFunctionSafeToOutlineFrom(MachineFunction &MF) const override; |
| 570 | |
| 571 | llvm::X86GenInstrInfo::MachineOutlinerInstrType |
| 572 | getOutliningType(MachineInstr &MI) const override; |
| 573 | |
| 574 | void insertOutlinerEpilogue(MachineBasicBlock &MBB, |
Jessica Paquette | c984e21 | 2017-03-13 18:39:33 +0000 | [diff] [blame] | 575 | MachineFunction &MF, |
| 576 | bool IsTailCall) const override; |
Jessica Paquette | 596f483 | 2017-03-06 21:31:18 +0000 | [diff] [blame] | 577 | |
| 578 | void insertOutlinerPrologue(MachineBasicBlock &MBB, |
Jessica Paquette | c984e21 | 2017-03-13 18:39:33 +0000 | [diff] [blame] | 579 | MachineFunction &MF, |
| 580 | bool isTailCall) const override; |
Jessica Paquette | 596f483 | 2017-03-06 21:31:18 +0000 | [diff] [blame] | 581 | |
| 582 | MachineBasicBlock::iterator |
| 583 | insertOutlinedCall(Module &M, MachineBasicBlock &MBB, |
| 584 | MachineBasicBlock::iterator &It, |
Jessica Paquette | c984e21 | 2017-03-13 18:39:33 +0000 | [diff] [blame] | 585 | MachineFunction &MF, |
| 586 | bool IsTailCall) const override; |
Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 587 | protected: |
| 588 | /// Commutes the operands in the given instruction by changing the operands |
| 589 | /// order and/or changing the instruction's opcode and/or the immediate value |
| 590 | /// operand. |
| 591 | /// |
| 592 | /// The arguments 'CommuteOpIdx1' and 'CommuteOpIdx2' specify the operands |
| 593 | /// to be commuted. |
| 594 | /// |
| 595 | /// Do not call this method for a non-commutable instruction or |
| 596 | /// non-commutable operands. |
| 597 | /// Even though the instruction is commutable, the method may still |
| 598 | /// fail to commute the operands, null pointer is returned in such cases. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 599 | MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, |
Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 600 | unsigned CommuteOpIdx1, |
| 601 | unsigned CommuteOpIdx2) const override; |
| 602 | |
Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 603 | private: |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 604 | MachineInstr *convertToThreeAddressWithLEA(unsigned MIOpc, |
| 605 | MachineFunction::iterator &MFI, |
| 606 | MachineInstr &MI, |
| 607 | LiveVariables *LV) const; |
Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 608 | |
Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 609 | /// Handles memory folding for special case instructions, for instance those |
| 610 | /// requiring custom manipulation of the address. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 611 | MachineInstr *foldMemoryOperandCustom(MachineFunction &MF, MachineInstr &MI, |
Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 612 | unsigned OpNum, |
| 613 | ArrayRef<MachineOperand> MOs, |
| 614 | MachineBasicBlock::iterator InsertPt, |
| 615 | unsigned Size, unsigned Align) const; |
| 616 | |
David Greene | 70fdd57 | 2009-11-12 20:55:29 +0000 | [diff] [blame] | 617 | /// isFrameOperand - Return true and the FrameIndex if the specified |
| 618 | /// operand and follow operands form a reference to the stack frame. |
Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 619 | bool isFrameOperand(const MachineInstr &MI, unsigned int Op, |
David Greene | 70fdd57 | 2009-11-12 20:55:29 +0000 | [diff] [blame] | 620 | int &FrameIndex) const; |
Craig Topper | 202b453 | 2016-09-22 03:00:50 +0000 | [diff] [blame] | 621 | |
| 622 | /// Returns true iff the routine could find two commutable operands in the |
| 623 | /// given machine instruction with 3 vector inputs. |
| 624 | /// The 'SrcOpIdx1' and 'SrcOpIdx2' are INPUT and OUTPUT arguments. Their |
| 625 | /// input values can be re-defined in this method only if the input values |
| 626 | /// are not pre-defined, which is designated by the special value |
| 627 | /// 'CommuteAnyOperandIndex' assigned to it. |
| 628 | /// If both of indices are pre-defined and refer to some operands, then the |
| 629 | /// method simply returns true if the corresponding operands are commutable |
| 630 | /// and returns false otherwise. |
| 631 | /// |
| 632 | /// For example, calling this method this way: |
| 633 | /// unsigned Op1 = 1, Op2 = CommuteAnyOperandIndex; |
| 634 | /// findThreeSrcCommutedOpIndices(MI, Op1, Op2); |
| 635 | /// can be interpreted as a query asking to find an operand that would be |
| 636 | /// commutable with the operand#1. |
| 637 | bool findThreeSrcCommutedOpIndices(const MachineInstr &MI, |
| 638 | unsigned &SrcOpIdx1, |
| 639 | unsigned &SrcOpIdx2) const; |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 640 | }; |
| 641 | |
Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 642 | } // End llvm namespace |
Brian Gaeke | 960707c | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 643 | |
Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 644 | #endif |