File: GenXFixInvalidFuncName.cpp

package info (click to toggle)
intel-graphics-compiler 1.0.12504.6-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 83,912 kB
  • sloc: cpp: 910,147; lisp: 202,655; ansic: 15,197; python: 4,025; yacc: 2,241; lex: 1,570; pascal: 244; sh: 104; makefile: 25
file content (95 lines) | stat: -rw-r--r-- 3,166 bytes parent folder | download | duplicates (2)
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
95
/*========================== begin_copyright_notice ============================

Copyright (C) 2022 Intel Corporation

SPDX-License-Identifier: MIT

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

//
/// GenXFixInvalidFuncName
/// ------------
///
/// GenXFixInvalidFuncName is a function pass that replaces all '.' and '$'
/// characters with '_' in function names generated by llvm in all call
/// instructions in the current function and in the name of the current function.
/// It needs to be kept in sync with the same pass on the SPMD side.
///
//===----------------------------------------------------------------------===//

#include "GenX.h"

#include "llvm/IR/Function.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"

#define DEBUG_TYPE "GENX_FIX_INVALID_FUNC_NAMES"

using namespace llvm;

class GenXFixInvalidFuncName : public FunctionPass
{
public:
  static char ID;
  explicit GenXFixInvalidFuncName() : FunctionPass(ID) {}
  llvm::StringRef getPassName() const override { return "Fix Invalid Func Name"; }
  bool runOnFunction(Function& F) override;
private:
  std::string replaceInvalidCharToUnderline(std::string str);
  bool isSupportedCallingConv(CallingConv::ID callingConv);
  bool changeFuncName(Function& F);
};

bool GenXFixInvalidFuncName::runOnFunction(Function& F) {
  bool modified = false;
  if(isSupportedCallingConv(F.getCallingConv())) {
    modified = changeFuncName(F);
  }
  for (Function::iterator fi = F.begin(), fe = F.end(); fi != fe; ++fi) {
    BasicBlock *BB = &*fi;
    for (BasicBlock::iterator bi = BB->begin(), be = BB->end(); bi != be; ++bi) {
      Instruction *Inst = &*bi;
      if (CallInst* callInst = dyn_cast<CallInst>(Inst)) {
        if (isSupportedCallingConv(callInst->getCallingConv())) {
          Function* func = callInst->getCalledFunction();
          if (func) {
            modified = changeFuncName(*func);
          }
        }
      }
    }
  }
  return modified;
}

std::string GenXFixInvalidFuncName::replaceInvalidCharToUnderline(std::string str) {
  std::replace_if(str.begin(), str.end(), [](const char c){ return c == '.' || c == '$'; }, '_');
  return str;
}

bool GenXFixInvalidFuncName::isSupportedCallingConv(CallingConv::ID callingConv) {
  return callingConv == CallingConv::SPIR_FUNC;
}

bool GenXFixInvalidFuncName::changeFuncName(Function& F) {
  bool isNameChanged = false;
  std::string original = F.getName().str();
  std::string changed  = replaceInvalidCharToUnderline(original);
  if (original != changed) {
    F.setName(changed);
    isNameChanged = true;
  }
  return isNameChanged;
}

char GenXFixInvalidFuncName::ID = 0;
namespace llvm {
void initializeGenXFixInvalidFuncNamePass(PassRegistry &);
}
INITIALIZE_PASS_BEGIN(GenXFixInvalidFuncName, "GenXFixInvalidFuncName", "GenXFixInvalidFuncName", false, false)
INITIALIZE_PASS_END(GenXFixInvalidFuncName, "GenXFixInvalidFuncName", "GenXFixInvalidFuncName", false, false)
FunctionPass *llvm::createGenXFixInvalidFuncNamePass() {
  initializeGenXFixInvalidFuncNamePass(*PassRegistry::getPassRegistry());
  return new GenXFixInvalidFuncName;
}