Add a late SSEDomainFix pass that twiddles SSE instructions to avoid domain crossings.
[oota-llvm.git] / lib / Target / X86 / SSEDomainFix.cpp
1 //===- SSEDomainFix.cpp - Use proper int/float domain for SSE ---*- 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 SSEDomainFix pass.
11 //
12 // Some SSE instructions like mov, and, or, xor are available in different
13 // variants for different operand types. These variant instructions are
14 // equivalent, but on Nehalem and newer cpus there is extra latency
15 // transferring data between integer and floating point domains.
16 //
17 // This pass changes the variant instructions to minimize domain crossings.
18 //
19 //===----------------------------------------------------------------------===//
20
21 #define DEBUG_TYPE "sse-domain-fix"
22 #include "X86InstrInfo.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/ADT/DepthFirstIterator.h"
25 #include "llvm/Support/Debug.h"
26 #include "llvm/Support/raw_ostream.h"
27
28 using namespace llvm;
29
30 namespace {
31 class SSEDomainFixPass : public MachineFunctionPass {
32   static char ID;
33   const X86InstrInfo *TII;
34
35   MachineFunction *MF;
36   MachineBasicBlock *MBB;
37 public:
38   SSEDomainFixPass() : MachineFunctionPass(&ID) {}
39
40   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
41     AU.setPreservesAll();
42     MachineFunctionPass::getAnalysisUsage(AU);
43   }
44
45   virtual bool runOnMachineFunction(MachineFunction &MF);
46
47   virtual const char *getPassName() const {
48     return "SSE execution domain fixup";
49   }
50
51 private:
52   void enterBasicBlock(MachineBasicBlock *MBB);
53 };
54 }
55
56 void SSEDomainFixPass::enterBasicBlock(MachineBasicBlock *mbb) {
57   MBB = mbb;
58   DEBUG(dbgs() << "Entering MBB " << MBB->getName() << "\n");
59 }
60
61 bool SSEDomainFixPass::runOnMachineFunction(MachineFunction &mf) {
62   MF = &mf;
63   TII = static_cast<const X86InstrInfo*>(MF->getTarget().getInstrInfo());
64
65   MachineBasicBlock *Entry = MF->begin();
66   SmallPtrSet<MachineBasicBlock*, 16> Visited;
67   for (df_ext_iterator<MachineBasicBlock*,
68          SmallPtrSet<MachineBasicBlock*, 16> >
69          DFI = df_ext_begin(Entry, Visited), DFE = df_ext_end(Entry, Visited);
70        DFI != DFE; ++DFI) {
71     enterBasicBlock(*DFI);
72     for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
73         ++I) {
74       MachineInstr *MI = I;
75       const unsigned *equiv = 0;
76       X86InstrInfo::SSEDomain domain = TII->GetSSEDomain(MI, equiv);
77       DEBUG(dbgs() << "isd-"[domain] << (equiv ? "* " : "  ") << *MI);
78     }
79   }
80   return false;
81 }
82
83 FunctionPass *llvm::createSSEDomainFixPass() {
84   return new SSEDomainFixPass();
85 }
86
87 // These are the replaceable instructions. Some of these have _Int variants
88 // that we don't include here. We don't want to replace instructions selected
89 // by intrinsics.
90 static const unsigned ReplaceableInstrs[][3] = {
91   //PackedInt          PackedSingle     PackedDouble
92   { X86::MOVDQAmr,     X86::MOVAPSmr,   X86::MOVAPDmr   },
93   { X86::MOVDQArm,     X86::MOVAPSrm,   X86::MOVAPDrm   },
94   { X86::MOVDQArr,     X86::MOVAPSrr,   X86::MOVAPDrr   },
95   { X86::MOVDQUmr,     X86::MOVUPSmr,   X86::MOVUPDmr   },
96   { X86::MOVDQUrm,     X86::MOVUPSrm,   X86::MOVUPDrm   },
97   { X86::MOVNTDQmr,    X86::MOVNTPSmr,  X86::MOVNTPDmr  },
98   { X86::PANDNrm,      X86::ANDNPSrm,   X86::ANDNPDrm   },
99   { X86::PANDNrr,      X86::ANDNPSrr,   X86::ANDNPDrr   },
100   { X86::PANDrm,       X86::ANDPSrm,    X86::ANDPDrm    },
101   { X86::PANDrr,       X86::ANDPSrr,    X86::ANDPDrr    },
102   { X86::PORrm,        X86::ORPSrm,     X86::ORPDrm     },
103   { X86::PORrr,        X86::ORPSrr,     X86::ORPDrr     },
104   { X86::PUNPCKHQDQrm, X86::UNPCKHPSrm, X86::UNPCKHPDrm },
105   { X86::PUNPCKHQDQrr, X86::UNPCKHPSrr, X86::UNPCKHPDrr },
106   { X86::PUNPCKLQDQrm, X86::UNPCKLPSrm, X86::UNPCKLPDrm },
107   { X86::PUNPCKLQDQrr, X86::UNPCKLPSrr, X86::UNPCKLPDrr },
108   { X86::PXORrm,       X86::XORPSrm,    X86::XORPDrm    },
109   { X86::PXORrr,       X86::XORPSrr,    X86::XORPDrr    },
110 };
111
112 void X86InstrInfo::populateSSEInstrDomainTable() {
113   // Instructions that execute in the packed integer domain.
114   static const unsigned PackedIntInstrs[] = {
115     X86::LDDQUrm,
116     X86::MASKMOVDQU,
117     X86::MASKMOVDQU64,
118     X86::MOVDI2PDIrm,
119     X86::MOVDI2PDIrr,
120     X86::MOVDQUmr_Int,
121     X86::MOVDQUrm_Int,
122     X86::MOVLQ128mr,
123     X86::MOVNTDQArm,
124     X86::MOVNTDQmr_Int,
125     X86::MOVNTDQ_64mr,
126     X86::MOVPDI2DImr,
127     X86::MOVPDI2DIrr,
128     X86::MOVPQI2QImr,
129     X86::MOVPQIto64rr,
130     X86::MOVQI2PQIrm,
131     X86::MOVQxrxr,
132     X86::MOVZDI2PDIrm,
133     X86::MOVZDI2PDIrr,
134     X86::MOVZPQILo2PQIrm,
135     X86::MOVZPQILo2PQIrr,
136     X86::MOVZQI2PQIrm,
137     X86::MOVZQI2PQIrr,
138     X86::MPSADBWrmi,
139     X86::MPSADBWrri,
140     X86::PABSBrm128,
141     X86::PABSBrr128,
142     X86::PABSDrm128,
143     X86::PABSDrr128,
144     X86::PABSWrm128,
145     X86::PABSWrr128,
146     X86::PACKSSDWrm,
147     X86::PACKSSDWrr,
148     X86::PACKSSWBrm,
149     X86::PACKSSWBrr,
150     X86::PACKUSDWrm,
151     X86::PACKUSDWrr,
152     X86::PACKUSWBrm,
153     X86::PACKUSWBrr,
154     X86::PADDBrm,
155     X86::PADDBrr,
156     X86::PADDDrm,
157     X86::PADDDrr,
158     X86::PADDQrm,
159     X86::PADDQrr,
160     X86::PADDSBrm,
161     X86::PADDSBrr,
162     X86::PADDSWrm,
163     X86::PADDSWrr,
164     X86::PADDUSBrm,
165     X86::PADDUSBrr,
166     X86::PADDUSWrm,
167     X86::PADDUSWrr,
168     X86::PADDWrm,
169     X86::PADDWrr,
170     X86::PALIGNR128rm,
171     X86::PALIGNR128rr,
172     X86::PAVGBrm,
173     X86::PAVGBrr,
174     X86::PAVGWrm,
175     X86::PAVGWrr,
176     X86::PBLENDVBrm0,
177     X86::PBLENDVBrr0,
178     X86::PBLENDWrmi,
179     X86::PBLENDWrri,
180     X86::PCMPEQBrm,
181     X86::PCMPEQBrr,
182     X86::PCMPEQDrm,
183     X86::PCMPEQDrr,
184     X86::PCMPEQQrm,
185     X86::PCMPEQQrr,
186     X86::PCMPEQWrm,
187     X86::PCMPEQWrr,
188     X86::PCMPESTRIArm,
189     X86::PCMPESTRIArr,
190     X86::PCMPESTRICrm,
191     X86::PCMPESTRICrr,
192     X86::PCMPESTRIOrm,
193     X86::PCMPESTRIOrr,
194     X86::PCMPESTRIrm,
195     X86::PCMPESTRIrr,
196     X86::PCMPESTRISrm,
197     X86::PCMPESTRISrr,
198     X86::PCMPESTRIZrm,
199     X86::PCMPESTRIZrr,
200     X86::PCMPESTRM128MEM,
201     X86::PCMPESTRM128REG,
202     X86::PCMPESTRM128rm,
203     X86::PCMPESTRM128rr,
204     X86::PCMPGTBrm,
205     X86::PCMPGTBrr,
206     X86::PCMPGTDrm,
207     X86::PCMPGTDrr,
208     X86::PCMPGTQrm,
209     X86::PCMPGTQrr,
210     X86::PCMPGTWrm,
211     X86::PCMPGTWrr,
212     X86::PCMPISTRIArm,
213     X86::PCMPISTRIArr,
214     X86::PCMPISTRICrm,
215     X86::PCMPISTRICrr,
216     X86::PCMPISTRIOrm,
217     X86::PCMPISTRIOrr,
218     X86::PCMPISTRIrm,
219     X86::PCMPISTRIrr,
220     X86::PCMPISTRISrm,
221     X86::PCMPISTRISrr,
222     X86::PCMPISTRIZrm,
223     X86::PCMPISTRIZrr,
224     X86::PCMPISTRM128MEM,
225     X86::PCMPISTRM128REG,
226     X86::PCMPISTRM128rm,
227     X86::PCMPISTRM128rr,
228     X86::PEXTRBmr,
229     X86::PEXTRBrr,
230     X86::PEXTRDmr,
231     X86::PEXTRDrr,
232     X86::PEXTRQmr,
233     X86::PEXTRQrr,
234     X86::PEXTRWmr,
235     X86::PEXTRWri,
236     X86::PHADDDrm128,
237     X86::PHADDDrr128,
238     X86::PHADDSWrm128,
239     X86::PHADDSWrr128,
240     X86::PHADDWrm128,
241     X86::PHADDWrr128,
242     X86::PHMINPOSUWrm128,
243     X86::PHMINPOSUWrr128,
244     X86::PHSUBDrm128,
245     X86::PHSUBDrr128,
246     X86::PHSUBSWrm128,
247     X86::PHSUBSWrr128,
248     X86::PHSUBWrm128,
249     X86::PHSUBWrr128,
250     X86::PINSRBrm,
251     X86::PINSRBrr,
252     X86::PINSRDrm,
253     X86::PINSRDrr,
254     X86::PINSRQrm,
255     X86::PINSRQrr,
256     X86::PINSRWrmi,
257     X86::PINSRWrri,
258     X86::PMADDUBSWrm128,
259     X86::PMADDUBSWrr128,
260     X86::PMADDWDrm,
261     X86::PMADDWDrr,
262     X86::PMAXSBrm,
263     X86::PMAXSBrr,
264     X86::PMAXSDrm,
265     X86::PMAXSDrr,
266     X86::PMAXSWrm,
267     X86::PMAXSWrr,
268     X86::PMAXUBrm,
269     X86::PMAXUBrr,
270     X86::PMAXUDrm,
271     X86::PMAXUDrr,
272     X86::PMAXUWrm,
273     X86::PMAXUWrr,
274     X86::PMINSBrm,
275     X86::PMINSBrr,
276     X86::PMINSDrm,
277     X86::PMINSDrr,
278     X86::PMINSWrm,
279     X86::PMINSWrr,
280     X86::PMINUBrm,
281     X86::PMINUBrr,
282     X86::PMINUDrm,
283     X86::PMINUDrr,
284     X86::PMINUWrm,
285     X86::PMINUWrr,
286     X86::PMOVSXBDrm,
287     X86::PMOVSXBDrr,
288     X86::PMOVSXBQrm,
289     X86::PMOVSXBQrr,
290     X86::PMOVSXBWrm,
291     X86::PMOVSXBWrr,
292     X86::PMOVSXDQrm,
293     X86::PMOVSXDQrr,
294     X86::PMOVSXWDrm,
295     X86::PMOVSXWDrr,
296     X86::PMOVSXWQrm,
297     X86::PMOVSXWQrr,
298     X86::PMOVZXBDrm,
299     X86::PMOVZXBDrr,
300     X86::PMOVZXBQrm,
301     X86::PMOVZXBQrr,
302     X86::PMOVZXBWrm,
303     X86::PMOVZXBWrr,
304     X86::PMOVZXDQrm,
305     X86::PMOVZXDQrr,
306     X86::PMOVZXWDrm,
307     X86::PMOVZXWDrr,
308     X86::PMOVZXWQrm,
309     X86::PMOVZXWQrr,
310     X86::PMULDQrm,
311     X86::PMULDQrr,
312     X86::PMULHRSWrm128,
313     X86::PMULHRSWrr128,
314     X86::PMULHUWrm,
315     X86::PMULHUWrr,
316     X86::PMULHWrm,
317     X86::PMULHWrr,
318     X86::PMULLDrm,
319     X86::PMULLDrm_int,
320     X86::PMULLDrr,
321     X86::PMULLDrr_int,
322     X86::PMULLWrm,
323     X86::PMULLWrr,
324     X86::PMULUDQrm,
325     X86::PMULUDQrr,
326     X86::PSADBWrm,
327     X86::PSADBWrr,
328     X86::PSHUFBrm128,
329     X86::PSHUFBrr128,
330     X86::PSHUFHWmi,
331     X86::PSHUFHWri,
332     X86::PSHUFLWmi,
333     X86::PSHUFLWri,
334     X86::PSIGNBrm128,
335     X86::PSIGNBrr128,
336     X86::PSIGNDrm128,
337     X86::PSIGNDrr128,
338     X86::PSIGNWrm128,
339     X86::PSIGNWrr128,
340     X86::PSLLDQri,
341     X86::PSLLDri,
342     X86::PSLLDrm,
343     X86::PSLLDrr,
344     X86::PSLLQri,
345     X86::PSLLQrm,
346     X86::PSLLQrr,
347     X86::PSLLWri,
348     X86::PSLLWrm,
349     X86::PSLLWrr,
350     X86::PSRADri,
351     X86::PSRADrm,
352     X86::PSRADrr,
353     X86::PSRAWri,
354     X86::PSRAWrm,
355     X86::PSRAWrr,
356     X86::PSRLDQri,
357     X86::PSRLDri,
358     X86::PSRLDrm,
359     X86::PSRLDrr,
360     X86::PSRLQri,
361     X86::PSRLQrm,
362     X86::PSRLQrr,
363     X86::PSRLWri,
364     X86::PSRLWrm,
365     X86::PSRLWrr,
366     X86::PSUBBrm,
367     X86::PSUBBrr,
368     X86::PSUBDrm,
369     X86::PSUBDrr,
370     X86::PSUBQrm,
371     X86::PSUBQrr,
372     X86::PSUBSBrm,
373     X86::PSUBSBrr,
374     X86::PSUBSWrm,
375     X86::PSUBSWrr,
376     X86::PSUBUSBrm,
377     X86::PSUBUSBrr,
378     X86::PSUBUSWrm,
379     X86::PSUBUSWrr,
380     X86::PSUBWrm,
381     X86::PSUBWrr,
382     X86::PUNPCKHBWrm,
383     X86::PUNPCKHBWrr,
384     X86::PUNPCKHWDrm,
385     X86::PUNPCKHWDrr,
386     X86::PUNPCKLBWrm,
387     X86::PUNPCKLBWrr,
388     X86::PUNPCKLWDrm,
389     X86::PUNPCKLWDrr,
390   };
391
392   // Instructions that execute in the packed single domain.
393   static const unsigned PackedSingleInstrs[] = {
394     X86::ADDPSrm,
395     X86::ADDPSrr,
396     X86::ADDSUBPSrm,
397     X86::ADDSUBPSrr,
398     X86::BLENDPSrmi,
399     X86::BLENDPSrri,
400     X86::BLENDVPSrm0,
401     X86::BLENDVPSrr0,
402     X86::CMPPSrmi,
403     X86::CMPPSrri,
404     X86::DIVPSrm,
405     X86::DIVPSrr,
406     X86::DPPSrmi,
407     X86::DPPSrri,
408     X86::EXTRACTPSmr,
409     X86::EXTRACTPSrr,
410     X86::HADDPSrm,
411     X86::HADDPSrr,
412     X86::HSUBPSrm,
413     X86::HSUBPSrr,
414     X86::INSERTPSrm,
415     X86::INSERTPSrr,
416     X86::MAXPSrm,
417     X86::MAXPSrm_Int,
418     X86::MAXPSrr,
419     X86::MAXPSrr_Int,
420     X86::MINPSrm,
421     X86::MINPSrm_Int,
422     X86::MINPSrr,
423     X86::MINPSrr_Int,
424     X86::MOVHLPSrr,
425     X86::MOVHPSmr,
426     X86::MOVHPSrm,
427     X86::MOVLHPSrr,
428     X86::MOVLPSmr,
429     X86::MOVLPSrm,
430     X86::MOVMSKPSrr,
431     X86::MOVNTPSmr_Int,
432     X86::MOVSHDUPrm,
433     X86::MOVSHDUPrr,
434     X86::MOVSLDUPrm,
435     X86::MOVSLDUPrr,
436     X86::MOVUPSmr_Int,
437     X86::MOVUPSrm_Int,
438     X86::MULPSrm,
439     X86::MULPSrr,
440     X86::RCPPSm,
441     X86::RCPPSm_Int,
442     X86::RCPPSr,
443     X86::RCPPSr_Int,
444     X86::ROUNDPSm_Int,
445     X86::ROUNDPSr_Int,
446     X86::RSQRTPSm,
447     X86::RSQRTPSm_Int,
448     X86::RSQRTPSr,
449     X86::RSQRTPSr_Int,
450     X86::SQRTPSm,
451     X86::SQRTPSm_Int,
452     X86::SQRTPSr,
453     X86::SQRTPSr_Int,
454     X86::SUBPSrm,
455     X86::SUBPSrr,
456   };
457
458   // Instructions that execute in the packed double domain.
459   static const unsigned PackedDoubleInstrs[] = {
460     X86::ADDPDrm,
461     X86::ADDPDrr,
462     X86::ADDSUBPDrm,
463     X86::ADDSUBPDrr,
464     X86::BLENDPDrmi,
465     X86::BLENDPDrri,
466     X86::BLENDVPDrm0,
467     X86::BLENDVPDrr0,
468     X86::CMPPDrmi,
469     X86::CMPPDrri,
470     X86::DIVPDrm,
471     X86::DIVPDrr,
472     X86::DPPDrmi,
473     X86::DPPDrri,
474     X86::HADDPDrm,
475     X86::HADDPDrr,
476     X86::HSUBPDrm,
477     X86::HSUBPDrr,
478     X86::MAXPDrm,
479     X86::MAXPDrm_Int,
480     X86::MAXPDrr,
481     X86::MAXPDrr_Int,
482     X86::MINPDrm,
483     X86::MINPDrm_Int,
484     X86::MINPDrr,
485     X86::MINPDrr_Int,
486     X86::MOVHPDmr,
487     X86::MOVHPDrm,
488     X86::MOVLPDmr,
489     X86::MOVLPDrm,
490     X86::MOVMSKPDrr,
491     X86::MOVNTPDmr_Int,
492     X86::MOVUPDmr_Int,
493     X86::MOVUPDrm_Int,
494     X86::MULPDrm,
495     X86::MULPDrr,
496     X86::ROUNDPDm_Int,
497     X86::ROUNDPDr_Int,
498     X86::SQRTPDm,
499     X86::SQRTPDm_Int,
500     X86::SQRTPDr,
501     X86::SQRTPDr_Int,
502     X86::SUBPDrm,
503     X86::SUBPDrr,
504   };
505
506   // Add non-negative entries for forcing instructions.
507   for (unsigned i = 0, e = array_lengthof(PackedIntInstrs); i != e; ++i)
508     SSEInstrDomainTable.insert(std::make_pair(PackedIntInstrs[i],
509                                               PackedInt));
510   for (unsigned i = 0, e = array_lengthof(PackedSingleInstrs); i != e; ++i)
511     SSEInstrDomainTable.insert(std::make_pair(PackedSingleInstrs[i],
512                                               PackedSingle));
513   for (unsigned i = 0, e = array_lengthof(PackedDoubleInstrs); i != e; ++i)
514     SSEInstrDomainTable.insert(std::make_pair(PackedDoubleInstrs[i],
515                                               PackedDouble));
516
517   // Add row number + 1 for replaceable instructions.
518   for (unsigned i = 0, e = array_lengthof(ReplaceableInstrs); i != e; ++i)
519     for (unsigned c = 0; c != 3; ++c)
520     SSEInstrDomainTable.insert(std::make_pair(ReplaceableInstrs[i][c],
521                                               c + 4*(i+1)));
522 }
523
524 X86InstrInfo::SSEDomain X86InstrInfo::GetSSEDomain(const MachineInstr *MI,
525                                                  const unsigned *&equiv) const {
526   DenseMap<unsigned,unsigned>::const_iterator i =
527     SSEInstrDomainTable.find(MI->getOpcode());
528   if (i == SSEInstrDomainTable.end())
529     return NotSSEDomain;
530   unsigned value = i->second;
531   if (value/4)
532     equiv = ReplaceableInstrs[value/4 - 1];
533   else
534     equiv = 0;
535   return SSEDomain(value & 3);
536 }