[Beignet] [PATCH 1/3] add basic function to dump Selection IR

Guo Yejun yejun.guo at intel.com
Sun Sep 6 14:27:01 PDT 2015


Selection IR is a representation between Gen IR and Gen ASM, it is
almost a Gen instruction but *before* the register allocation.

only basic dump supported, not fully completed yet. Once finished,
can be refined as operator<< for relative classes.

Signed-off-by: Guo Yejun <yejun.guo at intel.com>
---
 backend/src/CMakeLists.txt                        |   2 +
 backend/src/backend/gen_context.cpp               |   4 +
 backend/src/backend/gen_insn_selection_output.cpp | 166 ++++++++++++++++++++++
 backend/src/backend/gen_insn_selection_output.hpp |  13 ++
 backend/src/backend/gen_register.hpp              |  28 ++++
 5 files changed, 213 insertions(+)
 create mode 100644 backend/src/backend/gen_insn_selection_output.cpp
 create mode 100644 backend/src/backend/gen_insn_selection_output.hpp

diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt
index c0d0c23..ef95910 100644
--- a/backend/src/CMakeLists.txt
+++ b/backend/src/CMakeLists.txt
@@ -101,6 +101,8 @@ set (GBE_SRC
     backend/gen_insn_selection.hpp
     backend/gen_insn_scheduling.cpp
     backend/gen_insn_scheduling.hpp
+    backend/gen_insn_selection_output.cpp
+    backend/gen_insn_selection_output.hpp
     backend/gen_reg_allocation.cpp
     backend/gen_reg_allocation.hpp
     backend/gen_context.cpp
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 25fdf08..075307d 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -28,6 +28,7 @@
 #include "backend/gen_encoder.hpp"
 #include "backend/gen_insn_selection.hpp"
 #include "backend/gen_insn_scheduling.hpp"
+#include "backend/gen_insn_selection_output.hpp"
 #include "backend/gen_reg_allocation.hpp"
 #include "backend/gen/gen_mesa_disasm.h"
 #include "ir/function.hpp"
@@ -2298,10 +2299,13 @@ namespace gbe
     kernel->curbeSize = ALIGN(kernel->curbeSize, GEN_REG_SIZE);
   }
 
