diff options
Diffstat (limited to 'lib/Target/X86/SSEDomainFix.cpp')
-rw-r--r-- | lib/Target/X86/SSEDomainFix.cpp | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/lib/Target/X86/SSEDomainFix.cpp b/lib/Target/X86/SSEDomainFix.cpp new file mode 100644 index 0000000000..261b40c5ab --- /dev/null +++ b/lib/Target/X86/SSEDomainFix.cpp @@ -0,0 +1,98 @@ +//===- SSEDomainFix.cpp - Use proper int/float domain for SSE ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the SSEDomainFix pass. +// +// Some SSE instructions like mov, and, or, xor are available in different +// variants for different operand types. These variant instructions are +// equivalent, but on Nehalem and newer cpus there is extra latency +// transferring data between integer and floating point domains. +// +// This pass changes the variant instructions to minimize domain crossings. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sse-domain-fix" +#include "X86InstrInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +namespace { +class SSEDomainFixPass : public MachineFunctionPass { + static char ID; + const X86InstrInfo *TII; + + MachineFunction *MF; + MachineBasicBlock *MBB; +public: + SSEDomainFixPass() : MachineFunctionPass(&ID) {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + virtual bool runOnMachineFunction(MachineFunction &MF); + + virtual const char *getPassName() const { + return "SSE execution domain fixup"; + } + +private: + void enterBasicBlock(MachineBasicBlock *MBB); +}; +} + +char SSEDomainFixPass::ID = 0; + +void SSEDomainFixPass::enterBasicBlock(MachineBasicBlock *mbb) { + MBB = mbb; + DEBUG(dbgs() << "Entering MBB " << MBB->getName() << "\n"); +} + +bool SSEDomainFixPass::runOnMachineFunction(MachineFunction &mf) { + MF = &mf; + TII = static_cast<const X86InstrInfo*>(MF->getTarget().getInstrInfo()); + + // If no XMM registers are used in the function, we can skip it completely. + bool XMMIsUsed = false; + for (TargetRegisterClass::const_iterator I = X86::VR128RegClass.begin(), + E = X86::VR128RegClass.end(); I != E; ++I) + if (MF->getRegInfo().isPhysRegUsed(*I)) { + XMMIsUsed = true; + break; + } + if (!XMMIsUsed) return false; + + MachineBasicBlock *Entry = MF->begin(); + SmallPtrSet<MachineBasicBlock*, 16> Visited; + for (df_ext_iterator<MachineBasicBlock*, + SmallPtrSet<MachineBasicBlock*, 16> > + DFI = df_ext_begin(Entry, Visited), DFE = df_ext_end(Entry, Visited); + DFI != DFE; ++DFI) { + enterBasicBlock(*DFI); + for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E; + ++I) { + MachineInstr *MI = I; + const unsigned *equiv = 0; + X86InstrInfo::SSEDomain domain = TII->GetSSEDomain(MI, equiv); + DEBUG(dbgs() << "-isd"[domain] << (equiv ? "* " : " ") << *MI); + } + } + return false; +} + +FunctionPass *llvm::createSSEDomainFixPass() { + return new SSEDomainFixPass(); +} |