40 #include "llvm/ADT/SmallPtrSet.h"
41 #include "llvm/IR/Function.h"
42 #include "llvm/IR/Instructions.h"
43 #include "llvm/IR/IRBuilder.h"
44 #include "llvm/IR/Module.h"
45 #include "llvm/Support/InstIterator.h"
55 char FnCalleeInstrumenter::ID = 0;
57 FnCalleeInstrumenter::~FnCalleeInstrumenter() {
58 google::protobuf::ShutdownProtobufLibrary();
61 bool FnCalleeInstrumenter::runOnModule(Module &Mod) {
62 bool ModifiedIR =
false;
64 for (
auto i : M.RootAutomata()) {
65 auto& A = *M.FindAutomaton(i->identifier());
66 for (
auto EquivClass : A) {
67 assert(!EquivClass.empty());
69 auto *Head = dyn_cast<
FnTransition>(*EquivClass.begin());
73 auto& FnEvent = Head->
FnEvent();
74 if (FnEvent.context() != FunctionEvent::Callee)
77 Function *Target = Mod.getFunction(FnEvent.function().name());
80 if (!Target || Target->empty())
83 GetOrCreateInstr(Mod, Target, FnEvent.direction())
84 ->AppendInstrumentation(A, FnEvent, EquivClass);
94 CalleeInstr* FnCalleeInstrumenter::GetOrCreateInstr(
98 StringRef Name = F->getName();
100 auto& Map = (Dir == FunctionEvent::Entry) ? Entry : Exit;
103 Instr = Map[Name] = CalleeInstr::Build(M, F, Dir, SuppressDebugInstr);
113 bool SuppressDebugInstr) {
119 FunctionEvent::Callee,
127 for (
auto &Arg : Target->getArgumentList())
128 Args.push_back(&Arg);
132 case FunctionEvent::Entry: {
135 BasicBlock& Entry = Target->getEntryBlock();
136 CallInst::Create(InstrFn, Args)->insertBefore(Entry.getFirstNonPHI());
140 case FunctionEvent::Exit: {
141 SmallPtrSet<ReturnInst*, 16> Returns;
142 for (
auto i = inst_begin(Target), End = inst_end(Target); i != End; i++)
143 if (
auto *Return = dyn_cast<ReturnInst>(&*i))
144 Returns.insert(Return);
146 for (ReturnInst *Return : Returns) {
149 if (Dir == FunctionEvent::Exit && !Target->getReturnType()->isVoidTy())
150 InstrArgs.push_back(Return->getReturnValue());
152 CallInst::Create(InstrFn, InstrArgs)->insertBefore(Return);
162 CalleeInstr::CalleeInstr(Module& M, Function *Target, Function *InstrFn,
167 assert(InstrFn != NULL);
173 for (
auto &Arg : Target->getArgumentList())
174 Args.push_back(&Arg);