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;
}
|