File: ConvertUserSemanticDecoratorOnFunctions.cpp

package info (click to toggle)
intel-graphics-compiler2 2.18.5-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 107,080 kB
  • sloc: cpp: 807,289; lisp: 287,855; ansic: 16,414; python: 4,004; yacc: 2,588; lex: 1,666; pascal: 313; sh: 186; makefile: 35
file content (94 lines) | stat: -rw-r--r-- 3,710 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*========================== begin_copyright_notice ============================

Copyright (C) 2021 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

#include "ConvertUserSemanticDecoratorOnFunctions.h"
#include "Compiler/IGCPassSupport.h"

#include "common/LLVMWarningsPush.hpp"
#include "llvmWrapper/IR/DerivedTypes.h"
#include "llvmWrapper/IR/Instructions.h"
#include <llvm/IR/Module.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instructions.h>
#include <llvm/Demangle/Demangle.h>
#include <llvm/IR/Mangler.h>
#include "common/LLVMWarningsPop.hpp"
using namespace llvm;
using namespace IGC;

// Register pass to igc-opt
#define PASS_FLAG "igc-convert-user-semantic-decorator-on-functions"
#define PASS_DESCRIPTION "Convert user semantic decorator on functions"
#define PASS_CFG_ONLY false
#define PASS_ANALYSIS false
IGC_INITIALIZE_PASS_BEGIN(ConvertUserSemanticDecoratorOnFunctions, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY,
                          PASS_ANALYSIS)
IGC_INITIALIZE_PASS_END(ConvertUserSemanticDecoratorOnFunctions, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY,
                        PASS_ANALYSIS)

char ConvertUserSemanticDecoratorOnFunctions::ID = 0;

ConvertUserSemanticDecoratorOnFunctions::ConvertUserSemanticDecoratorOnFunctions() : ModulePass(ID) {
  initializeConvertUserSemanticDecoratorOnFunctionsPass(*PassRegistry::getPassRegistry());
}

// Some of the metadata may disappear when linking LLVM modules; attributes are much more permament.
static void convertAnnotationsToAttributes(llvm::Function *function, const std::vector<std::string> &annotations) {
  for (const auto &annotation : annotations) {
    if (annotation == "igc-force-stackcall") {
      function->addFnAttr("igc-force-stackcall");
    } else if (annotation == "sycl-unmasked") {
      function->addFnAttr("sycl-unmasked");
    } else if (annotation.rfind("num-thread-per-eu", 0) == 0) {
      std::string numThreadPerEU = annotation;
      numThreadPerEU.erase(0, sizeof("num-thread-per-eu") - 1);

      // Remove whitespaces - if they are present
      numThreadPerEU.erase(std::remove_if(numThreadPerEU.begin(), numThreadPerEU.end(), ::isspace),
                           numThreadPerEU.end());

      function->addFnAttr("num-thread-per-eu", numThreadPerEU == "auto" ? "0" : std::move(numThreadPerEU));
    }
  }
}

bool ConvertUserSemanticDecoratorOnFunctions::runOnModule(Module &M) {
  auto MD = getAnalysis<MetaDataUtilsWrapper>().getModuleMetaData();

  auto annotations_gv = M.getGlobalVariable("llvm.global.annotations");
  if (!annotations_gv) {
    return false;
  }

  //
  // GlobalVariable("llvm.global.annotations"):
  //    ConstantArray:
  //       ConstantStruct:
  //          BitCastOperator:
  //             Function = [ANNOTATED_FUNCTION]
  //          GetElementPtr:
  //             GlobalVariable = [ANNOTATION]
  //       ConstantStruct:
  //       ...
  //

  auto annotations_array = cast<ConstantArray>(annotations_gv->getOperand(0));
  for (const auto &op : annotations_array->operands()) {
    auto annotation_struct = cast<ConstantStruct>(op.get());
    auto annotated_function = cast<Function>(annotation_struct->getOperand(0)->getOperand(0));
    auto annotation_gv = cast<GlobalVariable>(annotation_struct->getOperand(1)->getOperand(0));
    auto annotation = cast<ConstantDataArray>(annotation_gv->getInitializer())->getAsCString();

    auto &funcInfo = MD->FuncMD[annotated_function];
    funcInfo.UserAnnotations.emplace_back(annotation.data());
    convertAnnotationsToAttributes(annotated_function, funcInfo.UserAnnotations);
  }

  IGC::serialize(*MD, &M);
  return true;
}