LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU/Utils - AMDKernelCodeTUtils.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 420 426 98.6 %
Date: 2018-10-20 13:21:21 Functions: 96 96 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      139877 : 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      139877 :   };
      35      139877 :   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           5 :   };
      45           5 :   return makeArrayRef(Table);
      46             : }
      47             : 
      48           5 : static StringMap<int> createIndexMap(const ArrayRef<StringRef> &names,
      49             :                                      const ArrayRef<StringRef> &altNames) {
      50             :   StringMap<int> map;
      51             :   assert(names.size() == altNames.size());
      52         320 :   for (unsigned i = 0; i < names.size(); ++i) {
      53         315 :     map.insert(std::make_pair(names[i], i));
      54         315 :     map.insert(std::make_pair(altNames[i], i));
      55             :   }
      56           5 :   return map;
      57             : }
      58             : 
      59         280 : static int get_amd_kernel_code_t_FieldIndex(StringRef name) {
      60           5 :   static const auto map = createIndexMap(get_amd_kernel_code_t_FldNames(),
      61         285 :                                          get_amd_kernel_code_t_FldAltNames());
      62         280 :   return map.lookup(name) - 1; // returns -1 if not found
      63             : }
      64             : 
      65             : static StringRef get_amd_kernel_code_t_FieldName(int index) {
      66      139872 :   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       97008 :   return OS << Name << " = ";
      73             : }
      74             : 
      75             : template <typename T, T amd_kernel_code_t::*ptr>
      76       60912 : static void printField(StringRef Name, const amd_kernel_code_t &C,
      77             :                        raw_ostream &OS) {
      78       60912 :   printName(OS, Name) << (int)(C.*ptr);
      79       60912 : }
      80        2256 : 
      81             : template <typename T, T amd_kernel_code_t::*ptr, int shift, int width = 1>
      82        2256 : static void printBitField(StringRef Name, const amd_kernel_code_t &c,
      83        2256 :                           raw_ostream &OS) {
      84        2256 :   const auto Mask = (static_cast<T>(1) << width) - 1;
      85             :   printName(OS, Name) << (int)((c.*ptr >> shift) & Mask);
      86        2256 : }
      87        2256 : 
      88        2256 : using PrintFx = void(*)(StringRef, const amd_kernel_code_t &, raw_ostream &);
      89             : 
      90        2256 : static ArrayRef<PrintFx> getPrinterTable() {
      91        2256 :   static const PrintFx Table[] = {
      92        2256 : #define RECORD(name, altName, print, parse) print
      93             : #include "AMDKernelCodeTInfo.h"
      94        2256 : #undef RECORD
      95        2256 :   };
      96        2256 :   return makeArrayRef(Table);
      97             : }
      98        2256 : 
      99        2256 : void llvm::printAmdKernelCodeField(const amd_kernel_code_t &C,
     100        2256 :                                    int FldIndex,
     101             :                                    raw_ostream &OS) {
     102        2256 :   auto Printer = getPrinterTable()[FldIndex];
     103        2256 :   if (Printer)
     104        2256 :     Printer(get_amd_kernel_code_t_FieldName(FldIndex), C, OS);
     105             : }
     106        2256 : 
     107        2256 : void llvm::dumpAmdKernelCode(const amd_kernel_code_t *C,
     108        2256 :                              raw_ostream &OS,
     109             :                              const char *tab) {
     110        2256 :   const int Size = getPrinterTable().size();
     111        2256 :   for (int i = 0; i < Size; ++i) {
     112        2256 :     OS << tab;
     113             :     printAmdKernelCodeField(*C, i, OS);
     114        2256 :     OS << '\n';
     115        2256 :   }
     116        2256 : }
     117             : 
     118        2256 : // Field parsing
     119        2256 : 
     120        2256 : static bool expectAbsExpression(MCAsmParser &MCParser, int64_t &Value, raw_ostream& Err) {
     121             : 
     122        2256 :   if (MCParser.getLexer().isNot(AsmToken::Equal)) {
     123        2256 :     Err << "expected '='";
     124        2256 :     return false;
     125             :   }
     126        2256 :   MCParser.getLexer().Lex();
     127        2256 : 
     128        2256 :   if (MCParser.parseAbsoluteExpression(Value)) {
     129             :     Err << "integer absolute expression expected";
     130        2256 :     return false;
     131        2256 :   }
     132        2256 :   return true;
     133             : }
     134        2256 : 
     135        2256 : template <typename T, T amd_kernel_code_t::*ptr>
     136        2256 : static bool parseField(amd_kernel_code_t &C, MCAsmParser &MCParser,
     137             :                        raw_ostream &Err) {
     138        2256 :   int64_t Value = 0;
     139        2256 :   if (!expectAbsExpression(MCParser, Value, Err))
     140        2256 :     return false;
     141             :   C.*ptr = (T)Value;
     142        2256 :   return true;
     143        2256 : }
     144        2256 : 
     145             : template <typename T, T amd_kernel_code_t::*ptr, int shift, int width = 1>
     146        2256 : static bool parseBitField(amd_kernel_code_t &C, MCAsmParser &MCParser,
     147        2256 :                           raw_ostream &Err) {
     148        2256 :   int64_t Value = 0;
     149             :   if (!expectAbsExpression(MCParser, Value, Err))
     150        2256 :     return false;
     151        2256 :   const uint64_t Mask = ((UINT64_C(1)  << width) - 1) << shift;
     152        2256 :   C.*ptr &= (T)~Mask;
     153             :   C.*ptr |= (T)((Value << shift) & Mask);
     154        2256 :   return true;
     155        2256 : }
     156        2256 : 
     157             : using ParseFx = bool(*)(amd_kernel_code_t &, MCAsmParser &MCParser,
     158        2256 :                         raw_ostream &Err);
     159        2256 : 
     160        2256 : static ArrayRef<ParseFx> getParserTable() {
     161             :   static const ParseFx Table[] = {
     162        2256 : #define RECORD(name, altName, print, parse) parse
     163        2256 : #include "AMDKernelCodeTInfo.h"
     164        2256 : #undef RECORD
     165             :   };
     166        2256 :   return makeArrayRef(Table);
     167        2256 : }
     168        2256 : 
     169             : bool llvm::parseAmdKernelCodeField(StringRef ID,
     170        2256 :                                    MCAsmParser &MCParser,
     171        2256 :                                    amd_kernel_code_t &C,
     172        2256 :                                    raw_ostream &Err) {
     173             :   const int Idx = get_amd_kernel_code_t_FieldIndex(ID);
     174        2256 :   if (Idx < 0) {
     175        2256 :     Err << "unexpected amd_kernel_code_t field name " << ID;
     176        2256 :     return false;
     177             :   }
     178        2256 :   auto Parser = getParserTable()[Idx];
     179        2256 :   return Parser ? Parser(C, MCParser, Err) : false;
     180        2256 : }

Generated by: LCOV version 1.13