Bug Summary

File:polly/lib/CodeGen/PerfMonitor.cpp
Warning:line 55, column 3
Value stored to 'GV' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name PerfMonitor.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-11/lib/clang/11.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/polly/lib -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -Wno-long-long -Wno-unused-parameter -Wwrite-strings -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/polly/lib -fdebug-prefix-map=/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-03-09-184146-41876-1 -x c++ /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/CodeGen/PerfMonitor.cpp
1//===------ PerfMonitor.cpp - Generate a run-time performance monitor. -======//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//===----------------------------------------------------------------------===//
10
11#include "polly/CodeGen/PerfMonitor.h"
12#include "polly/CodeGen/RuntimeDebugBuilder.h"
13#include "polly/ScopInfo.h"
14#include "llvm/ADT/Triple.h"
15#include "llvm/IR/IntrinsicsX86.h"
16#include <sstream>
17
18using namespace llvm;
19using namespace polly;
20
21Function *PerfMonitor::getAtExit() {
22 const char *Name = "atexit";
23 Function *F = M->getFunction(Name);
24
25 if (!F) {
26 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
27 FunctionType *Ty = FunctionType::get(Builder.getInt32Ty(),
28 {Builder.getInt8PtrTy()}, false);
29 F = Function::Create(Ty, Linkage, Name, M);
30 }
31
32 return F;
33}
34
35void PerfMonitor::addToGlobalConstructors(Function *Fn) {
36 const char *Name = "llvm.global_ctors";
37 GlobalVariable *GV = M->getGlobalVariable(Name);
38 std::vector<Constant *> V;
39
40 if (GV) {
41 Constant *Array = GV->getInitializer();
42 for (Value *X : Array->operand_values())
43 V.push_back(cast<Constant>(X));
44 GV->eraseFromParent();
45 }
46
47 StructType *ST = StructType::get(Builder.getInt32Ty(), Fn->getType(),
48 Builder.getInt8PtrTy());
49
50 V.push_back(
51 ConstantStruct::get(ST, Builder.getInt32(10), Fn,
52 ConstantPointerNull::get(Builder.getInt8PtrTy())));
53 ArrayType *Ty = ArrayType::get(ST, V.size());
54
55 GV = new GlobalVariable(*M, Ty, true, GlobalValue::AppendingLinkage,
Value stored to 'GV' is never read
56 ConstantArray::get(Ty, V), Name, nullptr,
57 GlobalVariable::NotThreadLocal);
58}
59
60Function *PerfMonitor::getRDTSCP() {
61 return Intrinsic::getDeclaration(M, Intrinsic::x86_rdtscp);
62}
63
64PerfMonitor::PerfMonitor(const Scop &S, Module *M)
65 : M(M), Builder(M->getContext()), S(S) {
66 if (Triple(M->getTargetTriple()).getArch() == llvm::Triple::x86_64)
67 Supported = true;
68 else
69 Supported = false;
70}
71
72static void TryRegisterGlobal(Module *M, const char *Name,
73 Constant *InitialValue, Value **Location) {
74 *Location = M->getGlobalVariable(Name);
75
76 if (!*Location)
77 *Location = new GlobalVariable(
78 *M, InitialValue->getType(), true, GlobalValue::WeakAnyLinkage,
79 InitialValue, Name, nullptr, GlobalVariable::InitialExecTLSModel);
80}
81
82// Generate a unique name that is usable as a LLVM name for a scop to name its
83// performance counter.
84static std::string GetScopUniqueVarname(const Scop &S) {
85 std::stringstream Name;
86 std::string EntryString, ExitString;
87 std::tie(EntryString, ExitString) = S.getEntryExitStr();
88
89 Name << "__polly_perf_in_" << std::string(S.getFunction().getName())
90 << "_from__" << EntryString << "__to__" << ExitString;
91 return Name.str();
92}
93
94void PerfMonitor::addScopCounter() {
95 const std::string varname = GetScopUniqueVarname(S);
96 TryRegisterGlobal(M, (varname + "_cycles").c_str(), Builder.getInt64(0),
97 &CyclesInCurrentScopPtr);
98
99 TryRegisterGlobal(M, (varname + "_trip_count").c_str(), Builder.getInt64(0),
100 &TripCountForCurrentScopPtr);
101}
102
103void PerfMonitor::addGlobalVariables() {
104 TryRegisterGlobal(M, "__polly_perf_cycles_total_start", Builder.getInt64(0),
105 &CyclesTotalStartPtr);
106
107 TryRegisterGlobal(M, "__polly_perf_initialized", Builder.getInt1(0),
108 &AlreadyInitializedPtr);
109
110 TryRegisterGlobal(M, "__polly_perf_cycles_in_scops", Builder.getInt64(0),
111 &CyclesInScopsPtr);
112
113 TryRegisterGlobal(M, "__polly_perf_cycles_in_scop_start", Builder.getInt64(0),
114 &CyclesInScopStartPtr);
115}
116
117static const char *InitFunctionName = "__polly_perf_init";
118static const char *FinalReportingFunctionName = "__polly_perf_final";
119
120static BasicBlock *FinalStartBB = nullptr;
121static ReturnInst *ReturnFromFinal = nullptr;
122
123Function *PerfMonitor::insertFinalReporting() {
124 // Create new function.
125 GlobalValue::LinkageTypes Linkage = Function::WeakODRLinkage;
126 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), {}, false);
127 Function *ExitFn =
128 Function::Create(Ty, Linkage, FinalReportingFunctionName, M);
129 FinalStartBB = BasicBlock::Create(M->getContext(), "start", ExitFn);
130 Builder.SetInsertPoint(FinalStartBB);
131
132 if (!Supported) {
133 RuntimeDebugBuilder::createCPUPrinter(
134 Builder, "Polly runtime information generation not supported\n");
135 Builder.CreateRetVoid();
136 return ExitFn;
137 }
138
139 // Measure current cycles and compute final timings.
140 Function *RDTSCPFn = getRDTSCP();
141
142 Value *CurrentCycles =
143 Builder.CreateExtractValue(Builder.CreateCall(RDTSCPFn), {0});
144 Value *CyclesStart = Builder.CreateLoad(CyclesTotalStartPtr, true);
145 Value *CyclesTotal = Builder.CreateSub(CurrentCycles, CyclesStart);
146 Value *CyclesInScops = Builder.CreateLoad(CyclesInScopsPtr, true);
147
148 // Print the runtime information.
149 RuntimeDebugBuilder::createCPUPrinter(Builder, "Polly runtime information\n");
150 RuntimeDebugBuilder::createCPUPrinter(Builder, "-------------------------\n");
151 RuntimeDebugBuilder::createCPUPrinter(Builder, "Total: ", CyclesTotal, "\n");
152 RuntimeDebugBuilder::createCPUPrinter(Builder, "Scops: ", CyclesInScops,
153 "\n");
154
155 // Print the preamble for per-scop information.
156 RuntimeDebugBuilder::createCPUPrinter(Builder, "\n");
157 RuntimeDebugBuilder::createCPUPrinter(Builder, "Per SCoP information\n");
158 RuntimeDebugBuilder::createCPUPrinter(Builder, "--------------------\n");
159
160 RuntimeDebugBuilder::createCPUPrinter(
161 Builder, "scop function, "
162 "entry block name, exit block name, total time, trip count\n");
163 ReturnFromFinal = Builder.CreateRetVoid();
164 return ExitFn;
165}
166
167void PerfMonitor::AppendScopReporting() {
168 if (!Supported)
169 return;
170
171 assert(FinalStartBB && "Expected FinalStartBB to be initialized by "((FinalStartBB && "Expected FinalStartBB to be initialized by "
"PerfMonitor::insertFinalReporting.") ? static_cast<void>
(0) : __assert_fail ("FinalStartBB && \"Expected FinalStartBB to be initialized by \" \"PerfMonitor::insertFinalReporting.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/CodeGen/PerfMonitor.cpp"
, 172, __PRETTY_FUNCTION__))
172 "PerfMonitor::insertFinalReporting.")((FinalStartBB && "Expected FinalStartBB to be initialized by "
"PerfMonitor::insertFinalReporting.") ? static_cast<void>
(0) : __assert_fail ("FinalStartBB && \"Expected FinalStartBB to be initialized by \" \"PerfMonitor::insertFinalReporting.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/CodeGen/PerfMonitor.cpp"
, 172, __PRETTY_FUNCTION__))
;
173 assert(ReturnFromFinal && "Expected ReturnFromFinal to be initialized by "((ReturnFromFinal && "Expected ReturnFromFinal to be initialized by "
"PerfMonitor::insertFinalReporting.") ? static_cast<void>
(0) : __assert_fail ("ReturnFromFinal && \"Expected ReturnFromFinal to be initialized by \" \"PerfMonitor::insertFinalReporting.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/CodeGen/PerfMonitor.cpp"
, 174, __PRETTY_FUNCTION__))
174 "PerfMonitor::insertFinalReporting.")((ReturnFromFinal && "Expected ReturnFromFinal to be initialized by "
"PerfMonitor::insertFinalReporting.") ? static_cast<void>
(0) : __assert_fail ("ReturnFromFinal && \"Expected ReturnFromFinal to be initialized by \" \"PerfMonitor::insertFinalReporting.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/CodeGen/PerfMonitor.cpp"
, 174, __PRETTY_FUNCTION__))
;
175
176 Builder.SetInsertPoint(FinalStartBB);
177 ReturnFromFinal->eraseFromParent();
178
179 Value *CyclesInCurrentScop =
180 Builder.CreateLoad(this->CyclesInCurrentScopPtr, true);
181
182 Value *TripCountForCurrentScop =
183 Builder.CreateLoad(this->TripCountForCurrentScopPtr, true);
184
185 std::string EntryName, ExitName;
186 std::tie(EntryName, ExitName) = S.getEntryExitStr();
187
188 // print in CSV for easy parsing with other tools.
189 RuntimeDebugBuilder::createCPUPrinter(
190 Builder, S.getFunction().getName(), ", ", EntryName, ", ", ExitName, ", ",
191 CyclesInCurrentScop, ", ", TripCountForCurrentScop, "\n");
192
193 ReturnFromFinal = Builder.CreateRetVoid();
194}
195
196static Function *FinalReporting = nullptr;
197
198void PerfMonitor::initialize() {
199 addGlobalVariables();
200 addScopCounter();
201
202 // Ensure that we only add the final reporting function once.
203 // On later invocations, append to the reporting function.
204 if (!FinalReporting) {
205 FinalReporting = insertFinalReporting();
206
207 Function *InitFn = insertInitFunction(FinalReporting);
208 addToGlobalConstructors(InitFn);
209 }
210
211 AppendScopReporting();
212}
213
214Function *PerfMonitor::insertInitFunction(Function *FinalReporting) {
215 // Insert function definition and BBs.
216 GlobalValue::LinkageTypes Linkage = Function::WeakODRLinkage;
217 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), {}, false);
218 Function *InitFn = Function::Create(Ty, Linkage, InitFunctionName, M);
219 BasicBlock *Start = BasicBlock::Create(M->getContext(), "start", InitFn);
220 BasicBlock *EarlyReturn =
221 BasicBlock::Create(M->getContext(), "earlyreturn", InitFn);
222 BasicBlock *InitBB = BasicBlock::Create(M->getContext(), "initbb", InitFn);
223
224 Builder.SetInsertPoint(Start);
225
226 // Check if this function was already run. If yes, return.
227 //
228 // In case profiling has been enabled in multiple translation units, the
229 // initializer function will be added to the global constructors list of
230 // each translation unit. When merging translation units, the global
231 // constructor lists are just appended, such that the initializer will appear
232 // multiple times. To avoid initializations being run multiple times (and
233 // especially to avoid that atExitFn is called more than once), we bail
234 // out if the initializer is run more than once.
235 Value *HasRunBefore = Builder.CreateLoad(AlreadyInitializedPtr);
236 Builder.CreateCondBr(HasRunBefore, EarlyReturn, InitBB);
237 Builder.SetInsertPoint(EarlyReturn);
238 Builder.CreateRetVoid();
239
240 // Keep track that this function has been run once.
241 Builder.SetInsertPoint(InitBB);
242 Value *True = Builder.getInt1(true);
243 Builder.CreateStore(True, AlreadyInitializedPtr);
244
245 // Register the final reporting function with atexit().
246 Value *FinalReportingPtr =
247 Builder.CreatePointerCast(FinalReporting, Builder.getInt8PtrTy());
248 Function *AtExitFn = getAtExit();
249 Builder.CreateCall(AtExitFn, {FinalReportingPtr});
250
251 if (Supported) {
252 // Read the currently cycle counter and store the result for later.
253 Function *RDTSCPFn = getRDTSCP();
254 Value *CurrentCycles =
255 Builder.CreateExtractValue(Builder.CreateCall(RDTSCPFn), {0});
256 Builder.CreateStore(CurrentCycles, CyclesTotalStartPtr, true);
257 }
258 Builder.CreateRetVoid();
259
260 return InitFn;
261}
262
263void PerfMonitor::insertRegionStart(Instruction *InsertBefore) {
264 if (!Supported)
265 return;
266
267 Builder.SetInsertPoint(InsertBefore);
268 Function *RDTSCPFn = getRDTSCP();
269 Value *CurrentCycles =
270 Builder.CreateExtractValue(Builder.CreateCall(RDTSCPFn), {0});
271 Builder.CreateStore(CurrentCycles, CyclesInScopStartPtr, true);
272}
273
274void PerfMonitor::insertRegionEnd(Instruction *InsertBefore) {
275 if (!Supported)
276 return;
277
278 Builder.SetInsertPoint(InsertBefore);
279 Function *RDTSCPFn = getRDTSCP();
280 LoadInst *CyclesStart = Builder.CreateLoad(CyclesInScopStartPtr, true);
281 Value *CurrentCycles =
282 Builder.CreateExtractValue(Builder.CreateCall(RDTSCPFn), {0});
283 Value *CyclesInScop = Builder.CreateSub(CurrentCycles, CyclesStart);
284 Value *CyclesInScops = Builder.CreateLoad(CyclesInScopsPtr, true);
285 CyclesInScops = Builder.CreateAdd(CyclesInScops, CyclesInScop);
286 Builder.CreateStore(CyclesInScops, CyclesInScopsPtr, true);
287
288 Value *CyclesInCurrentScop = Builder.CreateLoad(CyclesInCurrentScopPtr, true);
289 CyclesInCurrentScop = Builder.CreateAdd(CyclesInCurrentScop, CyclesInScop);
290 Builder.CreateStore(CyclesInCurrentScop, CyclesInCurrentScopPtr, true);
291
292 Value *TripCountForCurrentScop =
293 Builder.CreateLoad(TripCountForCurrentScopPtr, true);
294 TripCountForCurrentScop =
295 Builder.CreateAdd(TripCountForCurrentScop, Builder.getInt64(1));
296 Builder.CreateStore(TripCountForCurrentScop, TripCountForCurrentScopPtr,
297 true);
298}