We can inject function call in LLVM IR by add new FunctionPass like the follow
struct FunTime : public FunctionPass{
static char ID;
FunTime() : FunctionPass(ID){}
bool runOnFunction(Function &F) override{
if (F.getName().startswith("_ly_fun")) {
return false;
}
LLVMContext &context = F.getParent()->getContext();
BasicBlock &bb = F.getEntryBlock();
Instruction *beginInst = dyn_cast<Instruction>(bb.begin());
FunctionType *type = FunctionType::get(Type::getInt64Ty(context), {}, false);
Constant *beginFun = F.getParent()->getOrInsertFunction("_ly_fun_b", type);
Value *beginTime = nullptr;
if (Function *fun = dyn_cast<Function>(beginFun)) {
CallInst *inst = CallInst::Create(fun);
inst->insertBefore(beginInst);
beginTime = inst;
}
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
BasicBlock &BB = *I;
for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I){
ReturnInst *IST = dyn_cast<ReturnInst>(I);
if (IST){
FunctionType *type = FunctionType::get(Type::getVoidTy(context), {Type::getInt8PtrTy(context),Type::getInt64Ty(context)}, false);
Constant *s = BB.getModule()->getOrInsertFunction("_ly_fun_e", type);
if (Function *fun = dyn_cast<Function>(s)) {
IRBuilder<> builder(&BB);
CallInst *inst = CallInst::Create(fun, {builder.CreateGlobalStringPtr(BB.getParent()->getName()), beginTime});
inst->insertBefore(IST);
}
}
}
}
return false;
}
But how to inject function call in SIL by add new SIL Pass? Does the follow way is right? And I don't know how to continue.
class SwiftRoyOptimizer: public SILFunctionTransform {
public:
void run() override {
auto *F = getFunction();
auto *Mod = getIRGenModule();
SILBasicBlock &bb = *F->getEntryBlock();
SILInstruction *beginInst = dyn_cast<SILInstruction>(bb.begin());
}
};
}