[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