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 <[email protected]> --- 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 _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
