38 #include "llvm/IR/Instructions.h"
39 #include "llvm/IR/IRBuilder.h"
40 #include "llvm/IR/Module.h"
42 #include "llvm/Support/raw_ostream.h"
51 char FnCallerInstrumenter::ID = 0;
53 FnCallerInstrumenter::~FnCallerInstrumenter() {
54 ::google::protobuf::ShutdownProtobufLibrary();
57 bool FnCallerInstrumenter::doInitialization(Module &Mod) {
58 bool ModifiedIR =
true;
60 for (
auto i : M.RootAutomata()) {
61 auto& A = *M.FindAutomaton(i->identifier());
62 for (
auto EquivClass : A) {
63 assert(!EquivClass.empty());
65 auto *Head = dyn_cast<
FnTransition>(*EquivClass.begin());
69 auto& FnEvent = Head->
FnEvent();
70 if (FnEvent.context() != FunctionEvent::Caller)
73 Function *Target = Mod.getFunction(FnEvent.function().name());
77 GetOrCreateInstr(Mod, Target, FnEvent.direction())
78 ->AppendInstrumentation(A, FnEvent, EquivClass);
92 StringRef Name = F->getName();
94 auto& Map = (Dir == FunctionEvent::Entry) ? Calls : Returns;
97 Instr = Map[Name] = CallerInstrumentation::Build(M, F, Dir,
104 bool FnCallerInstrumenter::runOnFunction(Function &Fn) {
105 bool modifiedIR =
false;
107 for (
auto &Block : Fn) {
108 modifiedIR |= runOnBasicBlock(Block);
114 bool FnCallerInstrumenter::runOnBasicBlock(BasicBlock &Block) {
115 bool ModifiedIR =
false;
117 for (
auto &Inst : Block) {
118 if (!isa<CallInst>(Inst))
continue;
119 CallInst &Call = cast<CallInst>(Inst);
120 Function *Callee = Call.getCalledFunction();
126 StringRef Name = Callee->getName();
127 if (
auto Instr = Calls.lookup(Name))
130 if (
auto Instr = Returns.lookup(Name))
140 CallerInstrumentation::Build(Module& M, Function *Target,
142 bool SuppressDebugInstr) {
144 assert(Target != NULL);
147 FunctionEvent::Caller,
154 bool CallerInstrumentation::Instrument(Instruction &Inst) {
155 assert(isa<CallInst>(Inst));
156 CallInst &Call = cast<CallInst>(Inst);
159 for (
size_t i = 0; i < Call.getNumArgOperands(); i++)
160 Args.push_back(Call.getArgOperand(i));
163 case FunctionEvent::Entry:
164 CallInst::Create(InstrFn, Args)->insertBefore(&Inst);
167 case FunctionEvent::Exit:
168 if (!Call.getType()->isVoidTy())
169 Args.push_back(&Call);
171 CallInst::Create(InstrFn, Args)->insertAfter(&Inst);