LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU/Utils - AMDKernelCodeTUtils.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 64 70 91.4 %
Date: 2017-09-14 15:23:50 Functions: 98 98 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- AMDKernelCodeTUtils.cpp --------------------------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : /// \file - utility functions to parse/print amd_kernel_code_t structure
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "AMDKernelCodeTUtils.h"
      15             : #include "SIDefines.h"
      16             : #include "llvm/ADT/ArrayRef.h"
      17             : #include "llvm/ADT/StringMap.h"
      18             : #include "llvm/ADT/StringRef.h"
      19             : #include "llvm/MC/MCParser/MCAsmLexer.h"
      20             : #include "llvm/MC/MCParser/MCAsmParser.h"
      21             : #include "llvm/Support/raw_ostream.h"
      22             : #include <cassert>
      23             : #include <cstdint>
      24             : #include <utility>
      25             : 
      26             : using namespace llvm;
      27             : 
      28       97025 : static ArrayRef<StringRef> get_amd_kernel_code_t_FldNames() {
      29             :   static StringRef const Table[] = {
      30             :     "", // not found placeholder
      31             : #define RECORD(name, altName, print, parse) #name
      32             : #include "AMDKernelCodeTInfo.h"
      33             : #undef RECORD
      34      109441 :   };
      35       97025 :   return makeArrayRef(Table);
      36             : }
      37             : 
      38           5 : static ArrayRef<StringRef> get_amd_kernel_code_t_FldAltNames() {
      39             :   static StringRef const Table[] = {
      40             :     "", // not found placeholder
      41             : #define RECORD(name, altName, print, parse) #altName
      42             : #include "AMDKernelCodeTInfo.h"
      43             : #undef RECORD
      44         325 :   };
      45           5 :   return makeArrayRef(Table);
      46             : }
      47             : 
      48           5 : static StringMap<int> createIndexMap(const ArrayRef<StringRef> &names,
      49             :                                      const ArrayRef<StringRef> &altNames) {
      50           5 :   StringMap<int> map;
      51             :   assert(names.size() == altNames.size());
      52         325 :   for (unsigned i = 0; i < names.size(); ++i) {
      53        1600 :     map.insert(std::make_pair(names[i], i));
      54        1600 :     map.insert(std::make_pair(altNames[i], i));
      55             :   }
      56           5 :   return map;
      57             : }
      58             : 
      59         284 : static int get_amd_kernel_code_t_FieldIndex(StringRef name) {
      60          10 :   static const auto map = createIndexMap(get_amd_kernel_code_t_FldNames(),
      61         294 :                                          get_amd_kernel_code_t_FldAltNames());
      62         284 :   return map.lookup(name) - 1; // returns -1 if not found
      63             : }
      64             : 
      65             : static StringRef get_amd_kernel_code_t_FieldName(int index) {
      66      194040 :   return get_amd_kernel_code_t_FldNames()[index + 1];
      67             : }
      68             : 
      69             : // Field printing
      70             : 
      71             : static raw_ostream &printName(raw_ostream &OS, StringRef Name) {
      72       97020 :   return OS << Name << " = ";
      73             : }
      74             : 
      75             : template <typename T, T amd_kernel_code_t::*ptr>
      76       43120 : static void printField(StringRef Name, const amd_kernel_code_t &C,
      77             :                        raw_ostream &OS) {
      78       86240 :   printName(OS, Name) << (int)(C.*ptr);
      79       43120 : }
      80             : 
      81             : template <typename T, T amd_kernel_code_t::*ptr, int shift, int width = 1>
      82       24640 : static void printBitField(StringRef Name, const amd_kernel_code_t &c,
      83             :                           raw_ostream &OS) {
      84       24640 :   const auto Mask = (static_cast<T>(1) << width) - 1;
      85       49280 :   printName(OS, Name) << (int)((c.*ptr >> shift) & Mask);
      86       24640 : }
      87             : 
      88             : using PrintFx = void(*)(StringRef, const amd_kernel_code_t &, raw_ostream &);
      89             : 
      90       98560 : static ArrayRef<PrintFx> getPrinterTable() {
      91             :   static const PrintFx Table[] = {
      92             : #define RECORD(name, altName, print, parse) print
      93             : #include "AMDKernelCodeTInfo.h"
      94             : #undef RECORD
      95       98560 :   };
      96       98560 :   return makeArrayRef(Table);
      97             : }
      98             : 
      99       97020 : void llvm::printAmdKernelCodeField(const amd_kernel_code_t &C,
     100             :                                    int FldIndex,
     101             :                                    raw_ostream &OS) {
     102      194040 :   auto Printer = getPrinterTable()[FldIndex];
     103       97020 :   if (Printer)
     104       97020 :     Printer(get_amd_kernel_code_t_FieldName(FldIndex), C, OS);
     105       97020 : }
     106             : 
     107        1540 : void llvm::dumpAmdKernelCode(const amd_kernel_code_t *C,
     108             :                              raw_ostream &OS,
     109             :                              const char *tab) {
     110        1540 :   const int Size = getPrinterTable().size();
     111       98560 :   for (int i = 0; i < Size; ++i) {
     112       97020 :     OS << tab;
     113       97020 :     printAmdKernelCodeField(*C, i, OS);
     114       97020 :     OS << '\n';
     115             :   }
     116        1540 : }
     117             : 
     118             : // Field parsing
     119             : 
     120         284 : static bool expectAbsExpression(MCAsmParser &MCParser, int64_t &Value, raw_ostream& Err) {
     121             : 
     122         568 :   if (MCParser.getLexer().isNot(AsmToken::Equal)) {
     123           0 :     Err << "expected '='";
     124           0 :     return false;
     125             :   }
     126         284 :   MCParser.getLexer().Lex();
     127             : 
     128         284 :   if (MCParser.parseAbsoluteExpression(Value)) {
     129           0 :     Err << "integer absolute expression expected";
     130           0 :     return false;
     131             :   }
     132             :   return true;
     133             : }
     134             : 
     135             : template <typename T, T amd_kernel_code_t::*ptr>
     136         126 : static bool parseField(amd_kernel_code_t &C, MCAsmParser &MCParser,
     137             :                        raw_ostream &Err) {
     138         126 :   int64_t Value = 0;
     139         126 :   if (!expectAbsExpression(MCParser, Value, Err))
     140             :     return false;
     141         126 :   C.*ptr = (T)Value;
     142         126 :   return true;
     143             : }
     144             : 
     145             : template <typename T, T amd_kernel_code_t::*ptr, int shift, int width = 1>
     146          72 : static bool parseBitField(amd_kernel_code_t &C, MCAsmParser &MCParser,
     147             :                           raw_ostream &Err) {
     148          72 :   int64_t Value = 0;
     149          72 :   if (!expectAbsExpression(MCParser, Value, Err))
     150             :     return false;
     151          72 :   const uint64_t Mask = ((UINT64_C(1)  << width) - 1) << shift;
     152          72 :   C.*ptr &= (T)~Mask;
     153          72 :   C.*ptr |= (T)((Value << shift) & Mask);
     154          72 :   return true;
     155             : }
     156             : 
     157             : using ParseFx = bool(*)(amd_kernel_code_t &, MCAsmParser &MCParser,
     158             :                         raw_ostream &Err);
     159             : 
     160         284 : static ArrayRef<ParseFx> getParserTable() {
     161             :   static const ParseFx Table[] = {
     162             : #define RECORD(name, altName, print, parse) parse
     163             : #include "AMDKernelCodeTInfo.h"
     164             : #undef RECORD
     165         284 :   };
     166         284 :   return makeArrayRef(Table);
     167             : }
     168             : 
     169         284 : bool llvm::parseAmdKernelCodeField(StringRef ID,
     170             :                                    MCAsmParser &MCParser,
     171             :                                    amd_kernel_code_t &C,
     172             :                                    raw_ostream &Err) {
     173         284 :   const int Idx = get_amd_kernel_code_t_FieldIndex(ID);
     174         284 :   if (Idx < 0) {
     175           0 :     Err << "unexpected amd_kernel_code_t field name " << ID;
     176           0 :     return false;
     177             :   }
     178         568 :   auto Parser = getParserTable()[Idx];
     179         284 :   return Parser ? Parser(C, MCParser, Err) : false;
     180             : }

Generated by: LCOV version 1.13