Remove X86-dependent stuff from SSEDomainFix.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 27 Sep 2011 23:50:46 +0000 (23:50 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 27 Sep 2011 23:50:46 +0000 (23:50 +0000)
This also enables domain swizzling for AVX code which required a few
trivial test changes.

The pass will be moved to lib/CodeGen shortly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140659 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/Passes.h
lib/Target/X86/SSEDomainFix.cpp
lib/Target/X86/X86.h
lib/Target/X86/X86TargetMachine.cpp
test/CodeGen/X86/avx-load-store.ll
test/CodeGen/X86/avx-splat.ll

index 82b384461a1e185fe6d930c4ecf2b7eed036bc28..7a03ce905d897251854e989c6195df9ee4c1c002 100644 (file)
@@ -24,6 +24,7 @@ namespace llvm {
   class MachineFunctionPass;
   class PassInfo;
   class TargetLowering;
+  class TargetRegisterClass;
   class raw_ostream;
 
   /// createUnreachableBlockEliminationPass - The LLVM code generator does not
@@ -225,6 +226,14 @@ namespace llvm {
   ///
   FunctionPass *createExpandISelPseudosPass();
 
+  /// createExecutionDependencyFixPass - This pass fixes execution time
+  /// problems with dependent instructions, such as switching execution
+  /// domains to match.
+  ///
+  /// The pass will examine instructions using and defining registers in RC.
+  ///
+  FunctionPass *createExecutionDependencyFixPass(const TargetRegisterClass *RC);
+
 } // End llvm namespace
 
 #endif
index 752099846f7b710974dda8cb17cd3b96fd540527..8d8f5d452df01e28643417652c33be1b9ba59de2 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "sse-domain-fix"
-#include "X86InstrInfo.h"
+#define DEBUG_TYPE "execution-fix"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Debug.h"
@@ -97,25 +99,27 @@ struct DomainValue {
 };
 }
 
-static const unsigned NumRegs = 16;
-
 namespace {
 class SSEDomainFixPass : public MachineFunctionPass {
   static char ID;
   SpecificBumpPtrAllocator<DomainValue> Allocator;
   SmallVector<DomainValue*,16> Avail;
 
+  const TargetRegisterClass *const RC;
   MachineFunction *MF;
-  const X86InstrInfo *TII;
+  const TargetInstrInfo *TII;
   const TargetRegisterInfo *TRI;
   MachineBasicBlock *MBB;
+  std::vector<int> AliasMap;
+  const unsigned NumRegs;
   DomainValue **LiveRegs;
   typedef DenseMap<MachineBasicBlock*,DomainValue**> LiveOutMap;
   LiveOutMap LiveOuts;
   unsigned Distance;
 
 public:
-  SSEDomainFixPass() : MachineFunctionPass(ID) {}
+  SSEDomainFixPass(const TargetRegisterClass *rc)
+    : MachineFunctionPass(ID), RC(rc), NumRegs(RC->getNumRegs()) {}
 
   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.setPreservesAll();
@@ -154,10 +158,9 @@ char SSEDomainFixPass::ID = 0;
 
 /// Translate TRI register number to an index into our smaller tables of
 /// interesting registers. Return -1 for boring registers.
-int SSEDomainFixPass::RegIndex(unsigned reg) {
-  assert(X86::XMM15 == X86::XMM0+NumRegs-1 && "Unexpected sort");
-  reg -= X86::XMM0;
-  return reg < NumRegs ? (int) reg : -1;
+int SSEDomainFixPass::RegIndex(unsigned Reg) {
+  assert(Reg < AliasMap.size() && "Invalid register");
+  return AliasMap[Reg];
 }
 
 DomainValue *SSEDomainFixPass::Alloc(int domain) {
@@ -444,23 +447,33 @@ void SSEDomainFixPass::visitGenericInstr(MachineInstr *mi) {
 
 bool SSEDomainFixPass::runOnMachineFunction(MachineFunction &mf) {
   MF = &mf;
-  TII = static_cast<const X86InstrInfo*>(MF->getTarget().getInstrInfo());
+  TII = MF->getTarget().getInstrInfo();
   TRI = MF->getTarget().getRegisterInfo();
   MBB = 0;
   LiveRegs = 0;
   Distance = 0;
-  assert(NumRegs == X86::VR128RegClass.getNumRegs() && "Bad regclass");
+  assert(NumRegs == RC->getNumRegs() && "Bad regclass");
 
   // If no XMM registers are used in the function, we can skip it completely.
   bool anyregs = false;
-  for (TargetRegisterClass::const_iterator I = X86::VR128RegClass.begin(),
-         E = X86::VR128RegClass.end(); I != E; ++I)
+  for (TargetRegisterClass::const_iterator I = RC->begin(), E = RC->end();
+       I != E; ++I)
     if (MF->getRegInfo().isPhysRegUsed(*I)) {
       anyregs = true;
       break;
     }
   if (!anyregs) return false;
 
+  // Initialize the AliasMap on the first use.
+  if (AliasMap.empty()) {
+    // Given a PhysReg, AliasMap[PhysReg] is either the relevant index into RC,
+    // or -1.
+    AliasMap.resize(TRI->getNumRegs(), -1);
+    for (unsigned i = 0, e = RC->getNumRegs(); i != e; ++i)
+      for (const unsigned *AI = TRI->getOverlaps(RC->getRegister(i)); *AI; ++AI)
+        AliasMap[*AI] = i;
+  }
+
   MachineBasicBlock *Entry = MF->begin();
   SmallPtrSet<MachineBasicBlock*, 16> Visited;
   for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*, 16> >
@@ -501,6 +514,7 @@ bool SSEDomainFixPass::runOnMachineFunction(MachineFunction &mf) {
   return false;
 }
 
-FunctionPass *llvm::createSSEDomainFixPass() {
-  return new SSEDomainFixPass();
+FunctionPass *
+llvm::createExecutionDependencyFixPass(const TargetRegisterClass *RC) {
+  return new SSEDomainFixPass(RC);
 }
index d480d0c8654afaae2c1981ad1589ec08ccc122f7..81e94227fca6cb21952f4aec8f78b786d17a19ea 100644 (file)
@@ -44,10 +44,6 @@ FunctionPass* createGlobalBaseRegPass();
 ///
 FunctionPass *createX86FloatingPointStackifierPass();
 
-/// createSSEDomainFixPass - This pass twiddles SSE opcodes to prevent domain
-/// crossings.
-FunctionPass *createSSEDomainFixPass();
-
 /// createX86IssueVZeroUpperPass - This pass inserts AVX vzeroupper instructions
 /// before each call to avoid transition penalty between functions encoded with
 /// AVX and SSE.
index 6a35ecc605a02699001cb46f2bff85043181f6b2..683d6aa0dd5eb117b821e4228c3990bc5e894edc 100644 (file)
@@ -133,7 +133,7 @@ bool X86TargetMachine::addPreEmitPass(PassManagerBase &PM,
   bool ShouldPrint = false;
   if (OptLevel != CodeGenOpt::None &&
       (Subtarget.hasSSE2() || Subtarget.hasAVX())) {
-    PM.add(createSSEDomainFixPass());
+    PM.add(createExecutionDependencyFixPass(&X86::VR128RegClass));
     ShouldPrint = true;
   }
 
index 1fda9bc22923407804c5c1d3ff2a971a26a332e3..07a63efd71fc1c40aeab0c02c54f6798ceabe9af 100644 (file)
@@ -3,8 +3,8 @@
 
 ; CHECK: vmovaps
 ; CHECK: vmovaps
-; CHECK: vmovapd
-; CHECK: vmovapd
+; CHECK: vmovaps
+; CHECK: vmovaps
 ; CHECK: vmovaps
 ; CHECK: vmovaps
 define void @test_256_load(double* nocapture %d, float* nocapture %f, <4 x i64>* nocapture %i) nounwind uwtable ssp {
index f8522c269515d3ebb3746f811cefb12a6e37241a..af20b90322e173b567e36a5cfa2018c95f61d4aa 100644 (file)
@@ -47,7 +47,7 @@ entry:
 ;   shuffle (scalar_to_vector (load (ptr + 4))), undef, <0, 0, 0, 0>
 ; To:
 ;   shuffle (vload ptr)), undef, <1, 1, 1, 1>
-; CHECK: vmovaps
+; CHECK: vmovdqa
 ; CHECK-NEXT: vinsertf128  $1
 ; CHECK-NEXT: vpermilps $-1
 define <8 x float> @funcE() nounwind {