/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/X86/X86InstrInfo.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- X86InstrInfo.h - X86 Instruction Information ------------*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file contains the X86 implementation of the TargetInstrInfo class. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef LLVM_LIB_TARGET_X86_X86INSTRINFO_H |
15 | | #define LLVM_LIB_TARGET_X86_X86INSTRINFO_H |
16 | | |
17 | | #include "MCTargetDesc/X86BaseInfo.h" |
18 | | #include "X86InstrFMA3Info.h" |
19 | | #include "X86RegisterInfo.h" |
20 | | #include "llvm/ADT/DenseMap.h" |
21 | | #include "llvm/Target/TargetInstrInfo.h" |
22 | | |
23 | | #define GET_INSTRINFO_HEADER |
24 | | #include "X86GenInstrInfo.inc" |
25 | | |
26 | | namespace llvm { |
27 | | class MachineInstrBuilder; |
28 | | class X86RegisterInfo; |
29 | | class X86Subtarget; |
30 | | |
31 | | namespace X86 { |
32 | | // X86 specific condition code. These correspond to X86_*_COND in |
33 | | // X86InstrInfo.td. They must be kept in synch. |
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, |
52 | | |
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, |
60 | | |
61 | | COND_INVALID |
62 | | }; |
63 | | |
64 | | // Turn condition code into conditional branch opcode. |
65 | | unsigned GetCondBranchFromCond(CondCode CC); |
66 | | |
67 | | /// \brief Return a pair of condition code for the given predicate and whether |
68 | | /// the instruction operands should be swaped to match the condition code. |
69 | | std::pair<CondCode, bool> getX86ConditionCode(CmpInst::Predicate Predicate); |
70 | | |
71 | | /// \brief Return a set opcode for the given condition and whether it has |
72 | | /// a memory operand. |
73 | | unsigned getSETFromCond(CondCode CC, bool HasMemoryOperand = false); |
74 | | |
75 | | /// \brief Return a cmov opcode for the given condition, register size in |
76 | | /// bytes, and operand type. |
77 | | unsigned getCMovFromCond(CondCode CC, unsigned RegBytes, |
78 | | bool HasMemoryOperand = false); |
79 | | |
80 | | // Turn CMov opcode into condition code. |
81 | | CondCode getCondFromCMovOpc(unsigned Opc); |
82 | | |
83 | | /// GetOppositeBranchCondition - Return the inverse of the specified cond, |
84 | | /// e.g. turning COND_E to COND_NE. |
85 | | CondCode GetOppositeBranchCondition(CondCode CC); |
86 | | } // namespace X86 |
87 | | |
88 | | /// isGlobalStubReference - Return true if the specified TargetFlag operand is |
89 | | /// a reference to a stub for a global, not the global itself. |
90 | 52.2k | inline static bool isGlobalStubReference(unsigned char TargetFlag) { |
91 | 52.2k | switch (TargetFlag) { |
92 | 13.1k | case X86II::MO_DLLIMPORT: // dllimport stub. |
93 | 13.1k | case X86II::MO_GOTPCREL: // rip-relative GOT reference. |
94 | 13.1k | case X86II::MO_GOT: // normal GOT reference. |
95 | 13.1k | case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Normal $non_lazy_ptr ref. |
96 | 13.1k | case X86II::MO_DARWIN_NONLAZY: // Normal $non_lazy_ptr ref. |
97 | 13.1k | return true; |
98 | 39.1k | default: |
99 | 39.1k | return false; |
100 | 52.2k | } |
101 | 52.2k | } Unexecuted instantiation: X86AsmPrinter.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86CallFrameOptimization.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86CallLowering.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86CmovConversion.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86ExpandPseudo.cpp:llvm::isGlobalStubReference(unsigned char) X86FastISel.cpp:llvm::isGlobalStubReference(unsigned char) Line | Count | Source | 90 | 409 | inline static bool isGlobalStubReference(unsigned char TargetFlag) { | 91 | 409 | switch (TargetFlag) { | 92 | 100 | case X86II::MO_DLLIMPORT: // dllimport stub. | 93 | 100 | case X86II::MO_GOTPCREL: // rip-relative GOT reference. | 94 | 100 | case X86II::MO_GOT: // normal GOT reference. | 95 | 100 | case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Normal $non_lazy_ptr ref. | 96 | 100 | case X86II::MO_DARWIN_NONLAZY: // Normal $non_lazy_ptr ref. | 97 | 100 | return true; | 98 | 309 | default: | 99 | 309 | return false; | 100 | 409 | } | 101 | 409 | } |
Unexecuted instantiation: X86FixupBWInsts.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86FixupLEAs.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86FixupSetCC.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86FloatingPoint.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86FrameLowering.cpp:llvm::isGlobalStubReference(unsigned char) X86InstructionSelector.cpp:llvm::isGlobalStubReference(unsigned char) Line | Count | Source | 90 | 25 | inline static bool isGlobalStubReference(unsigned char TargetFlag) { | 91 | 25 | switch (TargetFlag) { | 92 | 0 | case X86II::MO_DLLIMPORT: // dllimport stub. | 93 | 0 | case X86II::MO_GOTPCREL: // rip-relative GOT reference. | 94 | 0 | case X86II::MO_GOT: // normal GOT reference. | 95 | 0 | case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Normal $non_lazy_ptr ref. | 96 | 0 | case X86II::MO_DARWIN_NONLAZY: // Normal $non_lazy_ptr ref. | 97 | 0 | return true; | 98 | 25 | default: | 99 | 25 | return false; | 100 | 25 | } | 101 | 25 | } |
Unexecuted instantiation: X86ISelDAGToDAG.cpp:llvm::isGlobalStubReference(unsigned char) X86ISelLowering.cpp:llvm::isGlobalStubReference(unsigned char) Line | Count | Source | 90 | 51.7k | inline static bool isGlobalStubReference(unsigned char TargetFlag) { | 91 | 51.7k | switch (TargetFlag) { | 92 | 13.0k | case X86II::MO_DLLIMPORT: // dllimport stub. | 93 | 13.0k | case X86II::MO_GOTPCREL: // rip-relative GOT reference. | 94 | 13.0k | case X86II::MO_GOT: // normal GOT reference. | 95 | 13.0k | case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Normal $non_lazy_ptr ref. | 96 | 13.0k | case X86II::MO_DARWIN_NONLAZY: // Normal $non_lazy_ptr ref. | 97 | 13.0k | return true; | 98 | 38.7k | default: | 99 | 38.7k | return false; | 100 | 51.7k | } | 101 | 51.7k | } |
Unexecuted instantiation: X86InterleavedAccess.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86InstrFMA3Info.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86InstrInfo.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86EvexToVex.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86LegalizerInfo.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86MCInstLower.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86MacroFusion.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86OptimizeLEAs.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86PadShortFunction.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86RegisterBankInfo.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86RegisterInfo.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86SelectionDAGInfo.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86Subtarget.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86TargetMachine.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86TargetTransformInfo.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86VZeroUpper.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86WinAllocaExpander.cpp:llvm::isGlobalStubReference(unsigned char) Unexecuted instantiation: X86CallingConv.cpp:llvm::isGlobalStubReference(unsigned char) |
102 | | |
103 | | /// isGlobalRelativeToPICBase - Return true if the specified global value |
104 | | /// reference is relative to a 32-bit PIC base (X86ISD::GlobalBaseReg). If this |
105 | | /// is true, the addressing mode has the PIC base register added in (e.g. EBX). |
106 | 29.7k | inline static bool isGlobalRelativeToPICBase(unsigned char TargetFlag) { |
107 | 29.7k | switch (TargetFlag) { |
108 | 7.45k | case X86II::MO_GOTOFF: // isPICStyleGOT: local global. |
109 | 7.45k | case X86II::MO_GOT: // isPICStyleGOT: other global. |
110 | 7.45k | case X86II::MO_PIC_BASE_OFFSET: // Darwin local global. |
111 | 7.45k | case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Darwin/32 external global. |
112 | 7.45k | case X86II::MO_TLVP: // ??? Pretty sure.. |
113 | 7.45k | return true; |
114 | 22.3k | default: |
115 | 22.3k | return false; |
116 | 29.7k | } |
117 | 29.7k | } Unexecuted instantiation: X86CallingConv.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86WinAllocaExpander.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86VZeroUpper.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86TargetTransformInfo.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86TargetMachine.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86Subtarget.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86SelectionDAGInfo.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86RegisterInfo.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86RegisterBankInfo.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86PadShortFunction.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86OptimizeLEAs.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86MacroFusion.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86MCInstLower.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86LegalizerInfo.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86EvexToVex.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86InstrInfo.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86InstrFMA3Info.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86InterleavedAccess.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) X86ISelLowering.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Line | Count | Source | 106 | 29.3k | inline static bool isGlobalRelativeToPICBase(unsigned char TargetFlag) { | 107 | 29.3k | switch (TargetFlag) { | 108 | 7.44k | case X86II::MO_GOTOFF: // isPICStyleGOT: local global. | 109 | 7.44k | case X86II::MO_GOT: // isPICStyleGOT: other global. | 110 | 7.44k | case X86II::MO_PIC_BASE_OFFSET: // Darwin local global. | 111 | 7.44k | case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Darwin/32 external global. | 112 | 7.44k | case X86II::MO_TLVP: // ??? Pretty sure.. | 113 | 7.44k | return true; | 114 | 21.8k | default: | 115 | 21.8k | return false; | 116 | 29.3k | } | 117 | 29.3k | } |
Unexecuted instantiation: X86ISelDAGToDAG.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) X86InstructionSelector.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Line | Count | Source | 106 | 25 | inline static bool isGlobalRelativeToPICBase(unsigned char TargetFlag) { | 107 | 25 | switch (TargetFlag) { | 108 | 0 | case X86II::MO_GOTOFF: // isPICStyleGOT: local global. | 109 | 0 | case X86II::MO_GOT: // isPICStyleGOT: other global. | 110 | 0 | case X86II::MO_PIC_BASE_OFFSET: // Darwin local global. | 111 | 0 | case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Darwin/32 external global. | 112 | 0 | case X86II::MO_TLVP: // ??? Pretty sure.. | 113 | 0 | return true; | 114 | 25 | default: | 115 | 25 | return false; | 116 | 25 | } | 117 | 25 | } |
Unexecuted instantiation: X86FrameLowering.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86FloatingPoint.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86FixupSetCC.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86FixupLEAs.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86FixupBWInsts.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) X86FastISel.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Line | Count | Source | 106 | 409 | inline static bool isGlobalRelativeToPICBase(unsigned char TargetFlag) { | 107 | 409 | switch (TargetFlag) { | 108 | 15 | case X86II::MO_GOTOFF: // isPICStyleGOT: local global. | 109 | 15 | case X86II::MO_GOT: // isPICStyleGOT: other global. | 110 | 15 | case X86II::MO_PIC_BASE_OFFSET: // Darwin local global. | 111 | 15 | case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Darwin/32 external global. | 112 | 15 | case X86II::MO_TLVP: // ??? Pretty sure.. | 113 | 15 | return true; | 114 | 394 | default: | 115 | 394 | return false; | 116 | 409 | } | 117 | 409 | } |
Unexecuted instantiation: X86ExpandPseudo.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86CmovConversion.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86CallLowering.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86CallFrameOptimization.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) Unexecuted instantiation: X86AsmPrinter.cpp:llvm::isGlobalRelativeToPICBase(unsigned char) |
118 | | |
119 | 1.81k | inline static bool isScale(const MachineOperand &MO) { |
120 | 1.81k | return MO.isImm() && (MO.getImm() == 1 || 1.81k MO.getImm() == 20 || |
121 | 1.81k | MO.getImm() == 40 || MO.getImm() == 80 ); |
122 | 1.81k | } Unexecuted instantiation: X86AsmPrinter.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86CallFrameOptimization.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86CallLowering.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86CmovConversion.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86ExpandPseudo.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86FastISel.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86FixupBWInsts.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86FixupLEAs.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86FixupSetCC.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86FloatingPoint.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86FrameLowering.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86InstructionSelector.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86ISelDAGToDAG.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86ISelLowering.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86InterleavedAccess.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86InstrFMA3Info.cpp:llvm::isScale(llvm::MachineOperand const&) X86InstrInfo.cpp:llvm::isScale(llvm::MachineOperand const&) Line | Count | Source | 119 | 1.81k | inline static bool isScale(const MachineOperand &MO) { | 120 | 1.81k | return MO.isImm() && (MO.getImm() == 1 || 1.81k MO.getImm() == 20 || | 121 | 1.81k | MO.getImm() == 40 || MO.getImm() == 80 ); | 122 | 1.81k | } |
Unexecuted instantiation: X86EvexToVex.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86LegalizerInfo.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86MCInstLower.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86MacroFusion.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86OptimizeLEAs.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86PadShortFunction.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86RegisterBankInfo.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86RegisterInfo.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86SelectionDAGInfo.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86Subtarget.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86TargetMachine.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86TargetTransformInfo.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86VZeroUpper.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86WinAllocaExpander.cpp:llvm::isScale(llvm::MachineOperand const&) Unexecuted instantiation: X86CallingConv.cpp:llvm::isScale(llvm::MachineOperand const&) |
123 | | |
124 | 1.81k | inline static bool isLeaMem(const MachineInstr &MI, unsigned Op) { |
125 | 1.81k | if (MI.getOperand(Op).isFI()) |
126 | 0 | return true; |
127 | 1.81k | return Op + X86::AddrSegmentReg <= MI.getNumOperands() && |
128 | 1.81k | MI.getOperand(Op + X86::AddrBaseReg).isReg() && |
129 | 1.81k | isScale(MI.getOperand(Op + X86::AddrScaleAmt)) && |
130 | 1.81k | MI.getOperand(Op + X86::AddrIndexReg).isReg() && |
131 | 1.81k | (MI.getOperand(Op + X86::AddrDisp).isImm() || |
132 | 114 | MI.getOperand(Op + X86::AddrDisp).isGlobal() || |
133 | 114 | MI.getOperand(Op + X86::AddrDisp).isCPI() || |
134 | 0 | MI.getOperand(Op + X86::AddrDisp).isJTI()); |
135 | 1.81k | } Unexecuted instantiation: X86CallingConv.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86WinAllocaExpander.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86VZeroUpper.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86TargetTransformInfo.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86TargetMachine.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86Subtarget.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86SelectionDAGInfo.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86RegisterInfo.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86RegisterBankInfo.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86PadShortFunction.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86OptimizeLEAs.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86MacroFusion.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86MCInstLower.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86LegalizerInfo.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86EvexToVex.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) X86InstrInfo.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Line | Count | Source | 124 | 1.81k | inline static bool isLeaMem(const MachineInstr &MI, unsigned Op) { | 125 | 1.81k | if (MI.getOperand(Op).isFI()) | 126 | 0 | return true; | 127 | 1.81k | return Op + X86::AddrSegmentReg <= MI.getNumOperands() && | 128 | 1.81k | MI.getOperand(Op + X86::AddrBaseReg).isReg() && | 129 | 1.81k | isScale(MI.getOperand(Op + X86::AddrScaleAmt)) && | 130 | 1.81k | MI.getOperand(Op + X86::AddrIndexReg).isReg() && | 131 | 1.81k | (MI.getOperand(Op + X86::AddrDisp).isImm() || | 132 | 114 | MI.getOperand(Op + X86::AddrDisp).isGlobal() || | 133 | 114 | MI.getOperand(Op + X86::AddrDisp).isCPI() || | 134 | 0 | MI.getOperand(Op + X86::AddrDisp).isJTI()); | 135 | 1.81k | } |
Unexecuted instantiation: X86InstrFMA3Info.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86InterleavedAccess.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86ISelLowering.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86ISelDAGToDAG.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86InstructionSelector.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FrameLowering.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FloatingPoint.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FixupSetCC.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FixupLEAs.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FixupBWInsts.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FastISel.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86ExpandPseudo.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86CmovConversion.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86CallLowering.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86CallFrameOptimization.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86AsmPrinter.cpp:llvm::isLeaMem(llvm::MachineInstr const&, unsigned int) |
136 | | |
137 | 6.23k | inline static bool isMem(const MachineInstr &MI, unsigned Op) { |
138 | 6.23k | if (MI.getOperand(Op).isFI()) |
139 | 52 | return true; |
140 | 6.18k | return Op + X86::AddrNumOperands <= MI.getNumOperands() && |
141 | 6.18k | MI.getOperand(Op + X86::AddrSegmentReg).isReg()1.81k && isLeaMem(MI, Op)1.81k ; |
142 | 6.23k | } Unexecuted instantiation: X86AsmPrinter.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86CallFrameOptimization.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86CallLowering.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86CmovConversion.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86ExpandPseudo.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FastISel.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FixupBWInsts.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FixupLEAs.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FixupSetCC.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FloatingPoint.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86FrameLowering.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86InstructionSelector.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86ISelDAGToDAG.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86ISelLowering.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86InterleavedAccess.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86InstrFMA3Info.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) X86InstrInfo.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Line | Count | Source | 137 | 6.23k | inline static bool isMem(const MachineInstr &MI, unsigned Op) { | 138 | 6.23k | if (MI.getOperand(Op).isFI()) | 139 | 52 | return true; | 140 | 6.18k | return Op + X86::AddrNumOperands <= MI.getNumOperands() && | 141 | 6.18k | MI.getOperand(Op + X86::AddrSegmentReg).isReg()1.81k && isLeaMem(MI, Op)1.81k ; | 142 | 6.23k | } |
Unexecuted instantiation: X86EvexToVex.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86LegalizerInfo.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86MCInstLower.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86MacroFusion.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86OptimizeLEAs.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86PadShortFunction.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86RegisterBankInfo.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86RegisterInfo.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86SelectionDAGInfo.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86Subtarget.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86TargetMachine.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86TargetTransformInfo.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86VZeroUpper.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86WinAllocaExpander.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) Unexecuted instantiation: X86CallingConv.cpp:llvm::isMem(llvm::MachineInstr const&, unsigned int) |
143 | | |
144 | | class X86InstrInfo final : public X86GenInstrInfo { |
145 | | X86Subtarget &Subtarget; |
146 | | const X86RegisterInfo RI; |
147 | | |
148 | | /// RegOp2MemOpTable3Addr, RegOp2MemOpTable0, RegOp2MemOpTable1, |
149 | | /// RegOp2MemOpTable2, RegOp2MemOpTable3 - Load / store folding opcode maps. |
150 | | /// |
151 | | typedef DenseMap<unsigned, std::pair<uint16_t, uint16_t>> |
152 | | RegOp2MemOpTableType; |
153 | | RegOp2MemOpTableType RegOp2MemOpTable2Addr; |
154 | | RegOp2MemOpTableType RegOp2MemOpTable0; |
155 | | RegOp2MemOpTableType RegOp2MemOpTable1; |
156 | | RegOp2MemOpTableType RegOp2MemOpTable2; |
157 | | RegOp2MemOpTableType RegOp2MemOpTable3; |
158 | | RegOp2MemOpTableType RegOp2MemOpTable4; |
159 | | |
160 | | /// MemOp2RegOpTable - Load / store unfolding opcode map. |
161 | | /// |
162 | | typedef DenseMap<unsigned, std::pair<uint16_t, uint16_t>> |
163 | | MemOp2RegOpTableType; |
164 | | MemOp2RegOpTableType MemOp2RegOpTable; |
165 | | |
166 | | static void AddTableEntry(RegOp2MemOpTableType &R2MTable, |
167 | | MemOp2RegOpTableType &M2RTable, uint16_t RegOp, |
168 | | uint16_t MemOp, uint16_t Flags); |
169 | | |
170 | | virtual void anchor(); |
171 | | |
172 | | bool AnalyzeBranchImpl(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, |
173 | | MachineBasicBlock *&FBB, |
174 | | SmallVectorImpl<MachineOperand> &Cond, |
175 | | SmallVectorImpl<MachineInstr *> &CondBranches, |
176 | | bool AllowModify) const; |
177 | | |
178 | | public: |
179 | | explicit X86InstrInfo(X86Subtarget &STI); |
180 | | |
181 | | /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As |
182 | | /// such, whenever a client has an instance of instruction info, it should |
183 | | /// always be able to get register info as well (through this method). |
184 | | /// |
185 | 17.0M | const X86RegisterInfo &getRegisterInfo() const { return RI; } |
186 | | |
187 | | /// Returns the stack pointer adjustment that happens inside the frame |
188 | | /// setup..destroy sequence (e.g. by pushes, or inside the callee). |
189 | 38.4k | int64_t getFrameAdjustment(const MachineInstr &I) const { |
190 | 38.4k | assert(isFrameInstr(I)); |
191 | 38.4k | if (isFrameSetup(I)) |
192 | 8.28k | return I.getOperand(2).getImm(); |
193 | 30.1k | return I.getOperand(1).getImm(); |
194 | 38.4k | } |
195 | | |
196 | | /// Sets the stack pointer adjustment made inside the frame made up by this |
197 | | /// instruction. |
198 | 6.93k | void setFrameAdjustment(MachineInstr &I, int64_t V) const { |
199 | 6.93k | assert(isFrameInstr(I)); |
200 | 6.93k | if (isFrameSetup(I)) |
201 | 6.93k | I.getOperand(2).setImm(V); |
202 | 6.93k | else |
203 | 0 | I.getOperand(1).setImm(V); |
204 | 6.93k | } |
205 | | |
206 | | /// getSPAdjust - This returns the stack pointer adjustment made by |
207 | | /// this instruction. For x86, we need to handle more complex call |
208 | | /// sequences involving PUSHes. |
209 | | int getSPAdjust(const MachineInstr &MI) const override; |
210 | | |
211 | | /// isCoalescableExtInstr - Return true if the instruction is a "coalescable" |
212 | | /// extension instruction. That is, it's like a copy where it's legal for the |
213 | | /// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns |
214 | | /// true, then it's expected the pre-extension value is available as a subreg |
215 | | /// of the result register. This also returns the sub-register index in |
216 | | /// SubIdx. |
217 | | bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg, |
218 | | unsigned &DstReg, unsigned &SubIdx) const override; |
219 | | |
220 | | unsigned isLoadFromStackSlot(const MachineInstr &MI, |
221 | | int &FrameIndex) const override; |
222 | | /// isLoadFromStackSlotPostFE - Check for post-frame ptr elimination |
223 | | /// stack locations as well. This uses a heuristic so it isn't |
224 | | /// reliable for correctness. |
225 | | unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI, |
226 | | int &FrameIndex) const override; |
227 | | |
228 | | unsigned isStoreToStackSlot(const MachineInstr &MI, |
229 | | int &FrameIndex) const override; |
230 | | /// isStoreToStackSlotPostFE - Check for post-frame ptr elimination |
231 | | /// stack locations as well. This uses a heuristic so it isn't |
232 | | /// reliable for correctness. |
233 | | unsigned isStoreToStackSlotPostFE(const MachineInstr &MI, |
234 | | int &FrameIndex) const override; |
235 | | |
236 | | bool isReallyTriviallyReMaterializable(const MachineInstr &MI, |
237 | | AliasAnalysis *AA) const override; |
238 | | void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, |
239 | | unsigned DestReg, unsigned SubIdx, |
240 | | const MachineInstr &Orig, |
241 | | const TargetRegisterInfo &TRI) const override; |
242 | | |
243 | | /// Given an operand within a MachineInstr, insert preceding code to put it |
244 | | /// into the right format for a particular kind of LEA instruction. This may |
245 | | /// involve using an appropriate super-register instead (with an implicit use |
246 | | /// of the original) or creating a new virtual register and inserting COPY |
247 | | /// instructions to get the data into the right class. |
248 | | /// |
249 | | /// Reference parameters are set to indicate how caller should add this |
250 | | /// operand to the LEA instruction. |
251 | | bool classifyLEAReg(MachineInstr &MI, const MachineOperand &Src, |
252 | | unsigned LEAOpcode, bool AllowSP, unsigned &NewSrc, |
253 | | bool &isKill, bool &isUndef, MachineOperand &ImplicitOp, |
254 | | LiveVariables *LV) const; |
255 | | |
256 | | /// convertToThreeAddress - This method must be implemented by targets that |
257 | | /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target |
258 | | /// may be able to convert a two-address instruction into a true |
259 | | /// three-address instruction on demand. This allows the X86 target (for |
260 | | /// example) to convert ADD and SHL instructions into LEA instructions if they |
261 | | /// would require register copies due to two-addressness. |
262 | | /// |
263 | | /// This method returns a null pointer if the transformation cannot be |
264 | | /// performed, otherwise it returns the new instruction. |
265 | | /// |
266 | | MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI, |
267 | | MachineInstr &MI, |
268 | | LiveVariables *LV) const override; |
269 | | |
270 | | /// Returns true iff the routine could find two commutable operands in the |
271 | | /// given machine instruction. |
272 | | /// The 'SrcOpIdx1' and 'SrcOpIdx2' are INPUT and OUTPUT arguments. Their |
273 | | /// input values can be re-defined in this method only if the input values |
274 | | /// are not pre-defined, which is designated by the special value |
275 | | /// 'CommuteAnyOperandIndex' assigned to it. |
276 | | /// If both of indices are pre-defined and refer to some operands, then the |
277 | | /// method simply returns true if the corresponding operands are commutable |
278 | | /// and returns false otherwise. |
279 | | /// |
280 | | /// For example, calling this method this way: |
281 | | /// unsigned Op1 = 1, Op2 = CommuteAnyOperandIndex; |
282 | | /// findCommutedOpIndices(MI, Op1, Op2); |
283 | | /// can be interpreted as a query asking to find an operand that would be |
284 | | /// commutable with the operand#1. |
285 | | bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1, |
286 | | unsigned &SrcOpIdx2) const override; |
287 | | |
288 | | /// Returns true if the routine could find two commutable operands |
289 | | /// in the given FMA instruction \p MI. Otherwise, returns false. |
290 | | /// |
291 | | /// \p SrcOpIdx1 and \p SrcOpIdx2 are INPUT and OUTPUT arguments. |
292 | | /// The output indices of the commuted operands are returned in these |
293 | | /// arguments. Also, the input values of these arguments may be preset either |
294 | | /// to indices of operands that must be commuted or be equal to a special |
295 | | /// value 'CommuteAnyOperandIndex' which means that the corresponding |
296 | | /// operand index is not set and this method is free to pick any of |
297 | | /// available commutable operands. |
298 | | /// The parameter \p FMA3Group keeps the reference to the group of relative |
299 | | /// FMA3 opcodes including register/memory forms of 132/213/231 opcodes. |
300 | | /// |
301 | | /// For example, calling this method this way: |
302 | | /// unsigned Idx1 = 1, Idx2 = CommuteAnyOperandIndex; |
303 | | /// findFMA3CommutedOpIndices(MI, Idx1, Idx2, FMA3Group); |
304 | | /// can be interpreted as a query asking if the operand #1 can be swapped |
305 | | /// with any other available operand (e.g. operand #2, operand #3, etc.). |
306 | | /// |
307 | | /// The returned FMA opcode may differ from the opcode in the given MI. |
308 | | /// For example, commuting the operands #1 and #3 in the following FMA |
309 | | /// FMA213 #1, #2, #3 |
310 | | /// results into instruction with adjusted opcode: |
311 | | /// FMA231 #3, #2, #1 |
312 | | bool findFMA3CommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, |
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 |
332 | | getFMA3OpcodeToCommuteOperands(const MachineInstr &MI, unsigned SrcOpIdx1, |
333 | | unsigned SrcOpIdx2, |
334 | | const X86InstrFMA3Group &FMA3Group) const; |
335 | | |
336 | | // Branch analysis. |
337 | | bool isUnpredicatedTerminator(const MachineInstr &MI) const override; |
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 | | |
345 | | bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, |
346 | | MachineBasicBlock *&FBB, |
347 | | SmallVectorImpl<MachineOperand> &Cond, |
348 | | bool AllowModify) const override; |
349 | | |
350 | | bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg, |
351 | | int64_t &Offset, |
352 | | const TargetRegisterInfo *TRI) const override; |
353 | | bool analyzeBranchPredicate(MachineBasicBlock &MBB, |
354 | | TargetInstrInfo::MachineBranchPredicate &MBP, |
355 | | bool AllowModify = false) const override; |
356 | | |
357 | | unsigned removeBranch(MachineBasicBlock &MBB, |
358 | | int *BytesRemoved = nullptr) const override; |
359 | | unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, |
360 | | MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, |
361 | | const DebugLoc &DL, |
362 | | int *BytesAdded = nullptr) const override; |
363 | | bool canInsertSelect(const MachineBasicBlock &, ArrayRef<MachineOperand> Cond, |
364 | | unsigned, unsigned, int &, int &, int &) const override; |
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, |
371 | | bool KillSrc) const override; |
372 | | void storeRegToStackSlot(MachineBasicBlock &MBB, |
373 | | MachineBasicBlock::iterator MI, unsigned SrcReg, |
374 | | bool isKill, int FrameIndex, |
375 | | const TargetRegisterClass *RC, |
376 | | const TargetRegisterInfo *TRI) const override; |
377 | | |
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; |
384 | | |
385 | | void loadRegFromStackSlot(MachineBasicBlock &MBB, |
386 | | MachineBasicBlock::iterator MI, unsigned DestReg, |
387 | | int FrameIndex, const TargetRegisterClass *RC, |
388 | | const TargetRegisterInfo *TRI) const override; |
389 | | |
390 | | void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, |
391 | | SmallVectorImpl<MachineOperand> &Addr, |
392 | | const TargetRegisterClass *RC, |
393 | | MachineInstr::mmo_iterator MMOBegin, |
394 | | MachineInstr::mmo_iterator MMOEnd, |
395 | | SmallVectorImpl<MachineInstr *> &NewMIs) const; |
396 | | |
397 | | bool expandPostRAPseudo(MachineInstr &MI) const override; |
398 | | |
399 | | /// Check whether the target can fold a load that feeds a subreg operand |
400 | | /// (or a subreg operand that feeds a store). |
401 | 29.7k | bool isSubregFoldable() const override { return true; } |
402 | | |
403 | | /// foldMemoryOperand - If this target supports it, fold a load or store of |
404 | | /// the specified stack slot into the specified machine instruction for the |
405 | | /// specified operand(s). If this is possible, the target should perform the |
406 | | /// folding and return true, otherwise it should return false. If it folds |
407 | | /// the instruction, it is likely that the MachineInstruction the iterator |
408 | | /// references has been changed. |
409 | | MachineInstr * |
410 | | foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, |
411 | | ArrayRef<unsigned> Ops, |
412 | | MachineBasicBlock::iterator InsertPt, int FrameIndex, |
413 | | LiveIntervals *LIS = nullptr) const override; |
414 | | |
415 | | /// foldMemoryOperand - Same as the previous version except it allows folding |
416 | | /// of any load and store from / to any address, not just from a specific |
417 | | /// stack slot. |
418 | | MachineInstr *foldMemoryOperandImpl( |
419 | | MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops, |
420 | | MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI, |
421 | | LiveIntervals *LIS = nullptr) const override; |
422 | | |
423 | | /// unfoldMemoryOperand - Separate a single instruction which folded a load or |
424 | | /// a store or a load and a store into two or more instruction. If this is |
425 | | /// possible, returns true as well as the new instructions by reference. |
426 | | bool |
427 | | unfoldMemoryOperand(MachineFunction &MF, MachineInstr &MI, unsigned Reg, |
428 | | bool UnfoldLoad, bool UnfoldStore, |
429 | | SmallVectorImpl<MachineInstr *> &NewMIs) const override; |
430 | | |
431 | | bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, |
432 | | SmallVectorImpl<SDNode *> &NewNodes) const override; |
433 | | |
434 | | /// getOpcodeAfterMemoryUnfold - Returns the opcode of the would be new |
435 | | /// instruction after load / store are unfolded from an instruction of the |
436 | | /// specified opcode. It returns zero if the specified unfolding is not |
437 | | /// possible. If LoadRegIndex is non-null, it is filled in with the operand |
438 | | /// index of the operand which will hold the register holding the loaded |
439 | | /// value. |
440 | | unsigned |
441 | | getOpcodeAfterMemoryUnfold(unsigned Opc, bool UnfoldLoad, bool UnfoldStore, |
442 | | unsigned *LoadRegIndex = nullptr) const override; |
443 | | |
444 | | /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler |
445 | | /// to determine if two loads are loading from the same base address. It |
446 | | /// should only return true if the base pointers are the same and the |
447 | | /// only differences between the two addresses are the offset. It also returns |
448 | | /// the offsets by reference. |
449 | | bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1, |
450 | | int64_t &Offset2) const override; |
451 | | |
452 | | /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to |
453 | | /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads |
454 | | /// should be scheduled togther. On some targets if two loads are loading from |
455 | | /// addresses in the same cache line, it's better if they are scheduled |
456 | | /// together. This function takes two integers that represent the load offsets |
457 | | /// from the common base address. It returns true if it decides it's desirable |
458 | | /// to schedule the two loads together. "NumLoads" is the number of loads that |
459 | | /// have already been scheduled after Load1. |
460 | | bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, int64_t Offset1, |
461 | | int64_t Offset2, |
462 | | unsigned NumLoads) const override; |
463 | | |
464 | | void getNoop(MCInst &NopInst) const override; |
465 | | |
466 | | bool |
467 | | reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; |
468 | | |
469 | | /// isSafeToMoveRegClassDefs - Return true if it's safe to move a machine |
470 | | /// instruction that defines the specified register class. |
471 | | bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const override; |
472 | | |
473 | | /// isSafeToClobberEFLAGS - Return true if it's safe insert an instruction tha |
474 | | /// would clobber the EFLAGS condition register. Note the result may be |
475 | | /// conservative. If it cannot definitely determine the safety after visiting |
476 | | /// a few instructions in each direction it assumes it's not safe. |
477 | | bool isSafeToClobberEFLAGS(MachineBasicBlock &MBB, |
478 | | MachineBasicBlock::iterator I) const; |
479 | | |
480 | | /// True if MI has a condition code def, e.g. EFLAGS, that is |
481 | | /// not marked dead. |
482 | | bool hasLiveCondCodeDef(MachineInstr &MI) const; |
483 | | |
484 | | /// getGlobalBaseReg - Return a virtual register initialized with the |
485 | | /// the global base register value. Output instructions required to |
486 | | /// initialize the register in the function entry block, if necessary. |
487 | | /// |
488 | | unsigned getGlobalBaseReg(MachineFunction *MF) const; |
489 | | |
490 | | std::pair<uint16_t, uint16_t> |
491 | | getExecutionDomain(const MachineInstr &MI) const override; |
492 | | |
493 | | void setExecutionDomain(MachineInstr &MI, unsigned Domain) const override; |
494 | | |
495 | | unsigned |
496 | | getPartialRegUpdateClearance(const MachineInstr &MI, unsigned OpNum, |
497 | | const TargetRegisterInfo *TRI) const override; |
498 | | unsigned getUndefRegClearance(const MachineInstr &MI, unsigned &OpNum, |
499 | | const TargetRegisterInfo *TRI) const override; |
500 | | void breakPartialRegDependency(MachineInstr &MI, unsigned OpNum, |
501 | | const TargetRegisterInfo *TRI) const override; |
502 | | |
503 | | MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, |
504 | | unsigned OpNum, |
505 | | ArrayRef<MachineOperand> MOs, |
506 | | MachineBasicBlock::iterator InsertPt, |
507 | | unsigned Size, unsigned Alignment, |
508 | | bool AllowCommute) const; |
509 | | |
510 | | bool isHighLatencyDef(int opc) const override; |
511 | | |
512 | | bool hasHighOperandLatency(const TargetSchedModel &SchedModel, |
513 | | const MachineRegisterInfo *MRI, |
514 | | const MachineInstr &DefMI, unsigned DefIdx, |
515 | | const MachineInstr &UseMI, |
516 | | unsigned UseIdx) const override; |
517 | | |
518 | 70.9k | bool useMachineCombiner() const override { return true; } |
519 | | |
520 | | bool isAssociativeAndCommutative(const MachineInstr &Inst) const override; |
521 | | |
522 | | bool hasReassociableOperands(const MachineInstr &Inst, |
523 | | const MachineBasicBlock *MBB) const override; |
524 | | |
525 | | void setSpecialOperandAttr(MachineInstr &OldMI1, MachineInstr &OldMI2, |
526 | | MachineInstr &NewMI1, |
527 | | MachineInstr &NewMI2) const override; |
528 | | |
529 | | /// analyzeCompare - For a comparison instruction, return the source registers |
530 | | /// in SrcReg and SrcReg2 if having two register operands, and the value it |
531 | | /// compares against in CmpValue. Return true if the comparison instruction |
532 | | /// can be analyzed. |
533 | | bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, |
534 | | unsigned &SrcReg2, int &CmpMask, |
535 | | int &CmpValue) const override; |
536 | | |
537 | | /// optimizeCompareInstr - Check if there exists an earlier instruction that |
538 | | /// operates on the same source operands and sets flags in the same way as |
539 | | /// Compare; remove Compare if possible. |
540 | | bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, |
541 | | unsigned SrcReg2, int CmpMask, int CmpValue, |
542 | | const MachineRegisterInfo *MRI) const override; |
543 | | |
544 | | /// optimizeLoadInstr - Try to remove the load by folding it to a register |
545 | | /// operand at the use. We fold the load instructions if and only if the |
546 | | /// def and use are in the same BB. We only look at one load and see |
547 | | /// whether it can be folded into MI. FoldAsLoadDefReg is the virtual register |
548 | | /// defined by the load we are trying to fold. DefMI returns the machine |
549 | | /// instruction that defines FoldAsLoadDefReg, and the function returns |
550 | | /// the machine instruction generated due to folding. |
551 | | MachineInstr *optimizeLoadInstr(MachineInstr &MI, |
552 | | const MachineRegisterInfo *MRI, |
553 | | unsigned &FoldAsLoadDefReg, |
554 | | MachineInstr *&DefMI) const override; |
555 | | |
556 | | std::pair<unsigned, unsigned> |
557 | | decomposeMachineOperandsTargetFlags(unsigned TF) const override; |
558 | | |
559 | | ArrayRef<std::pair<unsigned, const char *>> |
560 | | getSerializableDirectMachineOperandTargetFlags() const override; |
561 | | |
562 | | virtual MachineOutlinerInfo getOutlininingCandidateInfo( |
563 | | std::vector< |
564 | | std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>> |
565 | | &RepeatedSequenceLocs) const override; |
566 | | |
567 | | bool isFunctionSafeToOutlineFrom(MachineFunction &MF) const override; |
568 | | |
569 | | llvm::X86GenInstrInfo::MachineOutlinerInstrType |
570 | | getOutliningType(MachineInstr &MI) const override; |
571 | | |
572 | | void insertOutlinerEpilogue(MachineBasicBlock &MBB, MachineFunction &MF, |
573 | | const MachineOutlinerInfo &MInfo) const override; |
574 | | |
575 | | void insertOutlinerPrologue(MachineBasicBlock &MBB, MachineFunction &MF, |
576 | | const MachineOutlinerInfo &MInfo) const override; |
577 | | |
578 | | MachineBasicBlock::iterator |
579 | | insertOutlinedCall(Module &M, MachineBasicBlock &MBB, |
580 | | MachineBasicBlock::iterator &It, MachineFunction &MF, |
581 | | const MachineOutlinerInfo &MInfo) const override; |
582 | | |
583 | | protected: |
584 | | /// Commutes the operands in the given instruction by changing the operands |
585 | | /// order and/or changing the instruction's opcode and/or the immediate value |
586 | | /// operand. |
587 | | /// |
588 | | /// The arguments 'CommuteOpIdx1' and 'CommuteOpIdx2' specify the operands |
589 | | /// to be commuted. |
590 | | /// |
591 | | /// Do not call this method for a non-commutable instruction or |
592 | | /// non-commutable operands. |
593 | | /// Even though the instruction is commutable, the method may still |
594 | | /// fail to commute the operands, null pointer is returned in such cases. |
595 | | MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, |
596 | | unsigned CommuteOpIdx1, |
597 | | unsigned CommuteOpIdx2) const override; |
598 | | |
599 | | private: |
600 | | MachineInstr *convertToThreeAddressWithLEA(unsigned MIOpc, |
601 | | MachineFunction::iterator &MFI, |
602 | | MachineInstr &MI, |
603 | | LiveVariables *LV) const; |
604 | | |
605 | | /// Handles memory folding for special case instructions, for instance those |
606 | | /// requiring custom manipulation of the address. |
607 | | MachineInstr *foldMemoryOperandCustom(MachineFunction &MF, MachineInstr &MI, |
608 | | unsigned OpNum, |
609 | | ArrayRef<MachineOperand> MOs, |
610 | | MachineBasicBlock::iterator InsertPt, |
611 | | unsigned Size, unsigned Align) const; |
612 | | |
613 | | /// isFrameOperand - Return true and the FrameIndex if the specified |
614 | | /// operand and follow operands form a reference to the stack frame. |
615 | | bool isFrameOperand(const MachineInstr &MI, unsigned int Op, |
616 | | int &FrameIndex) const; |
617 | | |
618 | | /// Returns true iff the routine could find two commutable operands in the |
619 | | /// given machine instruction with 3 vector inputs. |
620 | | /// The 'SrcOpIdx1' and 'SrcOpIdx2' are INPUT and OUTPUT arguments. Their |
621 | | /// input values can be re-defined in this method only if the input values |
622 | | /// are not pre-defined, which is designated by the special value |
623 | | /// 'CommuteAnyOperandIndex' assigned to it. |
624 | | /// If both of indices are pre-defined and refer to some operands, then the |
625 | | /// method simply returns true if the corresponding operands are commutable |
626 | | /// and returns false otherwise. |
627 | | /// |
628 | | /// For example, calling this method this way: |
629 | | /// unsigned Op1 = 1, Op2 = CommuteAnyOperandIndex; |
630 | | /// findThreeSrcCommutedOpIndices(MI, Op1, Op2); |
631 | | /// can be interpreted as a query asking to find an operand that would be |
632 | | /// commutable with the operand#1. |
633 | | bool findThreeSrcCommutedOpIndices(const MachineInstr &MI, |
634 | | unsigned &SrcOpIdx1, |
635 | | unsigned &SrcOpIdx2) const; |
636 | | }; |
637 | | |
638 | | } // namespace llvm |
639 | | |
640 | | #endif |