[Mesa-dev] [PATCH 2/2] radeon/llvm: Add a R600VolatileLoadSetter pass to fix v3f32 store/load

Vincent Lejeune vljn at ovi.com
Fri Nov 16 08:04:39 PST 2012


---
 lib/Target/AMDGPU/AMDGPU.h                   |  1 +
 lib/Target/AMDGPU/AMDGPUTargetMachine.cpp    |  1 +
 lib/Target/AMDGPU/R600AllocateMemoryRegs.cpp |  2 +-
 lib/Target/AMDGPU/R600VolatileLoadSetter.cpp | 71 ++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 lib/Target/AMDGPU/R600VolatileLoadSetter.cpp

diff --git a/lib/Target/AMDGPU/AMDGPU.h b/lib/Target/AMDGPU/AMDGPU.h
index 9897e0d..14bc173 100644
--- a/lib/Target/AMDGPU/AMDGPU.h
+++ b/lib/Target/AMDGPU/AMDGPU.h
@@ -20,6 +20,7 @@ class FunctionPass;
 class AMDGPUTargetMachine;
 
 // R600 Passes
+FunctionPass *createR600VolatileLoadSetter();
 FunctionPass* createR600AllocateMemoryRegsPass(TargetMachine &tm);
 FunctionPass* createR600KernelParametersPass(const DataLayout *TD);
 FunctionPass *createR600ExpandSpecialInstrsPass(TargetMachine &tm);
diff --git a/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 5210849..ecb8da0 100644
--- a/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -95,6 +95,7 @@ TargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) {
 bool
 AMDGPUPassConfig::addPreISel()
 {
+  addPass(createR600VolatileLoadSetter());
   return false;
 }
 
diff --git a/lib/Target/AMDGPU/R600AllocateMemoryRegs.cpp b/lib/Target/AMDGPU/R600AllocateMemoryRegs.cpp
index a5b3c68..dd227f9 100644
--- a/lib/Target/AMDGPU/R600AllocateMemoryRegs.cpp
+++ b/lib/Target/AMDGPU/R600AllocateMemoryRegs.cpp
@@ -57,7 +57,7 @@ bool R600AllocateMemoryRegsPass::runOnMachineFunction(MachineFunction &MF) {
 
   std::vector<unsigned> IndirectRegs = TII->getIndirectReservedRegs(MF);
   MachineRegisterInfo &MRI = MF.getRegInfo();
-  unsigned IndirectRegOffset = TII->getIndirectIndexBegin(MF);
+  unsigned IndirectRegOffset = 15;// TII->getIndirectIndexBegin(MF);
 
   for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
                                                       BB != BB_E; ++BB) {
diff --git a/lib/Target/AMDGPU/R600VolatileLoadSetter.cpp b/lib/Target/AMDGPU/R600VolatileLoadSetter.cpp
new file mode 100644
index 0000000..dde4cdf
--- /dev/null
+++ b/lib/Target/AMDGPU/R600VolatileLoadSetter.cpp
@@ -0,0 +1,71 @@
+//===-- R600AllocateMemoryRegs.cpp - Indirect Adressing Support -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass force every load instruction to be set as volatile.
+// For non power of 2 vectors, LLVM always uses tinier vector store instructions
+// to match the exact size of the original vector ; on the other hand it
+// can load vector using bigger vector load instructions if the load is marked
+// as non volatile, which can lead to inconsistent store/load operations
+// in AMDGPU backend. This pass force all load instructions to be volatile.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AMDGPU.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/InstVisitor.h"
+
+namespace llvm {
+
+class LLVM_LIBRARY_VISIBILITY R600VolatileLoadSetter :
+  public FunctionPass, public InstVisitor<R600VolatileLoadSetter>
+{
+protected:
+  bool TypeContainsVec3(Type *LoadedType) const {
+    if (VectorType *VectorLoadedType = dyn_cast<VectorType>(LoadedType)) {
+      return VectorLoadedType->getNumElements() == 3;
+    }
+    if (CompositeType *CompLoadedType = dyn_cast<CompositeType>(LoadedType)) {
+      for (CompositeType::subtype_iterator I = CompLoadedType->subtype_begin(),
+          E = CompLoadedType->subtype_end(); I != E; ++I)
+      {
+        if (TypeContainsVec3(*I))
+          return true;
+      }
+      return false;
+    }
+    return false;
+  }
+
+public:
+  static char ID;
+  R600VolatileLoadSetter() : FunctionPass(ID) { }
+  ~R600VolatileLoadSetter() { }
+  bool runOnFunction(Function &F) {
+    visit(F);
+    return true;
+  }
+
+  const char *getPassName() const { return "R600 Set Volatile to Load Inst"; }
+
+  void visitLoadInst(LoadInst &I) {
+    if (I.getPointerAddressSpace() != 0)
+      return;
+    if (TypeContainsVec3(I.getType()))
+      I.setVolatile(true);
+  }
+};
+
+char R600VolatileLoadSetter::ID = 0;
+
+
+FunctionPass *createR600VolatileLoadSetter() {
+  return new R600VolatileLoadSetter();
+}
+
+}
-- 
1.7.11.7



More information about the mesa-dev mailing list