From 6c8c74969a152a62ffce0f83e3a45ea54b4655b4 Mon Sep 17 00:00:00 2001 From: Nikolay Haustov Date: Wed, 2 Mar 2016 10:36:25 +0000 Subject: [PATCH] [AMDGPU] table-driven parser/printer for amd_kernel_code_t structure fields This is going to be used in .hsatext disassembler and can be used in current assembler parser (lit tests passed on parsing). Code using this helpers isn't included in this patch. Benefits: unified approach fast field name lookup on parsing Later I would like to enhance some of the field naming/syntax using this code. Patch by: Valery Pykhtin Differential Revision: http://reviews.llvm.org/D17150 llvm-svn: 262473 --- llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTInfo.h | 165 ++++++++++++++++++++ .../Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp | 166 +++++++++++++++++++++ llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.h | 38 +++++ llvm/lib/Target/AMDGPU/Utils/CMakeLists.txt | 1 + 4 files changed, 370 insertions(+) create mode 100644 llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTInfo.h create mode 100644 llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp create mode 100644 llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.h diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTInfo.h new file mode 100644 index 0000000..493ddd2 --- /dev/null +++ b/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTInfo.h @@ -0,0 +1,165 @@ +//===--------------------- AMDKernelCodeTInfo.h -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// +// +/// \file - specifies tables for amd_kernel_code_t structure parsing/printing +// +//===----------------------------------------------------------------------===// + +#define QNAME(name) amd_kernel_code_t::name +#define FLD_T(name) decltype(QNAME(name)), &QNAME(name) + +#define FIELD2(sname, name) \ + RECORD(sname, printField, parseField) + +#define FIELD(name) FIELD2(name, name) + + +#define PRINTCODEPROP(name) \ + printBitField + +#define PARSECODEPROP(name) \ + parseBitField + +#define CODEPROP(name, shift) \ + RECORD(name, PRINTCODEPROP(shift), PARSECODEPROP(shift)) + +// have to define these lambdas because of Set/GetMacro +#define PRINTCOMP(GetMacro, Shift) \ +[](StringRef Name, const amd_kernel_code_t &C, raw_ostream &OS) { \ + printName(OS, Name) << \ + (int)GetMacro(C.compute_pgm_resource_registers >> Shift); \ +} +#define PARSECOMP(SetMacro, Shift) \ +[](amd_kernel_code_t &C, MCAsmLexer &Lexer, raw_ostream &Err) { \ + if (!expectEqualInt(Lexer, Err)) \ + return false; \ + const uint64_t Value = Lexer.getTok().getIntVal(); \ + C.compute_pgm_resource_registers |= SetMacro(Value) << Shift; \ + return true; \ +} + +#define COMPPGM(name, GetMacro, SetMacro, Shift) \ + RECORD(name, PRINTCOMP(GetMacro, Shift), PARSECOMP(SetMacro, Shift)) + +#define COMPPGM1(name, AccMacro) \ + COMPPGM(compute_pgm_rsrc1_##name, \ + G_00B848_##AccMacro, S_00B848_##AccMacro, 0) + +#define COMPPGM2(name, AccMacro) \ + COMPPGM(compute_pgm_rsrc2_##name, \ + G_00B84C_##AccMacro, S_00B84C_##AccMacro, 32) + +/////////////////////////////////////////////////////////////////////////////// +// Begin of the table +// Define RECORD(name, print, parse) in your code to get field definitions +// and include this file + +FIELD2(kernel_code_version_major, amd_kernel_code_version_major), +FIELD2(kernel_code_version_minor, amd_kernel_code_version_minor), +FIELD2(machine_kind, amd_machine_kind), +FIELD2(machine_version_major, amd_machine_version_major), +FIELD2(machine_version_minor, amd_machine_version_minor), +FIELD2(machine_version_stepping, amd_machine_version_stepping), +FIELD(kernel_code_entry_byte_offset), +FIELD(kernel_code_prefetch_byte_size), +FIELD(max_scratch_backing_memory_byte_size), +FIELD(compute_pgm_resource_registers), +FIELD(workitem_private_segment_byte_size), +FIELD(workgroup_group_segment_byte_size), +FIELD(gds_segment_byte_size), +FIELD(kernarg_segment_byte_size), +FIELD(workgroup_fbarrier_count), +FIELD(wavefront_sgpr_count), +FIELD(workitem_vgpr_count), +FIELD(reserved_vgpr_first), +FIELD(reserved_vgpr_count), +FIELD(reserved_sgpr_first), +FIELD(reserved_sgpr_count), +FIELD(debug_wavefront_private_segment_offset_sgpr), +FIELD(debug_private_segment_buffer_sgpr), +FIELD(kernarg_segment_alignment), +FIELD(group_segment_alignment), +FIELD(private_segment_alignment), +FIELD(wavefront_size), +FIELD(call_convention), +FIELD(runtime_loader_kernel_symbol), + +COMPPGM1(vgprs, VGPRS), +COMPPGM1(sgprs, SGPRS), +COMPPGM1(priority, PRIORITY), +COMPPGM1(float_mode, FLOAT_MODE), +COMPPGM1(priv, PRIV), +COMPPGM1(dx10_clamp, DX10_CLAMP), +COMPPGM1(debug_mode, DEBUG_MODE), +COMPPGM1(ieee_mode, IEEE_MODE), +COMPPGM2(scratch_en, SCRATCH_EN), +COMPPGM2(user_sgpr, USER_SGPR), +COMPPGM2(tgid_x_en, TGID_X_EN), +COMPPGM2(tgid_y_en, TGID_Y_EN), +COMPPGM2(tgid_z_en, TGID_Z_EN), +COMPPGM2(tg_size_en, TG_SIZE_EN), +COMPPGM2(tidig_comp_cnt, TIDIG_COMP_CNT), +COMPPGM2(excp_en_msb, EXCP_EN_MSB), +COMPPGM2(lds_size, LDS_SIZE), +COMPPGM2(excp_en, EXCP_EN), + +CODEPROP(enable_sgpr_private_segment_buffer, + ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER), +CODEPROP(enable_sgpr_dispatch_ptr, + ENABLE_SGPR_DISPATCH_PTR), +CODEPROP(enable_sgpr_queue_ptr, + ENABLE_SGPR_QUEUE_PTR), +CODEPROP(enable_sgpr_kernarg_segment_ptr, + ENABLE_SGPR_KERNARG_SEGMENT_PTR), +CODEPROP(enable_sgpr_dispatch_id, + ENABLE_SGPR_DISPATCH_ID), +CODEPROP(enable_sgpr_flat_scratch_init, + ENABLE_SGPR_FLAT_SCRATCH_INIT), +CODEPROP(enable_sgpr_private_segment_size, + ENABLE_SGPR_PRIVATE_SEGMENT_SIZE), +CODEPROP(enable_sgpr_grid_workgroup_count_x, + ENABLE_SGPR_GRID_WORKGROUP_COUNT_X), +CODEPROP(enable_sgpr_grid_workgroup_count_y, + ENABLE_SGPR_GRID_WORKGROUP_COUNT_Y), +CODEPROP(enable_sgpr_grid_workgroup_count_z, + ENABLE_SGPR_GRID_WORKGROUP_COUNT_Z), +CODEPROP(enable_ordered_append_gds, + ENABLE_ORDERED_APPEND_GDS), +CODEPROP(private_element_size, + PRIVATE_ELEMENT_SIZE), +CODEPROP(is_ptr64, + IS_PTR64), +CODEPROP(is_dynamic_callstack, + IS_DYNAMIC_CALLSTACK), +CODEPROP(is_debug_enabled, + IS_DEBUG_SUPPORTED), +CODEPROP(is_xnack_enabled, + IS_XNACK_SUPPORTED) + +// end of the table +/////////////////////////////////////////////////////////////////////////////// + +#undef QNAME +#undef FLD_T +#undef FIELD2 +#undef FIELD +#undef PRINTCODEPROP +#undef PARSECODEPROP +#undef CODEPROP +#undef PRINTCOMP +#undef PAPSECOMP +#undef COMPPGM +#undef COMPPGM1 +#undef COMPPGM2 diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp new file mode 100644 index 0000000..a826f15 --- /dev/null +++ b/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp @@ -0,0 +1,166 @@ +//===-------------------- AMDKernelCodeTUtils.cpp -------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// +// +/// \file - utility functions to parse/print amd_kernel_code_t structure +// +//===----------------------------------------------------------------------===// + +#include "AMDKernelCodeT.h" +#include "AMDKernelCodeTUtils.h" +#include "SIDefines.h" +#include +#include + +using namespace llvm; + +static ArrayRef get_amd_kernel_code_t_FldNames() { + static StringRef const Table[] = { + "", // not found placeholder +#define RECORD(name, print, parse) #name +#include "AMDKernelCodeTInfo.h" +#undef RECORD + }; + return Table; +} + +static StringMap createIndexMap(const ArrayRef &a) { + StringMap map; + for (auto Name : a) + map.insert(std::make_pair(Name, map.size())); + return std::move(map); +} + +static int get_amd_kernel_code_t_FieldIndex(StringRef name) { + static const auto map = createIndexMap(get_amd_kernel_code_t_FldNames()); + return map.lookup(name) - 1; // returns -1 if not found +} + +static StringRef get_amd_kernel_code_t_FieldName(int index) { + return get_amd_kernel_code_t_FldNames()[index + 1]; +} + + +// Field printing + +raw_ostream& printName(raw_ostream &OS, StringRef Name) { + return OS << Name << " = "; +} + +template +void printField(StringRef Name, + const amd_kernel_code_t &C, + raw_ostream &OS) { + printName(OS, Name) << (int)(C.*ptr); +} + +template +void printBitField(StringRef Name, + const amd_kernel_code_t &c, + raw_ostream &OS) { + const auto Mask = (static_cast(1) << width) - 1; + printName(OS, Name) << (int)((c.*ptr >> shift) & Mask); +} + +typedef void(*PrintFx)(StringRef, + const amd_kernel_code_t&, + raw_ostream&); + +static ArrayRef getPrinterTable() { + static const PrintFx table[] = { +#define RECORD(name, print, parse) print +#include "AMDKernelCodeTInfo.h" +#undef RECORD + }; + return table; +} + +void llvm::printAmdKernelCodeField(const amd_kernel_code_t &C, + int FldIndex, + raw_ostream &OS) { + auto Printer = getPrinterTable()[FldIndex]; + if (Printer) + Printer(get_amd_kernel_code_t_FieldName(FldIndex), C, OS); +} + +void llvm::dumpAmdKernelCode(const amd_kernel_code_t *C, + raw_ostream &OS, + const char *tab) { + const int Size = getPrinterTable().size(); + for (int i = 0; i < Size; ++i) { + OS << tab; + printAmdKernelCodeField(*C, i, OS); + OS << '\n'; + } +} + + +// Field parsing + +static bool expectEqualInt(MCAsmLexer &Lexer, raw_ostream &Err) { + if (Lexer.isNot(AsmToken::Equal)) { + Err << "expected '='"; + return false; + } + Lexer.Lex(); + if (Lexer.isNot(AsmToken::Integer)) { + Err << "integer literal expected"; + return false; + } + return true; +} + +template +bool parseField(amd_kernel_code_t &C, + MCAsmLexer &Lexer, + raw_ostream &Err) { + if (!expectEqualInt(Lexer, Err)) + return false; + C.*ptr = (T)Lexer.getTok().getIntVal(); + return true; +} + +template +bool parseBitField(amd_kernel_code_t &C, + MCAsmLexer &Lexer, + raw_ostream &Err) { + if (!expectEqualInt(Lexer, Err)) + return false; + const uint64_t Mask = ((UINT64_C(1) << width) - 1) << shift; + C.*ptr &= (T)~Mask; + C.*ptr |= (T)((Lexer.getTok().getIntVal() << shift) & Mask); + return true; +} + +typedef bool(*ParseFx)(amd_kernel_code_t&, + MCAsmLexer&, + raw_ostream&); + +static ArrayRef getParserTable() { + static const ParseFx table[] = { +#define RECORD(name, print, parse) parse +#include "AMDKernelCodeTInfo.h" +#undef RECORD + }; + return table; +} + +bool llvm::parseAmdKernelCodeField(StringRef ID, + MCAsmLexer &Lexer, + amd_kernel_code_t &C, + raw_ostream &Err) { + const int Idx = get_amd_kernel_code_t_FieldIndex(ID); + if (Idx < 0) { + Err << "unexpected amd_kernel_code_t field name " << ID; + return false; + } + auto Parser = getParserTable()[Idx]; + return Parser ? Parser(C, Lexer, Err) : false; +} diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.h b/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.h new file mode 100644 index 0000000..b053e83 --- /dev/null +++ b/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.h @@ -0,0 +1,38 @@ +//===- AMDGPUKernelCodeTUtils.h - helpers for amd_kernel_code_t *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file AMDKernelCodeTUtils.h +//===----------------------------------------------------------------------===// + +#ifndef AMDKERNELCODETUTILS_H +#define AMDKERNELCODETUTILS_H + +typedef struct amd_kernel_code_s amd_kernel_code_t; + +namespace llvm { + +class MCAsmLexer; +class raw_ostream; +class StringRef; + +void printAmdKernelCodeField(const amd_kernel_code_t &C, + int FldIndex, + raw_ostream &OS); + +void dumpAmdKernelCode(const amd_kernel_code_t *C, + raw_ostream &OS, + const char *tab); + +bool parseAmdKernelCodeField(StringRef ID, + MCAsmLexer &Lexer, + amd_kernel_code_t &C, + raw_ostream &Err); + +} + +#endif // AMDKERNELCODETUTILS_H diff --git a/llvm/lib/Target/AMDGPU/Utils/CMakeLists.txt b/llvm/lib/Target/AMDGPU/Utils/CMakeLists.txt index 2c07aea..119403d 100644 --- a/llvm/lib/Target/AMDGPU/Utils/CMakeLists.txt +++ b/llvm/lib/Target/AMDGPU/Utils/CMakeLists.txt @@ -1,3 +1,4 @@ add_llvm_library(LLVMAMDGPUUtils AMDGPUBaseInfo.cpp + AMDKernelCodeTUtils.cpp ) -- 2.7.4