Bug Summary

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