+  BVAR(OCL_OUTPUT_SEL_IR, false);
   bool GenContext::emitCode(void) {
     GenKernel *genKernel = static_cast<GenKernel*>(this->kernel);
     buildPatchList();
     sel->select();
+    if (OCL_OUTPUT_SEL_IR)
+      outputSelectionIR(*this, this->sel);
     schedulePreRegAllocation(*this, *this->sel);
     if (UNLIKELY(ra->allocate(*this->sel) == false))
       return false;
diff --git a/backend/src/backend/gen_insn_selection_output.cpp b/backend/src/backend/gen_insn_selection_output.cpp
new file mode 100644
index 0000000..1861637
--- /dev/null
+++ b/backend/src/backend/gen_insn_selection_output.cpp
@@ -0,0 +1,166 @@
+#include "backend/gen_insn_selection.hpp"
+#include "backend/gen_insn_selection_output.hpp"
+#include "sys/cvar.hpp"
+#include "sys/intrusive_list.hpp"
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+using namespace std;
+
+namespace gbe
+{
+  static void outputGenReg(GenRegister& reg, bool dst)
+  {
+    if (reg.file == GEN_IMMEDIATE_VALUE || reg.file == GEN_GENERAL_REGISTER_FILE) {
+      if (reg.file == GEN_IMMEDIATE_VALUE) {
+        switch (reg.type) {
+          case GEN_TYPE_UD:
+          case GEN_TYPE_UW:
+          case GEN_TYPE_UB:
+          case GEN_TYPE_HF_IMM:
+            cout << hex << "0x" << reg.value.ud  << dec;
+            break;
+          case GEN_TYPE_D:
+          case GEN_TYPE_W:
+          case GEN_TYPE_B:
+            cout << reg.value.d;
+            break;
+          case GEN_TYPE_V:
+            cout << hex << "0x" << reg.value.ud << dec;
+            break;
+          case GEN_TYPE_UL:
+            cout << reg.value.u64;
+            break;
+          case GEN_TYPE_L:
+            cout << reg.value.i64;
+            break;
+          case GEN_TYPE_F:
+            cout << reg.value.f;
+            break;
+        }
+      }else {
+        if (reg.negation)
+          cout << "-";
+        if (reg.absolute)
+          cout << "(abs)";
+        cout << "%" << reg.value.reg;
+        if (reg.subphysical)
+          cout << "." << reg.subnr;
+
+        if (dst)
+          cout << "<" << GenRegister::hstride_size(reg) << ">";
+        else
+          cout << "<" << GenRegister::vstride_size(reg) << "," << GenRegister::width_size(reg) << "," << GenRegister::hstride_size(reg) << ">";
+      }
+
+      cout << ":";
+      switch (reg.type) {
+        case GEN_TYPE_UD:
+          cout << "UD";
+          break;
+        case GEN_TYPE_UW:
+          cout << "UW";
+          break;
+        case GEN_TYPE_UB:
+          cout << "UB";
+          break;
+        case GEN_TYPE_HF_IMM:
+          cout << "HF";
+          break;
+        case GEN_TYPE_D:
+          cout << "D";
+          break;
+        case GEN_TYPE_W:
+          cout << "W";
+          break;
+        case GEN_TYPE_B:
+          cout << "B";
+          break;
+        case GEN_TYPE_V:
+          cout << "V";
+          break;
+        case GEN_TYPE_UL:
+          cout << "UL";
+          break;
+        case GEN_TYPE_L:
+          cout << "L";
+          break;
+        case GEN_TYPE_F:
+          cout << "F";
+          break;
+      }
+    } else if (reg.file == GEN_ARCHITECTURE_REGISTER_FILE) {
+      cout << setw(8) << "arf";
+    } else
+      assert(!"should not reach here");
+  }
+
+  void outputSelectionIR(GenContext &ctx, Selection* sel)
+  {
+    cout << "SELECTION IR begin:" << endl;
+    cout << "WARNING: not completed yet, welcome for the FIX!" << endl;
+    for (SelectionBlock &block : *sel->blockList) {
+      for (SelectionInstruction &insn : block.insnList) {
+        char opname[512];
+        if (insn.isLabel()) {
+            cout << "  L" << insn.index << ":" << endl;
+            continue;
+        } else {
+          switch (insn.opcode) {
+            #define DECL_SELECTION_IR(OP, FAMILY) case SEL_OP_##OP: sprintf(opname, "%s", #OP); break;
+            #include "backend/gen_insn_selection.hxx"
+            #undef DECL_SELECTION_IR
+          }
+        }
+
+        if (insn.opcode == SEL_OP_CMP) {
+          switch (insn.extra.function) {
+            case GEN_CONDITIONAL_LE:
+              strcat(opname, ".le");
+              break;
+            case GEN_CONDITIONAL_L:
+              strcat(opname, ".l");
+              break;
+            case GEN_CONDITIONAL_GE:
+              strcat(opname, ".ge");
+              break;
+            case GEN_CONDITIONAL_G:
+              strcat(opname, ".g");
+              break;
+            case GEN_CONDITIONAL_EQ:
+              strcat(opname, ".eq");
+              break;
+            case GEN_CONDITIONAL_NEQ:
+              strcat(opname, ".neq");
+              break;
+          }
+        }
+
+        int n = strlen(opname);
+        sprintf(&opname[n], "(%d)", insn.state.execWidth);
+        cout << "    " << left << setw(20) << opname;
+
+        for (int i = 0; i < insn.dstNum; ++i)
+        {
+          GenRegister dst = insn.dst(i);
+          outputGenReg(dst, true);
+          cout << "\t";
+        }
+
+        cout << ":\t";
+
+        for (int i = 0; i < insn.srcNum; ++i)
+        {
+          GenRegister src = insn.src(i);
+          outputGenReg(src, false);
+          cout << "\t";
+        }
+
+        cout << endl;
+      }
+      cout << endl;
+    }
+    cout << "SELECTION IR end." << endl << endl;
+  }
+
+}
diff --git a/backend/src/backend/gen_insn_selection_output.hpp b/backend/src/backend/gen_insn_selection_output.hpp
new file mode 100644
index 0000000..dd372dc
--- /dev/null
+++ b/backend/src/backend/gen_insn_selection_output.hpp
@@ -0,0 +1,13 @@
+#ifndef __GBE_GEN_INSN_SELECTION_OUTPUT_HPP__
+#define __GBE_GEN_INSN_SELECTION_OUTPUT_HPP__
+
+namespace gbe
+{
+  class Selection;  // Pre ISA code
+  class GenContext; // Handle compilation for Gen
+
+  void outputSelectionIR(GenContext &ctx, Selection* sel);
+
+} /* namespace gbe */
+
+#endif
diff --git a/backend/src/backend/gen_register.hpp b/backend/src/backend/gen_register.hpp
index 4f37e30..c619b10 100644
--- a/backend/src/backend/gen_register.hpp
+++ b/backend/src/backend/gen_register.hpp
@@ -937,6 +937,34 @@ namespace gbe
       }
     }
 
+    static INLINE int vstride_size(GenRegister reg) {
+      switch (reg.vstride) {
+        case GEN_VERTICAL_STRIDE_0: return 0;
+        case GEN_VERTICAL_STRIDE_1: return 1;
+        case GEN_VERTICAL_STRIDE_2: return 2;
+        case GEN_VERTICAL_STRIDE_4: return 4;
+        case GEN_VERTICAL_STRIDE_8: return 8;
+        case GEN_VERTICAL_STRIDE_16: return 16;
+        case GEN_VERTICAL_STRIDE_32: return 32;
+        case GEN_VERTICAL_STRIDE_64: return 64;
+        case GEN_VERTICAL_STRIDE_128: return 128;
+        case GEN_VERTICAL_STRIDE_256: return 256;
+        default: NOT_IMPLEMENTED; return 0;
+      }
+    }
+
+    static INLINE int width_size(GenRegister reg) {
+      switch (reg.width) {
+        case GEN_WIDTH_1: return 1;
+        case GEN_WIDTH_2: return 2;
+        case GEN_WIDTH_4: return 4;
+        case GEN_WIDTH_8: return 8;
+        case GEN_WIDTH_16: return 16;
+        case GEN_WIDTH_32: return 32;
+        default: NOT_IMPLEMENTED; return 0;
+      }
+    }
+
     static INLINE GenRegister suboffset(GenRegister reg, uint32_t delta) {
       if (reg.hstride != GEN_HORIZONTAL_STRIDE_0) {
         reg.subnr += delta * typeSize(reg.type) * hstride_size(reg);
-- 
1.9.1



More information about the Beignet mailing list