/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/X86/X86ExpandPseudo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===------- X86ExpandPseudo.cpp - Expand pseudo instructions -------------===// |
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 a pass that expands pseudo instructions into target |
11 | | // instructions to allow proper scheduling, if-conversion, other late |
12 | | // optimizations, or simply the encoding of the instructions. |
13 | | // |
14 | | //===----------------------------------------------------------------------===// |
15 | | |
16 | | #include "X86.h" |
17 | | #include "X86FrameLowering.h" |
18 | | #include "X86InstrBuilder.h" |
19 | | #include "X86InstrInfo.h" |
20 | | #include "X86MachineFunctionInfo.h" |
21 | | #include "X86Subtarget.h" |
22 | | #include "llvm/Analysis/EHPersonalities.h" |
23 | | #include "llvm/CodeGen/MachineFunctionPass.h" |
24 | | #include "llvm/CodeGen/MachineInstrBuilder.h" |
25 | | #include "llvm/CodeGen/Passes.h" // For IDs of passes that are preserved. |
26 | | #include "llvm/IR/GlobalValue.h" |
27 | | using namespace llvm; |
28 | | |
29 | | #define DEBUG_TYPE "x86-pseudo" |
30 | | |
31 | | namespace { |
32 | | class X86ExpandPseudo : public MachineFunctionPass { |
33 | | public: |
34 | | static char ID; |
35 | 8.54k | X86ExpandPseudo() : MachineFunctionPass(ID) {} |
36 | | |
37 | 8.52k | void getAnalysisUsage(AnalysisUsage &AU) const override { |
38 | 8.52k | AU.setPreservesCFG(); |
39 | 8.52k | AU.addPreservedID(MachineLoopInfoID); |
40 | 8.52k | AU.addPreservedID(MachineDominatorsID); |
41 | 8.52k | MachineFunctionPass::getAnalysisUsage(AU); |
42 | 8.52k | } |
43 | | |
44 | | const X86Subtarget *STI; |
45 | | const X86InstrInfo *TII; |
46 | | const X86RegisterInfo *TRI; |
47 | | const X86MachineFunctionInfo *X86FI; |
48 | | const X86FrameLowering *X86FL; |
49 | | |
50 | | bool runOnMachineFunction(MachineFunction &Fn) override; |
51 | | |
52 | 8.52k | MachineFunctionProperties getRequiredProperties() const override { |
53 | 8.52k | return MachineFunctionProperties().set( |
54 | 8.52k | MachineFunctionProperties::Property::NoVRegs); |
55 | 8.52k | } |
56 | | |
57 | 8.52k | StringRef getPassName() const override { |
58 | 8.52k | return "X86 pseudo instruction expansion pass"; |
59 | 8.52k | } |
60 | | |
61 | | private: |
62 | | bool ExpandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); |
63 | | bool ExpandMBB(MachineBasicBlock &MBB); |
64 | | }; |
65 | | char X86ExpandPseudo::ID = 0; |
66 | | } // End anonymous namespace. |
67 | | |
68 | | /// If \p MBBI is a pseudo instruction, this method expands |
69 | | /// it to the corresponding (sequence of) actual instruction(s). |
70 | | /// \returns true if \p MBBI has been expanded. |
71 | | bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB, |
72 | 889k | MachineBasicBlock::iterator MBBI) { |
73 | 889k | MachineInstr &MI = *MBBI; |
74 | 889k | unsigned Opcode = MI.getOpcode(); |
75 | 889k | DebugLoc DL = MBBI->getDebugLoc(); |
76 | 889k | switch (Opcode) { |
77 | 820k | default: |
78 | 820k | return false; |
79 | 1.88k | case X86::TCRETURNdi: |
80 | 1.88k | case X86::TCRETURNdicc: |
81 | 1.88k | case X86::TCRETURNri: |
82 | 1.88k | case X86::TCRETURNmi: |
83 | 1.88k | case X86::TCRETURNdi64: |
84 | 1.88k | case X86::TCRETURNdi64cc: |
85 | 1.88k | case X86::TCRETURNri64: |
86 | 1.88k | case X86::TCRETURNmi64: { |
87 | 1.88k | bool isMem = Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64; |
88 | 1.88k | MachineOperand &JumpTarget = MBBI->getOperand(0); |
89 | 1.88k | MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 545 : 11.84k ); |
90 | 1.88k | assert(StackAdjust.isImm() && "Expecting immediate value."); |
91 | 1.88k | |
92 | 1.88k | // Adjust stack pointer. |
93 | 1.88k | int StackAdj = StackAdjust.getImm(); |
94 | 1.88k | int MaxTCDelta = X86FI->getTCReturnAddrDelta(); |
95 | 1.88k | int Offset = 0; |
96 | 1.88k | assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive"); |
97 | 1.88k | |
98 | 1.88k | // Incoporate the retaddr area. |
99 | 1.88k | Offset = StackAdj - MaxTCDelta; |
100 | 1.88k | assert(Offset >= 0 && "Offset should never be negative"); |
101 | 1.88k | |
102 | 1.88k | if (Opcode == X86::TCRETURNdicc || 1.88k Opcode == X86::TCRETURNdi64cc1.88k ) { |
103 | 26 | assert(Offset == 0 && "Conditional tail call cannot adjust the stack."); |
104 | 26 | } |
105 | 1.88k | |
106 | 1.88k | if (Offset1.88k ) { |
107 | 1 | // Check for possible merge with preceding ADD instruction. |
108 | 1 | Offset += X86FL->mergeSPUpdates(MBB, MBBI, true); |
109 | 1 | X86FL->emitSPUpdate(MBB, MBBI, Offset, /*InEpilogue=*/true); |
110 | 1 | } |
111 | 1.88k | |
112 | 1.88k | // Jump to label or value in register. |
113 | 1.88k | bool IsWin64 = STI->isTargetWin64(); |
114 | 1.88k | if (Opcode == X86::TCRETURNdi || 1.88k Opcode == X86::TCRETURNdicc1.56k || |
115 | 1.88k | Opcode == X86::TCRETURNdi641.56k || Opcode == X86::TCRETURNdi64cc263 ) { |
116 | 1.65k | unsigned Op; |
117 | 1.65k | switch (Opcode) { |
118 | 326 | case X86::TCRETURNdi: |
119 | 326 | Op = X86::TAILJMPd; |
120 | 326 | break; |
121 | 2 | case X86::TCRETURNdicc: |
122 | 2 | Op = X86::TAILJMPd_CC; |
123 | 2 | break; |
124 | 24 | case X86::TCRETURNdi64cc: |
125 | 24 | assert(!MBB.getParent()->hasWinCFI() && |
126 | 24 | "Conditional tail calls confuse " |
127 | 24 | "the Win64 unwinder."); |
128 | 24 | Op = X86::TAILJMPd64_CC; |
129 | 24 | break; |
130 | 1.29k | default: |
131 | 1.29k | // Note: Win64 uses REX prefixes indirect jumps out of functions, but |
132 | 1.29k | // not direct ones. |
133 | 1.29k | Op = X86::TAILJMPd64; |
134 | 1.29k | break; |
135 | 1.65k | } |
136 | 1.65k | MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(Op)); |
137 | 1.65k | if (JumpTarget.isGlobal()1.65k ) { |
138 | 1.57k | MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(), |
139 | 1.57k | JumpTarget.getTargetFlags()); |
140 | 1.65k | } else { |
141 | 73 | assert(JumpTarget.isSymbol()); |
142 | 73 | MIB.addExternalSymbol(JumpTarget.getSymbolName(), |
143 | 73 | JumpTarget.getTargetFlags()); |
144 | 73 | } |
145 | 1.65k | if (Op == X86::TAILJMPd_CC || 1.65k Op == X86::TAILJMPd64_CC1.64k ) { |
146 | 26 | MIB.addImm(MBBI->getOperand(2).getImm()); |
147 | 26 | } |
148 | 1.65k | |
149 | 1.88k | } else if (239 Opcode == X86::TCRETURNmi || 239 Opcode == X86::TCRETURNmi64232 ) { |
150 | 45 | unsigned Op = (Opcode == X86::TCRETURNmi) |
151 | 7 | ? X86::TAILJMPm |
152 | 38 | : (IsWin64 ? 38 X86::TAILJMPm64_REX3 : X86::TAILJMPm6435 ); |
153 | 45 | MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(Op)); |
154 | 270 | for (unsigned i = 0; i != 5270 ; ++i225 ) |
155 | 225 | MIB.add(MBBI->getOperand(i)); |
156 | 239 | } else if (194 Opcode == X86::TCRETURNri64194 ) { |
157 | 115 | BuildMI(MBB, MBBI, DL, |
158 | 115 | TII->get(IsWin64 ? X86::TAILJMPr64_REX6 : X86::TAILJMPr64109 )) |
159 | 115 | .addReg(JumpTarget.getReg(), RegState::Kill); |
160 | 194 | } else { |
161 | 79 | BuildMI(MBB, MBBI, DL, TII->get(X86::TAILJMPr)) |
162 | 79 | .addReg(JumpTarget.getReg(), RegState::Kill); |
163 | 79 | } |
164 | 1.88k | |
165 | 1.88k | MachineInstr &NewMI = *std::prev(MBBI); |
166 | 1.88k | NewMI.copyImplicitOps(*MBBI->getParent()->getParent(), *MBBI); |
167 | 1.88k | |
168 | 1.88k | // Delete the pseudo instruction TCRETURN. |
169 | 1.88k | MBB.erase(MBBI); |
170 | 1.88k | |
171 | 1.88k | return true; |
172 | 1.88k | } |
173 | 6 | case X86::EH_RETURN: |
174 | 6 | case X86::EH_RETURN64: { |
175 | 6 | MachineOperand &DestAddr = MBBI->getOperand(0); |
176 | 6 | assert(DestAddr.isReg() && "Offset should be in register!"); |
177 | 6 | const bool Uses64BitFramePtr = |
178 | 2 | STI->isTarget64BitLP64() || STI->isTargetNaCl64(); |
179 | 6 | unsigned StackPtr = TRI->getStackRegister(); |
180 | 6 | BuildMI(MBB, MBBI, DL, |
181 | 6 | TII->get(Uses64BitFramePtr ? X86::MOV64rr4 : X86::MOV32rr2 ), StackPtr) |
182 | 6 | .addReg(DestAddr.getReg()); |
183 | 6 | // The EH_RETURN pseudo is really removed during the MC Lowering. |
184 | 6 | return true; |
185 | 6 | } |
186 | 25 | case X86::IRET: { |
187 | 25 | // Adjust stack to erase error code |
188 | 25 | int64_t StackAdj = MBBI->getOperand(0).getImm(); |
189 | 25 | X86FL->emitSPUpdate(MBB, MBBI, StackAdj, true); |
190 | 25 | // Replace pseudo with machine iret |
191 | 25 | BuildMI(MBB, MBBI, DL, |
192 | 25 | TII->get(STI->is64Bit() ? X86::IRET6414 : X86::IRET3211 )); |
193 | 25 | MBB.erase(MBBI); |
194 | 25 | return true; |
195 | 6 | } |
196 | 67.4k | case X86::RET: { |
197 | 67.4k | // Adjust stack to erase error code |
198 | 67.4k | int64_t StackAdj = MBBI->getOperand(0).getImm(); |
199 | 67.4k | MachineInstrBuilder MIB; |
200 | 67.4k | if (StackAdj == 067.4k ) { |
201 | 67.0k | MIB = BuildMI(MBB, MBBI, DL, |
202 | 67.0k | TII->get(STI->is64Bit() ? X86::RETQ54.9k : X86::RETL12.1k )); |
203 | 67.4k | } else if (385 isUInt<16>(StackAdj)385 ) { |
204 | 381 | MIB = BuildMI(MBB, MBBI, DL, |
205 | 381 | TII->get(STI->is64Bit() ? X86::RETIQ1 : X86::RETIL380 )) |
206 | 381 | .addImm(StackAdj); |
207 | 385 | } else { |
208 | 4 | assert(!STI->is64Bit() && |
209 | 4 | "shouldn't need to do this for x86_64 targets!"); |
210 | 4 | // A ret can only handle immediates as big as 2**16-1. If we need to pop |
211 | 4 | // off bytes before the return address, we must do it manually. |
212 | 4 | BuildMI(MBB, MBBI, DL, TII->get(X86::POP32r)).addReg(X86::ECX, RegState::Define); |
213 | 4 | X86FL->emitSPUpdate(MBB, MBBI, StackAdj, /*InEpilogue=*/true); |
214 | 4 | BuildMI(MBB, MBBI, DL, TII->get(X86::PUSH32r)).addReg(X86::ECX); |
215 | 4 | MIB = BuildMI(MBB, MBBI, DL, TII->get(X86::RETL)); |
216 | 4 | } |
217 | 127k | for (unsigned I = 1, E = MBBI->getNumOperands(); I != E127k ; ++I60.2k ) |
218 | 60.2k | MIB.add(MBBI->getOperand(I)); |
219 | 67.4k | MBB.erase(MBBI); |
220 | 67.4k | return true; |
221 | 6 | } |
222 | 34 | case X86::EH_RESTORE: { |
223 | 34 | // Restore ESP and EBP, and optionally ESI if required. |
224 | 34 | bool IsSEH = isAsynchronousEHPersonality(classifyEHPersonality( |
225 | 34 | MBB.getParent()->getFunction()->getPersonalityFn())); |
226 | 34 | X86FL->restoreWin32EHStackPointers(MBB, MBBI, DL, /*RestoreSP=*/IsSEH); |
227 | 34 | MBBI->eraseFromParent(); |
228 | 34 | return true; |
229 | 6 | } |
230 | 2 | case X86::LCMPXCHG8B_SAVE_EBX: |
231 | 2 | case X86::LCMPXCHG16B_SAVE_RBX: { |
232 | 2 | // Perform the following transformation. |
233 | 2 | // SaveRbx = pseudocmpxchg Addr, <4 opds for the address>, InArg, SaveRbx |
234 | 2 | // => |
235 | 2 | // [E|R]BX = InArg |
236 | 2 | // actualcmpxchg Addr |
237 | 2 | // [E|R]BX = SaveRbx |
238 | 2 | const MachineOperand &InArg = MBBI->getOperand(6); |
239 | 2 | unsigned SaveRbx = MBBI->getOperand(7).getReg(); |
240 | 2 | |
241 | 2 | unsigned ActualInArg = |
242 | 2 | Opcode == X86::LCMPXCHG8B_SAVE_EBX ? X86::EBX0 : X86::RBX2 ; |
243 | 2 | // Copy the input argument of the pseudo into the argument of the |
244 | 2 | // actual instruction. |
245 | 2 | TII->copyPhysReg(MBB, MBBI, DL, ActualInArg, InArg.getReg(), |
246 | 2 | InArg.isKill()); |
247 | 2 | // Create the actual instruction. |
248 | 2 | unsigned ActualOpc = |
249 | 2 | Opcode == X86::LCMPXCHG8B_SAVE_EBX ? X86::LCMPXCHG8B0 : X86::LCMPXCHG16B2 ; |
250 | 2 | MachineInstr *NewInstr = BuildMI(MBB, MBBI, DL, TII->get(ActualOpc)); |
251 | 2 | // Copy the operands related to the address. |
252 | 12 | for (unsigned Idx = 1; Idx < 612 ; ++Idx10 ) |
253 | 10 | NewInstr->addOperand(MBBI->getOperand(Idx)); |
254 | 2 | // Finally, restore the value of RBX. |
255 | 2 | TII->copyPhysReg(MBB, MBBI, DL, ActualInArg, SaveRbx, |
256 | 2 | /*SrcIsKill*/ true); |
257 | 2 | |
258 | 2 | // Delete the pseudo. |
259 | 2 | MBBI->eraseFromParent(); |
260 | 2 | return true; |
261 | 0 | } |
262 | 0 | } |
263 | 0 | llvm_unreachable0 ("Previous switch has a fallthrough?"); |
264 | 0 | } |
265 | | |
266 | | /// Expand all pseudo instructions contained in \p MBB. |
267 | | /// \returns true if any expansion occurred for \p MBB. |
268 | 138k | bool X86ExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) { |
269 | 138k | bool Modified = false; |
270 | 138k | |
271 | 138k | // MBBI may be invalidated by the expansion. |
272 | 138k | MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); |
273 | 1.02M | while (MBBI != E1.02M ) { |
274 | 889k | MachineBasicBlock::iterator NMBBI = std::next(MBBI); |
275 | 889k | Modified |= ExpandMI(MBB, MBBI); |
276 | 889k | MBBI = NMBBI; |
277 | 889k | } |
278 | 138k | |
279 | 138k | return Modified; |
280 | 138k | } |
281 | | |
282 | 72.7k | bool X86ExpandPseudo::runOnMachineFunction(MachineFunction &MF) { |
283 | 72.7k | STI = &static_cast<const X86Subtarget &>(MF.getSubtarget()); |
284 | 72.7k | TII = STI->getInstrInfo(); |
285 | 72.7k | TRI = STI->getRegisterInfo(); |
286 | 72.7k | X86FI = MF.getInfo<X86MachineFunctionInfo>(); |
287 | 72.7k | X86FL = STI->getFrameLowering(); |
288 | 72.7k | |
289 | 72.7k | bool Modified = false; |
290 | 72.7k | for (MachineBasicBlock &MBB : MF) |
291 | 138k | Modified |= ExpandMBB(MBB); |
292 | 72.7k | return Modified; |
293 | 72.7k | } |
294 | | |
295 | | /// Returns an instance of the pseudo instruction expansion pass. |
296 | 8.54k | FunctionPass *llvm::createX86ExpandPseudoPass() { |
297 | 8.54k | return new X86ExpandPseudo(); |
298 | 8.54k | } |