MCPcopy Create free account
hub / github.com/banach-space/llvm-tutor / runOnModule

Method runOnModule

lib/DynamicCallCounter.cpp:76–214  ·  view source on GitHub ↗

----------------------------------------------------------------------------- DynamicCallCounter implementation -----------------------------------------------------------------------------

Source from the content-addressed store, hash-verified

74// DynamicCallCounter implementation
75//-----------------------------------------------------------------------------
76bool DynamicCallCounter::runOnModule(Module &M) {
77 bool Instrumented = false;
78
79 // Function name <--> IR variable that holds the call counter
80 llvm::StringMap<Constant *> CallCounterMap;
81 // Function name <--> IR variable that holds the function name
82 llvm::StringMap<Constant *> FuncNameMap;
83
84 auto &CTX = M.getContext();
85
86 // STEP 1: For each function in the module, inject a call-counting code
87 // --------------------------------------------------------------------
88 for (auto &F : M) {
89 if (F.isDeclaration())
90 continue;
91
92 // Get an IR builder. Sets the insertion point to the top of the function
93 IRBuilder<> Builder(&*F.getEntryBlock().getFirstInsertionPt());
94
95 // Create a global variable to count the calls to this function
96 std::string CounterName = "CounterFor_" + std::string(F.getName());
97 Constant *Var = CreateGlobalCounter(M, CounterName);
98 CallCounterMap[F.getName()] = Var;
99
100 // Create a global variable to hold the name of this function
101 auto FuncName = Builder.CreateGlobalString(F.getName());
102 FuncNameMap[F.getName()] = FuncName;
103
104 // Inject instruction to increment the call count each time this function
105 // executes
106 LoadInst *Load2 = Builder.CreateLoad(IntegerType::getInt32Ty(CTX), Var);
107 Value *Inc2 = Builder.CreateAdd(Builder.getInt32(1), Load2);
108 Builder.CreateStore(Inc2, Var);
109
110 // The following is visible only if you pass -debug on the command line
111 // *and* you have an assert build.
112 LLVM_DEBUG(dbgs() << " Instrumented: " << F.getName() << "\n");
113
114 Instrumented = true;
115 }
116
117 // Stop here if there are no function definitions in this module
118 if (false == Instrumented)
119 return Instrumented;
120
121 // STEP 2: Inject the declaration of printf
122 // ----------------------------------------
123 // Create (or _get_ in cases where it's already available) the following
124 // declaration in the IR module:
125 // declare i32 @printf(i8*, ...)
126 // It corresponds to the following C declaration:
127 // int printf(char *, ...)
128 PointerType *PrintfArgTy = PointerType::getUnqual(Type::getInt8Ty(CTX));
129 FunctionType *PrintfTy =
130 FunctionType::get(IntegerType::getInt32Ty(CTX), PrintfArgTy,
131 /*IsVarArgs=*/true);
132
133 FunctionCallee Printf = M.getOrInsertFunction("printf", PrintfTy);

Callers

nothing calls this directly

Calls 1

CreateGlobalCounterFunction · 0.85

Tested by

no test coverage detected