Bug Summary

File:lib/MC/MCExpr.cpp
Warning:line 775, column 43
Division by zero

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 MCExpr.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -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-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/lib/MC -I /build/llvm-toolchain-snapshot-7~svn325118/lib/MC -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn325118/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.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 -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/lib/MC -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-02-14-150435-17243-1 -x c++ /build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp

/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp

1//===- MCExpr.cpp - Assembly Level Expression Implementation --------------===//
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#include "llvm/MC/MCExpr.h"
11#include "llvm/ADT/Statistic.h"
12#include "llvm/ADT/StringSwitch.h"
13#include "llvm/MC/MCAsmInfo.h"
14#include "llvm/MC/MCAsmLayout.h"
15#include "llvm/MC/MCAssembler.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCObjectWriter.h"
18#include "llvm/MC/MCSymbol.h"
19#include "llvm/MC/MCValue.h"
20#include "llvm/Support/Casting.h"
21#include "llvm/Support/Compiler.h"
22#include "llvm/Support/Debug.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/raw_ostream.h"
25#include <cassert>
26#include <cstdint>
27
28using namespace llvm;
29
30#define DEBUG_TYPE"mcexpr" "mcexpr"
31
32namespace {
33namespace stats {
34
35STATISTIC(MCExprEvaluate, "Number of MCExpr evaluations")static llvm::Statistic MCExprEvaluate = {"mcexpr", "MCExprEvaluate"
, "Number of MCExpr evaluations", {0}, {false}}
;
36
37} // end namespace stats
38} // end anonymous namespace
39
40void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const {
41 switch (getKind()) {
42 case MCExpr::Target:
43 return cast<MCTargetExpr>(this)->printImpl(OS, MAI);
44 case MCExpr::Constant:
45 OS << cast<MCConstantExpr>(*this).getValue();
46 return;
47
48 case MCExpr::SymbolRef: {
49 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*this);
50 const MCSymbol &Sym = SRE.getSymbol();
51 // Parenthesize names that start with $ so that they don't look like
52 // absolute names.
53 bool UseParens =
54 !InParens && !Sym.getName().empty() && Sym.getName()[0] == '$';
55 if (UseParens) {
56 OS << '(';
57 Sym.print(OS, MAI);
58 OS << ')';
59 } else
60 Sym.print(OS, MAI);
61
62 if (SRE.getKind() != MCSymbolRefExpr::VK_None)
63 SRE.printVariantKind(OS);
64
65 return;
66 }
67
68 case MCExpr::Unary: {
69 const MCUnaryExpr &UE = cast<MCUnaryExpr>(*this);
70 switch (UE.getOpcode()) {
71 case MCUnaryExpr::LNot: OS << '!'; break;
72 case MCUnaryExpr::Minus: OS << '-'; break;
73 case MCUnaryExpr::Not: OS << '~'; break;
74 case MCUnaryExpr::Plus: OS << '+'; break;
75 }
76 UE.getSubExpr()->print(OS, MAI);
77 return;
78 }
79
80 case MCExpr::Binary: {
81 const MCBinaryExpr &BE = cast<MCBinaryExpr>(*this);
82
83 // Only print parens around the LHS if it is non-trivial.
84 if (isa<MCConstantExpr>(BE.getLHS()) || isa<MCSymbolRefExpr>(BE.getLHS())) {
85 BE.getLHS()->print(OS, MAI);
86 } else {
87 OS << '(';
88 BE.getLHS()->print(OS, MAI);
89 OS << ')';
90 }
91
92 switch (BE.getOpcode()) {
93 case MCBinaryExpr::Add:
94 // Print "X-42" instead of "X+-42".
95 if (const MCConstantExpr *RHSC = dyn_cast<MCConstantExpr>(BE.getRHS())) {
96 if (RHSC->getValue() < 0) {
97 OS << RHSC->getValue();
98 return;
99 }
100 }
101
102 OS << '+';
103 break;
104 case MCBinaryExpr::AShr: OS << ">>"; break;
105 case MCBinaryExpr::And: OS << '&'; break;
106 case MCBinaryExpr::Div: OS << '/'; break;
107 case MCBinaryExpr::EQ: OS << "=="; break;
108 case MCBinaryExpr::GT: OS << '>'; break;
109 case MCBinaryExpr::GTE: OS << ">="; break;
110 case MCBinaryExpr::LAnd: OS << "&&"; break;
111 case MCBinaryExpr::LOr: OS << "||"; break;
112 case MCBinaryExpr::LShr: OS << ">>"; break;
113 case MCBinaryExpr::LT: OS << '<'; break;
114 case MCBinaryExpr::LTE: OS << "<="; break;
115 case MCBinaryExpr::Mod: OS << '%'; break;
116 case MCBinaryExpr::Mul: OS << '*'; break;
117 case MCBinaryExpr::NE: OS << "!="; break;
118 case MCBinaryExpr::Or: OS << '|'; break;
119 case MCBinaryExpr::Shl: OS << "<<"; break;
120 case MCBinaryExpr::Sub: OS << '-'; break;
121 case MCBinaryExpr::Xor: OS << '^'; break;
122 }
123
124 // Only print parens around the LHS if it is non-trivial.
125 if (isa<MCConstantExpr>(BE.getRHS()) || isa<MCSymbolRefExpr>(BE.getRHS())) {
126 BE.getRHS()->print(OS, MAI);
127 } else {
128 OS << '(';
129 BE.getRHS()->print(OS, MAI);
130 OS << ')';
131 }
132 return;
133 }
134 }
135
136 llvm_unreachable("Invalid expression kind!")::llvm::llvm_unreachable_internal("Invalid expression kind!",
"/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp"
, 136)
;
137}
138
139#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
140LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void MCExpr::dump() const {
141 dbgs() << *this;
142 dbgs() << '\n';
143}
144#endif
145
146/* *** */
147
148const MCBinaryExpr *MCBinaryExpr::create(Opcode Opc, const MCExpr *LHS,
149 const MCExpr *RHS, MCContext &Ctx,
150 SMLoc Loc) {
151 return new (Ctx) MCBinaryExpr(Opc, LHS, RHS, Loc);
152}
153
154const MCUnaryExpr *MCUnaryExpr::create(Opcode Opc, const MCExpr *Expr,
155 MCContext &Ctx, SMLoc Loc) {
156 return new (Ctx) MCUnaryExpr(Opc, Expr, Loc);
157}
158
159const MCConstantExpr *MCConstantExpr::create(int64_t Value, MCContext &Ctx) {
160 return new (Ctx) MCConstantExpr(Value);
161}
162
163/* *** */
164
165MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
166 const MCAsmInfo *MAI, SMLoc Loc)
167 : MCExpr(MCExpr::SymbolRef, Loc), Kind(Kind),
168 UseParensForSymbolVariant(MAI->useParensForSymbolVariant()),
169 HasSubsectionsViaSymbols(MAI->hasSubsectionsViaSymbols()),
170 Symbol(Symbol) {
171 assert(Symbol)(static_cast <bool> (Symbol) ? void (0) : __assert_fail
("Symbol", "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp"
, 171, __extension__ __PRETTY_FUNCTION__))
;
172}
173
174const MCSymbolRefExpr *MCSymbolRefExpr::create(const MCSymbol *Sym,
175 VariantKind Kind,
176 MCContext &Ctx, SMLoc Loc) {
177 return new (Ctx) MCSymbolRefExpr(Sym, Kind, Ctx.getAsmInfo(), Loc);
178}
179
180const MCSymbolRefExpr *MCSymbolRefExpr::create(StringRef Name, VariantKind Kind,
181 MCContext &Ctx) {
182 return create(Ctx.getOrCreateSymbol(Name), Kind, Ctx);
183}
184
185StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
186 switch (Kind) {
187 case VK_Invalid: return "<<invalid>>";
188 case VK_None: return "<<none>>";
189
190 case VK_DTPOFF: return "DTPOFF";
191 case VK_DTPREL: return "DTPREL";
192 case VK_GOT: return "GOT";
193 case VK_GOTOFF: return "GOTOFF";
194 case VK_GOTREL: return "GOTREL";
195 case VK_GOTPCREL: return "GOTPCREL";
196 case VK_GOTTPOFF: return "GOTTPOFF";
197 case VK_INDNTPOFF: return "INDNTPOFF";
198 case VK_NTPOFF: return "NTPOFF";
199 case VK_GOTNTPOFF: return "GOTNTPOFF";
200 case VK_PLT: return "PLT";
201 case VK_TLSGD: return "TLSGD";
202 case VK_TLSLD: return "TLSLD";
203 case VK_TLSLDM: return "TLSLDM";
204 case VK_TPOFF: return "TPOFF";
205 case VK_TPREL: return "TPREL";
206 case VK_TLSCALL: return "tlscall";
207 case VK_TLSDESC: return "tlsdesc";
208 case VK_TLVP: return "TLVP";
209 case VK_TLVPPAGE: return "TLVPPAGE";
210 case VK_TLVPPAGEOFF: return "TLVPPAGEOFF";
211 case VK_PAGE: return "PAGE";
212 case VK_PAGEOFF: return "PAGEOFF";
213 case VK_GOTPAGE: return "GOTPAGE";
214 case VK_GOTPAGEOFF: return "GOTPAGEOFF";
215 case VK_SECREL: return "SECREL32";
216 case VK_SIZE: return "SIZE";
217 case VK_WEAKREF: return "WEAKREF";
218 case VK_X86_ABS8: return "ABS8";
219 case VK_ARM_NONE: return "none";
220 case VK_ARM_GOT_PREL: return "GOT_PREL";
221 case VK_ARM_TARGET1: return "target1";
222 case VK_ARM_TARGET2: return "target2";
223 case VK_ARM_PREL31: return "prel31";
224 case VK_ARM_SBREL: return "sbrel";
225 case VK_ARM_TLSLDO: return "tlsldo";
226 case VK_ARM_TLSDESCSEQ: return "tlsdescseq";
227 case VK_AVR_NONE: return "none";
228 case VK_AVR_LO8: return "lo8";
229 case VK_AVR_HI8: return "hi8";
230 case VK_AVR_HLO8: return "hlo8";
231 case VK_AVR_DIFF8: return "diff8";
232 case VK_AVR_DIFF16: return "diff16";
233 case VK_AVR_DIFF32: return "diff32";
234 case VK_PPC_LO: return "l";
235 case VK_PPC_HI: return "h";
236 case VK_PPC_HA: return "ha";
237 case VK_PPC_HIGHER: return "higher";
238 case VK_PPC_HIGHERA: return "highera";
239 case VK_PPC_HIGHEST: return "highest";
240 case VK_PPC_HIGHESTA: return "highesta";
241 case VK_PPC_GOT_LO: return "got@l";
242 case VK_PPC_GOT_HI: return "got@h";
243 case VK_PPC_GOT_HA: return "got@ha";
244 case VK_PPC_TOCBASE: return "tocbase";
245 case VK_PPC_TOC: return "toc";
246 case VK_PPC_TOC_LO: return "toc@l";
247 case VK_PPC_TOC_HI: return "toc@h";
248 case VK_PPC_TOC_HA: return "toc@ha";
249 case VK_PPC_DTPMOD: return "dtpmod";
250 case VK_PPC_TPREL_LO: return "tprel@l";
251 case VK_PPC_TPREL_HI: return "tprel@h";
252 case VK_PPC_TPREL_HA: return "tprel@ha";
253 case VK_PPC_TPREL_HIGHER: return "tprel@higher";
254 case VK_PPC_TPREL_HIGHERA: return "tprel@highera";
255 case VK_PPC_TPREL_HIGHEST: return "tprel@highest";
256 case VK_PPC_TPREL_HIGHESTA: return "tprel@highesta";
257 case VK_PPC_DTPREL_LO: return "dtprel@l";
258 case VK_PPC_DTPREL_HI: return "dtprel@h";
259 case VK_PPC_DTPREL_HA: return "dtprel@ha";
260 case VK_PPC_DTPREL_HIGHER: return "dtprel@higher";
261 case VK_PPC_DTPREL_HIGHERA: return "dtprel@highera";
262 case VK_PPC_DTPREL_HIGHEST: return "dtprel@highest";
263 case VK_PPC_DTPREL_HIGHESTA: return "dtprel@highesta";
264 case VK_PPC_GOT_TPREL: return "got@tprel";
265 case VK_PPC_GOT_TPREL_LO: return "got@tprel@l";
266 case VK_PPC_GOT_TPREL_HI: return "got@tprel@h";
267 case VK_PPC_GOT_TPREL_HA: return "got@tprel@ha";
268 case VK_PPC_GOT_DTPREL: return "got@dtprel";
269 case VK_PPC_GOT_DTPREL_LO: return "got@dtprel@l";
270 case VK_PPC_GOT_DTPREL_HI: return "got@dtprel@h";
271 case VK_PPC_GOT_DTPREL_HA: return "got@dtprel@ha";
272 case VK_PPC_TLS: return "tls";
273 case VK_PPC_GOT_TLSGD: return "got@tlsgd";
274 case VK_PPC_GOT_TLSGD_LO: return "got@tlsgd@l";
275 case VK_PPC_GOT_TLSGD_HI: return "got@tlsgd@h";
276 case VK_PPC_GOT_TLSGD_HA: return "got@tlsgd@ha";
277 case VK_PPC_TLSGD: return "tlsgd";
278 case VK_PPC_GOT_TLSLD: return "got@tlsld";
279 case VK_PPC_GOT_TLSLD_LO: return "got@tlsld@l";
280 case VK_PPC_GOT_TLSLD_HI: return "got@tlsld@h";
281 case VK_PPC_GOT_TLSLD_HA: return "got@tlsld@ha";
282 case VK_PPC_TLSLD: return "tlsld";
283 case VK_PPC_LOCAL: return "local";
284 case VK_COFF_IMGREL32: return "IMGREL";
285 case VK_Hexagon_PCREL: return "PCREL";
286 case VK_Hexagon_LO16: return "LO16";
287 case VK_Hexagon_HI16: return "HI16";
288 case VK_Hexagon_GPREL: return "GPREL";
289 case VK_Hexagon_GD_GOT: return "GDGOT";
290 case VK_Hexagon_LD_GOT: return "LDGOT";
291 case VK_Hexagon_GD_PLT: return "GDPLT";
292 case VK_Hexagon_LD_PLT: return "LDPLT";
293 case VK_Hexagon_IE: return "IE";
294 case VK_Hexagon_IE_GOT: return "IEGOT";
295 case VK_WebAssembly_FUNCTION: return "FUNCTION";
296 case VK_WebAssembly_TYPEINDEX: return "TYPEINDEX";
297 case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo";
298 case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi";
299 case VK_AMDGPU_REL32_LO: return "rel32@lo";
300 case VK_AMDGPU_REL32_HI: return "rel32@hi";
301 }
302 llvm_unreachable("Invalid variant kind")::llvm::llvm_unreachable_internal("Invalid variant kind", "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp"
, 302)
;
303}
304
305MCSymbolRefExpr::VariantKind
306MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
307 return StringSwitch<VariantKind>(Name.lower())
308 .Case("dtprel", VK_DTPREL)
309 .Case("dtpoff", VK_DTPOFF)
310 .Case("got", VK_GOT)
311 .Case("gotoff", VK_GOTOFF)
312 .Case("gotrel", VK_GOTREL)
313 .Case("gotpcrel", VK_GOTPCREL)
314 .Case("gottpoff", VK_GOTTPOFF)
315 .Case("indntpoff", VK_INDNTPOFF)
316 .Case("ntpoff", VK_NTPOFF)
317 .Case("gotntpoff", VK_GOTNTPOFF)
318 .Case("plt", VK_PLT)
319 .Case("tlscall", VK_TLSCALL)
320 .Case("tlsdesc", VK_TLSDESC)
321 .Case("tlsgd", VK_TLSGD)
322 .Case("tlsld", VK_TLSLD)
323 .Case("tlsldm", VK_TLSLDM)
324 .Case("tpoff", VK_TPOFF)
325 .Case("tprel", VK_TPREL)
326 .Case("tlvp", VK_TLVP)
327 .Case("tlvppage", VK_TLVPPAGE)
328 .Case("tlvppageoff", VK_TLVPPAGEOFF)
329 .Case("page", VK_PAGE)
330 .Case("pageoff", VK_PAGEOFF)
331 .Case("gotpage", VK_GOTPAGE)
332 .Case("gotpageoff", VK_GOTPAGEOFF)
333 .Case("imgrel", VK_COFF_IMGREL32)
334 .Case("secrel32", VK_SECREL)
335 .Case("size", VK_SIZE)
336 .Case("abs8", VK_X86_ABS8)
337 .Case("l", VK_PPC_LO)
338 .Case("h", VK_PPC_HI)
339 .Case("ha", VK_PPC_HA)
340 .Case("higher", VK_PPC_HIGHER)
341 .Case("highera", VK_PPC_HIGHERA)
342 .Case("highest", VK_PPC_HIGHEST)
343 .Case("highesta", VK_PPC_HIGHESTA)
344 .Case("got@l", VK_PPC_GOT_LO)
345 .Case("got@h", VK_PPC_GOT_HI)
346 .Case("got@ha", VK_PPC_GOT_HA)
347 .Case("local", VK_PPC_LOCAL)
348 .Case("tocbase", VK_PPC_TOCBASE)
349 .Case("toc", VK_PPC_TOC)
350 .Case("toc@l", VK_PPC_TOC_LO)
351 .Case("toc@h", VK_PPC_TOC_HI)
352 .Case("toc@ha", VK_PPC_TOC_HA)
353 .Case("tls", VK_PPC_TLS)
354 .Case("dtpmod", VK_PPC_DTPMOD)
355 .Case("tprel@l", VK_PPC_TPREL_LO)
356 .Case("tprel@h", VK_PPC_TPREL_HI)
357 .Case("tprel@ha", VK_PPC_TPREL_HA)
358 .Case("tprel@higher", VK_PPC_TPREL_HIGHER)
359 .Case("tprel@highera", VK_PPC_TPREL_HIGHERA)
360 .Case("tprel@highest", VK_PPC_TPREL_HIGHEST)
361 .Case("tprel@highesta", VK_PPC_TPREL_HIGHESTA)
362 .Case("dtprel@l", VK_PPC_DTPREL_LO)
363 .Case("dtprel@h", VK_PPC_DTPREL_HI)
364 .Case("dtprel@ha", VK_PPC_DTPREL_HA)
365 .Case("dtprel@higher", VK_PPC_DTPREL_HIGHER)
366 .Case("dtprel@highera", VK_PPC_DTPREL_HIGHERA)
367 .Case("dtprel@highest", VK_PPC_DTPREL_HIGHEST)
368 .Case("dtprel@highesta", VK_PPC_DTPREL_HIGHESTA)
369 .Case("got@tprel", VK_PPC_GOT_TPREL)
370 .Case("got@tprel@l", VK_PPC_GOT_TPREL_LO)
371 .Case("got@tprel@h", VK_PPC_GOT_TPREL_HI)
372 .Case("got@tprel@ha", VK_PPC_GOT_TPREL_HA)
373 .Case("got@dtprel", VK_PPC_GOT_DTPREL)
374 .Case("got@dtprel@l", VK_PPC_GOT_DTPREL_LO)
375 .Case("got@dtprel@h", VK_PPC_GOT_DTPREL_HI)
376 .Case("got@dtprel@ha", VK_PPC_GOT_DTPREL_HA)
377 .Case("got@tlsgd", VK_PPC_GOT_TLSGD)
378 .Case("got@tlsgd@l", VK_PPC_GOT_TLSGD_LO)
379 .Case("got@tlsgd@h", VK_PPC_GOT_TLSGD_HI)
380 .Case("got@tlsgd@ha", VK_PPC_GOT_TLSGD_HA)
381 .Case("got@tlsld", VK_PPC_GOT_TLSLD)
382 .Case("got@tlsld@l", VK_PPC_GOT_TLSLD_LO)
383 .Case("got@tlsld@h", VK_PPC_GOT_TLSLD_HI)
384 .Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA)
385 .Case("gdgot", VK_Hexagon_GD_GOT)
386 .Case("gdplt", VK_Hexagon_GD_PLT)
387 .Case("iegot", VK_Hexagon_IE_GOT)
388 .Case("ie", VK_Hexagon_IE)
389 .Case("ldgot", VK_Hexagon_LD_GOT)
390 .Case("ldplt", VK_Hexagon_LD_PLT)
391 .Case("pcrel", VK_Hexagon_PCREL)
392 .Case("none", VK_ARM_NONE)
393 .Case("got_prel", VK_ARM_GOT_PREL)
394 .Case("target1", VK_ARM_TARGET1)
395 .Case("target2", VK_ARM_TARGET2)
396 .Case("prel31", VK_ARM_PREL31)
397 .Case("sbrel", VK_ARM_SBREL)
398 .Case("tlsldo", VK_ARM_TLSLDO)
399 .Case("lo8", VK_AVR_LO8)
400 .Case("hi8", VK_AVR_HI8)
401 .Case("hlo8", VK_AVR_HLO8)
402 .Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO)
403 .Case("gotpcrel32@hi", VK_AMDGPU_GOTPCREL32_HI)
404 .Case("rel32@lo", VK_AMDGPU_REL32_LO)
405 .Case("rel32@hi", VK_AMDGPU_REL32_HI)
406 .Default(VK_Invalid);
407}
408
409void MCSymbolRefExpr::printVariantKind(raw_ostream &OS) const {
410 if (UseParensForSymbolVariant)
411 OS << '(' << MCSymbolRefExpr::getVariantKindName(getKind()) << ')';
412 else
413 OS << '@' << MCSymbolRefExpr::getVariantKindName(getKind());
414}
415
416/* *** */
417
418void MCTargetExpr::anchor() {}
419
420/* *** */
421
422bool MCExpr::evaluateAsAbsolute(int64_t &Res) const {
423 return evaluateAsAbsolute(Res, nullptr, nullptr, nullptr);
424}
425
426bool MCExpr::evaluateAsAbsolute(int64_t &Res,
427 const MCAsmLayout &Layout) const {
428 return evaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, nullptr);
429}
430
431bool MCExpr::evaluateAsAbsolute(int64_t &Res,
432 const MCAsmLayout &Layout,
433 const SectionAddrMap &Addrs) const {
434 return evaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, &Addrs);
435}
436
437bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const {
438 return evaluateAsAbsolute(Res, &Asm, nullptr, nullptr);
439}
440
441bool MCExpr::evaluateKnownAbsolute(int64_t &Res,
442 const MCAsmLayout &Layout) const {
443 return evaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, nullptr,
444 true);
445}
446
447bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
448 const MCAsmLayout *Layout,
449 const SectionAddrMap *Addrs) const {
450 // FIXME: The use if InSet = Addrs is a hack. Setting InSet causes us
451 // absolutize differences across sections and that is what the MachO writer
452 // uses Addrs for.
453 return evaluateAsAbsolute(Res, Asm, Layout, Addrs, Addrs);
454}
455
456bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
457 const MCAsmLayout *Layout,
458 const SectionAddrMap *Addrs, bool InSet) const {
459 MCValue Value;
460
461 // Fast path constants.
462 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(this)) {
463 Res = CE->getValue();
464 return true;
465 }
466
467 bool IsRelocatable =
468 evaluateAsRelocatableImpl(Value, Asm, Layout, nullptr, Addrs, InSet);
469
470 // Record the current value.
471 Res = Value.getConstant();
472
473 return IsRelocatable && Value.isAbsolute();
474}
475
476/// \brief Helper method for \see EvaluateSymbolAdd().
477static void AttemptToFoldSymbolOffsetDifference(
478 const MCAssembler *Asm, const MCAsmLayout *Layout,
479 const SectionAddrMap *Addrs, bool InSet, const MCSymbolRefExpr *&A,
480 const MCSymbolRefExpr *&B, int64_t &Addend) {
481 if (!A || !B)
482 return;
483
484 const MCSymbol &SA = A->getSymbol();
485 const MCSymbol &SB = B->getSymbol();
486
487 if (SA.isUndefined() || SB.isUndefined())
488 return;
489
490 if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet))
491 return;
492
493 if (SA.getFragment() == SB.getFragment() && !SA.isVariable() &&
494 !SB.isVariable()) {
495 Addend += (SA.getOffset() - SB.getOffset());
496
497 // Pointers to Thumb symbols need to have their low-bit set to allow
498 // for interworking.
499 if (Asm->isThumbFunc(&SA))
500 Addend |= 1;
501
502 // Clear the symbol expr pointers to indicate we have folded these
503 // operands.
504 A = B = nullptr;
505 return;
506 }
507
508 if (!Layout)
509 return;
510
511 const MCSection &SecA = *SA.getFragment()->getParent();
512 const MCSection &SecB = *SB.getFragment()->getParent();
513
514 if ((&SecA != &SecB) && !Addrs)
515 return;
516
517 // Eagerly evaluate.
518 Addend += Layout->getSymbolOffset(A->getSymbol()) -
519 Layout->getSymbolOffset(B->getSymbol());
520 if (Addrs && (&SecA != &SecB))
521 Addend += (Addrs->lookup(&SecA) - Addrs->lookup(&SecB));
522
523 // Pointers to Thumb symbols need to have their low-bit set to allow
524 // for interworking.
525 if (Asm->isThumbFunc(&SA))
526 Addend |= 1;
527
528 // Clear the symbol expr pointers to indicate we have folded these
529 // operands.
530 A = B = nullptr;
531}
532
533/// \brief Evaluate the result of an add between (conceptually) two MCValues.
534///
535/// This routine conceptually attempts to construct an MCValue:
536/// Result = (Result_A - Result_B + Result_Cst)
537/// from two MCValue's LHS and RHS where
538/// Result = LHS + RHS
539/// and
540/// Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).
541///
542/// This routine attempts to aggresively fold the operands such that the result
543/// is representable in an MCValue, but may not always succeed.
544///
545/// \returns True on success, false if the result is not representable in an
546/// MCValue.
547
548/// NOTE: It is really important to have both the Asm and Layout arguments.
549/// They might look redundant, but this function can be used before layout
550/// is done (see the object streamer for example) and having the Asm argument
551/// lets us avoid relaxations early.
552static bool
553EvaluateSymbolicAdd(const MCAssembler *Asm, const MCAsmLayout *Layout,
554 const SectionAddrMap *Addrs, bool InSet, const MCValue &LHS,
555 const MCSymbolRefExpr *RHS_A, const MCSymbolRefExpr *RHS_B,
556 int64_t RHS_Cst, MCValue &Res) {
557 // FIXME: This routine (and other evaluation parts) are *incredibly* sloppy
558 // about dealing with modifiers. This will ultimately bite us, one day.
559 const MCSymbolRefExpr *LHS_A = LHS.getSymA();
560 const MCSymbolRefExpr *LHS_B = LHS.getSymB();
561 int64_t LHS_Cst = LHS.getConstant();
562
563 // Fold the result constant immediately.
564 int64_t Result_Cst = LHS_Cst + RHS_Cst;
565
566 assert((!Layout || Asm) &&(static_cast <bool> ((!Layout || Asm) && "Must have an assembler object if layout is given!"
) ? void (0) : __assert_fail ("(!Layout || Asm) && \"Must have an assembler object if layout is given!\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp"
, 567, __extension__ __PRETTY_FUNCTION__))
567 "Must have an assembler object if layout is given!")(static_cast <bool> ((!Layout || Asm) && "Must have an assembler object if layout is given!"
) ? void (0) : __assert_fail ("(!Layout || Asm) && \"Must have an assembler object if layout is given!\""
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp"
, 567, __extension__ __PRETTY_FUNCTION__))
;
568
569 // If we have a layout, we can fold resolved differences.
570 if (Asm) {
571 // First, fold out any differences which are fully resolved. By
572 // reassociating terms in
573 // Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).
574 // we have the four possible differences:
575 // (LHS_A - LHS_B),
576 // (LHS_A - RHS_B),
577 // (RHS_A - LHS_B),
578 // (RHS_A - RHS_B).
579 // Since we are attempting to be as aggressive as possible about folding, we
580 // attempt to evaluate each possible alternative.
581 AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, LHS_B,
582 Result_Cst);
583 AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, RHS_B,
584 Result_Cst);
585 AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, LHS_B,
586 Result_Cst);
587 AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, RHS_B,
588 Result_Cst);
589 }
590
591 // We can't represent the addition or subtraction of two symbols.
592 if ((LHS_A && RHS_A) || (LHS_B && RHS_B))
593 return false;
594
595 // At this point, we have at most one additive symbol and one subtractive
596 // symbol -- find them.
597 const MCSymbolRefExpr *A = LHS_A ? LHS_A : RHS_A;
598 const MCSymbolRefExpr *B = LHS_B ? LHS_B : RHS_B;
599
600 Res = MCValue::get(A, B, Result_Cst);
601 return true;
602}
603
604bool MCExpr::evaluateAsRelocatable(MCValue &Res,
605 const MCAsmLayout *Layout,
606 const MCFixup *Fixup) const {
607 MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
608 return evaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr,
609 false);
610}
611
612bool MCExpr::evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const {
613 MCAssembler *Assembler = &Layout.getAssembler();
614 return evaluateAsRelocatableImpl(Res, Assembler, &Layout, nullptr, nullptr,
1
Calling 'MCExpr::evaluateAsRelocatableImpl'
615 true);
616}
617
618static bool canExpand(const MCSymbol &Sym, bool InSet) {
619 const MCExpr *Expr = Sym.getVariableValue();
620 const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr);
621 if (Inner) {
622 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF)
623 return false;
624 }
625
626 if (InSet)
627 return true;
628 return !Sym.isInSection();
629}
630
631bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
632 const MCAsmLayout *Layout,
633 const MCFixup *Fixup,
634 const SectionAddrMap *Addrs,
635 bool InSet) const {
636 ++stats::MCExprEvaluate;
13
Calling 'Statistic::operator++'
16
Returning from 'Statistic::operator++'
637
638 switch (getKind()) {
2
Control jumps to 'case Binary:' at line 717
4
Control jumps to 'case Binary:' at line 717
6
Control jumps to 'case Binary:' at line 717
8
Control jumps to 'case Binary:' at line 717
17
Calling 'MCExpr::getKind'
18
Returning from 'MCExpr::getKind'
19
Control jumps to 'case Binary:' at line 717
639 case Target:
640 return cast<MCTargetExpr>(this)->evaluateAsRelocatableImpl(Res, Layout,
641 Fixup);
642
643 case Constant:
644 Res = MCValue::get(cast<MCConstantExpr>(this)->getValue());
645 return true;
646
647 case SymbolRef: {
648 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
649 const MCSymbol &Sym = SRE->getSymbol();
650
651 // Evaluate recursively if this is a variable.
652 if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None &&
653 canExpand(Sym, InSet)) {
654 bool IsMachO = SRE->hasSubsectionsViaSymbols();
655 if (Sym.getVariableValue()->evaluateAsRelocatableImpl(
656 Res, Asm, Layout, Fixup, Addrs, InSet || IsMachO)) {
657 if (!IsMachO)
658 return true;
659
660 const MCSymbolRefExpr *A = Res.getSymA();
661 const MCSymbolRefExpr *B = Res.getSymB();
662 // FIXME: This is small hack. Given
663 // a = b + 4
664 // .long a
665 // the OS X assembler will completely drop the 4. We should probably
666 // include it in the relocation or produce an error if that is not
667 // possible.
668 // Allow constant expressions.
669 if (!A && !B)
670 return true;
671 // Allows aliases with zero offset.
672 if (Res.getConstant() == 0 && (!A || !B))
673 return true;
674 }
675 }
676
677 Res = MCValue::get(SRE, nullptr, 0);
678 return true;
679 }
680
681 case Unary: {
682 const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);
683 MCValue Value;
684
685 if (!AUE->getSubExpr()->evaluateAsRelocatableImpl(Value, Asm, Layout, Fixup,
686 Addrs, InSet))
687 return false;
688
689 switch (AUE->getOpcode()) {
690 case MCUnaryExpr::LNot:
691 if (!Value.isAbsolute())
692 return false;
693 Res = MCValue::get(!Value.getConstant());
694 break;
695 case MCUnaryExpr::Minus:
696 /// -(a - b + const) ==> (b - a - const)
697 if (Value.getSymA() && !Value.getSymB())
698 return false;
699
700 // The cast avoids undefined behavior if the constant is INT64_MIN.
701 Res = MCValue::get(Value.getSymB(), Value.getSymA(),
702 -(uint64_t)Value.getConstant());
703 break;
704 case MCUnaryExpr::Not:
705 if (!Value.isAbsolute())
706 return false;
707 Res = MCValue::get(~Value.getConstant());
708 break;
709 case MCUnaryExpr::Plus:
710 Res = Value;
711 break;
712 }
713
714 return true;
715 }
716
717 case Binary: {
718 const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
719 MCValue LHSValue, RHSValue;
9
Calling defaulted default constructor for 'MCValue'
11
Returning from default constructor for 'MCValue'
20
Calling defaulted default constructor for 'MCValue'
21
Returning from default constructor for 'MCValue'
22
Calling defaulted default constructor for 'MCValue'
23
Returning from default constructor for 'MCValue'
720
721 if (!ABE->getLHS()->evaluateAsRelocatableImpl(LHSValue, Asm, Layout, Fixup,
24
Calling 'MCBinaryExpr::getLHS'
25
Returning from 'MCBinaryExpr::getLHS'
26
Assuming the condition is false
30
Taking false branch
48
Taking false branch
722 Addrs, InSet) ||
723 !ABE->getRHS()->evaluateAsRelocatableImpl(RHSValue, Asm, Layout, Fixup,
3
Calling 'MCExpr::evaluateAsRelocatableImpl'
5
Calling 'MCExpr::evaluateAsRelocatableImpl'
7
Calling 'MCExpr::evaluateAsRelocatableImpl'
12
Calling 'MCExpr::evaluateAsRelocatableImpl'
27
Calling 'MCBinaryExpr::getRHS'
28
Returning from 'MCBinaryExpr::getRHS'
29
Assuming the condition is false
47
Returning from 'MCExpr::evaluateAsRelocatableImpl'
724 Addrs, InSet))
725 return false;
726
727 // We only support a few operations on non-constant expressions, handle
728 // those first.
729 if (!LHSValue.isAbsolute() || !RHSValue.isAbsolute()) {
31
Assuming the condition is false
32
Assuming the condition is false
33
Taking false branch
49
Taking false branch
730 switch (ABE->getOpcode()) {
731 default:
732 return false;
733 case MCBinaryExpr::Sub:
734 // Negate RHS and add.
735 // The cast avoids undefined behavior if the constant is INT64_MIN.
736 return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
737 RHSValue.getSymB(), RHSValue.getSymA(),
738 -(uint64_t)RHSValue.getConstant(), Res);
739
740 case MCBinaryExpr::Add:
741 return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
742 RHSValue.getSymA(), RHSValue.getSymB(),
743 RHSValue.getConstant(), Res);
744 }
745 }
746
747 // FIXME: We need target hooks for the evaluation. It may be limited in
748 // width, and gas defines the result of comparisons differently from
749 // Apple as.
750 int64_t LHS = LHSValue.getConstant(), RHS = RHSValue.getConstant();
34
Calling 'MCValue::getConstant'
35
Returning from 'MCValue::getConstant'
36
Calling 'MCValue::getConstant'
37
Returning from 'MCValue::getConstant'
50
Calling 'MCValue::getConstant'
52
Returning from 'MCValue::getConstant'
53
'RHS' initialized to 0
751 int64_t Result = 0;
752 switch (ABE->getOpcode()) {
38
Calling 'MCBinaryExpr::getOpcode'
39
Returning from 'MCBinaryExpr::getOpcode'
40
Control jumps to 'case LAnd:' at line 770
54
Control jumps to 'case Mod:' at line 775
753 case MCBinaryExpr::AShr: Result = LHS >> RHS; break;
754 case MCBinaryExpr::Add: Result = LHS + RHS; break;
755 case MCBinaryExpr::And: Result = LHS & RHS; break;
756 case MCBinaryExpr::Div:
757 // Handle division by zero. gas just emits a warning and keeps going,
758 // we try to be stricter.
759 // FIXME: Currently the caller of this function has no way to understand
760 // we're bailing out because of 'division by zero'. Therefore, it will
761 // emit a 'expected relocatable expression' error. It would be nice to
762 // change this code to emit a better diagnostic.
763 if (RHS == 0)
764 return false;
765 Result = LHS / RHS;
766 break;
767 case MCBinaryExpr::EQ: Result = LHS == RHS; break;
768 case MCBinaryExpr::GT: Result = LHS > RHS; break;
769 case MCBinaryExpr::GTE: Result = LHS >= RHS; break;
770 case MCBinaryExpr::LAnd: Result = LHS && RHS; break;
41
Assuming 'LHS' is 0
42
Execution continues on line 784
771 case MCBinaryExpr::LOr: Result = LHS || RHS; break;
772 case MCBinaryExpr::LShr: Result = uint64_t(LHS) >> uint64_t(RHS); break;
773 case MCBinaryExpr::LT: Result = LHS < RHS; break;
774 case MCBinaryExpr::LTE: Result = LHS <= RHS; break;
775 case MCBinaryExpr::Mod: Result = LHS % RHS; break;
55
Division by zero
776 case MCBinaryExpr::Mul: Result = LHS * RHS; break;
777 case MCBinaryExpr::NE: Result = LHS != RHS; break;
778 case MCBinaryExpr::Or: Result = LHS | RHS; break;
779 case MCBinaryExpr::Shl: Result = uint64_t(LHS) << uint64_t(RHS); break;
780 case MCBinaryExpr::Sub: Result = LHS - RHS; break;
781 case MCBinaryExpr::Xor: Result = LHS ^ RHS; break;
782 }
783
784 Res = MCValue::get(Result);
43
Calling 'MCValue::get'
46
Returning from 'MCValue::get'
785 return true;
786 }
787 }
788
789 llvm_unreachable("Invalid assembly expression kind!")::llvm::llvm_unreachable_internal("Invalid assembly expression kind!"
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp"
, 789)
;
790}
791
792MCFragment *MCExpr::findAssociatedFragment() const {
793 switch (getKind()) {
794 case Target:
795 // We never look through target specific expressions.
796 return cast<MCTargetExpr>(this)->findAssociatedFragment();
797
798 case Constant:
799 return MCSymbol::AbsolutePseudoFragment;
800
801 case SymbolRef: {
802 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
803 const MCSymbol &Sym = SRE->getSymbol();
804 return Sym.getFragment();
805 }
806
807 case Unary:
808 return cast<MCUnaryExpr>(this)->getSubExpr()->findAssociatedFragment();
809
810 case Binary: {
811 const MCBinaryExpr *BE = cast<MCBinaryExpr>(this);
812 MCFragment *LHS_F = BE->getLHS()->findAssociatedFragment();
813 MCFragment *RHS_F = BE->getRHS()->findAssociatedFragment();
814
815 // If either is absolute, return the other.
816 if (LHS_F == MCSymbol::AbsolutePseudoFragment)
817 return RHS_F;
818 if (RHS_F == MCSymbol::AbsolutePseudoFragment)
819 return LHS_F;
820
821 // Not always correct, but probably the best we can do without more context.
822 if (BE->getOpcode() == MCBinaryExpr::Sub)
823 return MCSymbol::AbsolutePseudoFragment;
824
825 // Otherwise, return the first non-null fragment.
826 return LHS_F ? LHS_F : RHS_F;
827 }
828 }
829
830 llvm_unreachable("Invalid assembly expression kind!")::llvm::llvm_unreachable_internal("Invalid assembly expression kind!"
, "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp"
, 830)
;
831}

/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/MC/MCValue.h

1//===-- llvm/MC/MCValue.h - MCValue class -----------------------*- C++ -*-===//
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// This file contains the declaration of the MCValue class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_MC_MCVALUE_H
15#define LLVM_MC_MCVALUE_H
16
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCSymbol.h"
19#include "llvm/Support/DataTypes.h"
20#include <cassert>
21
22namespace llvm {
23class MCAsmInfo;
24class raw_ostream;
25
26/// \brief This represents an "assembler immediate".
27///
28/// In its most general form, this can hold ":Kind:(SymbolA - SymbolB +
29/// imm64)". Not all targets supports relocations of this general form, but we
30/// need to represent this anyway.
31///
32/// In general both SymbolA and SymbolB will also have a modifier
33/// analogous to the top-level Kind. Current targets are not expected
34/// to make use of both though. The choice comes down to whether
35/// relocation modifiers apply to the closest symbol or the whole
36/// expression.
37///
38/// Note that this class must remain a simple POD value class, because we need
39/// it to live in unions etc.
40class MCValue {
41 const MCSymbolRefExpr *SymA = nullptr, *SymB = nullptr;
42 int64_t Cst = 0;
10
The value 0 is assigned to 'RHSValue.Cst'
43 uint32_t RefKind = 0;
44
45public:
46 MCValue() = default;
47 int64_t getConstant() const { return Cst; }
51
Returning zero
48 const MCSymbolRefExpr *getSymA() const { return SymA; }
49 const MCSymbolRefExpr *getSymB() const { return SymB; }
50 uint32_t getRefKind() const { return RefKind; }
51
52 /// \brief Is this an absolute (as opposed to relocatable) value.
53 bool isAbsolute() const { return !SymA && !SymB; }
54
55 /// \brief Print the value to the stream \p OS.
56 void print(raw_ostream &OS) const;
57
58 /// \brief Print the value to stderr.
59 void dump() const;
60
61 MCSymbolRefExpr::VariantKind getAccessVariant() const;
62
63 static MCValue get(const MCSymbolRefExpr *SymA,
64 const MCSymbolRefExpr *SymB = nullptr,
65 int64_t Val = 0, uint32_t RefKind = 0) {
66 MCValue R;
67 R.Cst = Val;
68 R.SymA = SymA;
69 R.SymB = SymB;
70 R.RefKind = RefKind;
71 return R;
72 }
73
74 static MCValue get(int64_t Val) {
75 MCValue R;
44
Calling defaulted default constructor for 'MCValue'
45
Returning from default constructor for 'MCValue'
76 R.Cst = Val;
77 R.SymA = nullptr;
78 R.SymB = nullptr;
79 R.RefKind = 0;
80 return R;
81 }
82
83};
84
85} // end namespace llvm
86
87#endif

/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/ADT/Statistic.h

1//===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===//
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// This file defines the 'Statistic' class, which is designed to be an easy way
11// to expose various metrics from passes. These statistics are printed at the
12// end of a run (from llvm_shutdown), when the -stats command line option is
13// passed on the command line.
14//
15// This is useful for reporting information like the number of instructions
16// simplified, optimized or removed by various transformations, like this:
17//
18// static Statistic NumInstsKilled("gcse", "Number of instructions killed");
19//
20// Later, in the code: ++NumInstsKilled;
21//
22// NOTE: Statistics *must* be declared as global variables.
23//
24//===----------------------------------------------------------------------===//
25
26#ifndef LLVM_ADT_STATISTIC_H
27#define LLVM_ADT_STATISTIC_H
28
29#include "llvm/Support/Compiler.h"
30#include <atomic>
31#include <memory>
32
33namespace llvm {
34
35class raw_ostream;
36class raw_fd_ostream;
37
38class Statistic {
39public:
40 const char *DebugType;
41 const char *Name;
42 const char *Desc;
43 std::atomic<unsigned> Value;
44 std::atomic<bool> Initialized;
45
46 unsigned getValue() const { return Value.load(std::memory_order_relaxed); }
47 const char *getDebugType() const { return DebugType; }
48 const char *getName() const { return Name; }
49 const char *getDesc() const { return Desc; }
50
51 /// construct - This should only be called for non-global statistics.
52 void construct(const char *debugtype, const char *name, const char *desc) {
53 DebugType = debugtype;
54 Name = name;
55 Desc = desc;
56 Value = 0;
57 Initialized = false;
58 }
59
60 // Allow use of this class as the value itself.
61 operator unsigned() const { return getValue(); }
62
63#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
64 const Statistic &operator=(unsigned Val) {
65 Value.store(Val, std::memory_order_relaxed);
66 return init();
67 }
68
69 const Statistic &operator++() {
70 Value.fetch_add(1, std::memory_order_relaxed);
14
Calling '__atomic_base::fetch_add'
15
Returning from '__atomic_base::fetch_add'
71 return init();
72 }
73
74 unsigned operator++(int) {
75 init();
76 return Value.fetch_add(1, std::memory_order_relaxed);
77 }
78
79 const Statistic &operator--() {
80 Value.fetch_sub(1, std::memory_order_relaxed);
81 return init();
82 }
83
84 unsigned operator--(int) {
85 init();
86 return Value.fetch_sub(1, std::memory_order_relaxed);
87 }
88
89 const Statistic &operator+=(unsigned V) {
90 if (V == 0)
91 return *this;
92 Value.fetch_add(V, std::memory_order_relaxed);
93 return init();
94 }
95
96 const Statistic &operator-=(unsigned V) {
97 if (V == 0)
98 return *this;
99 Value.fetch_sub(V, std::memory_order_relaxed);
100 return init();
101 }
102
103 void updateMax(unsigned V) {
104 unsigned PrevMax = Value.load(std::memory_order_relaxed);
105 // Keep trying to update max until we succeed or another thread produces
106 // a bigger max than us.
107 while (V > PrevMax && !Value.compare_exchange_weak(
108 PrevMax, V, std::memory_order_relaxed)) {
109 }
110 init();
111 }
112
113#else // Statistics are disabled in release builds.
114
115 const Statistic &operator=(unsigned Val) {
116 return *this;
117 }
118
119 const Statistic &operator++() {
120 return *this;
121 }
122
123 unsigned operator++(int) {
124 return 0;
125 }
126
127 const Statistic &operator--() {
128 return *this;
129 }
130
131 unsigned operator--(int) {
132 return 0;
133 }
134
135 const Statistic &operator+=(const unsigned &V) {
136 return *this;
137 }
138
139 const Statistic &operator-=(const unsigned &V) {
140 return *this;
141 }
142
143 void updateMax(unsigned V) {}
144
145#endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
146
147protected:
148 Statistic &init() {
149 if (!Initialized.load(std::memory_order_acquire))
150 RegisterStatistic();
151 return *this;
152 }
153
154 void RegisterStatistic();
155};
156
157// STATISTIC - A macro to make definition of statistics really simple. This
158// automatically passes the DEBUG_TYPE of the file into the statistic.
159#define STATISTIC(VARNAME, DESC)static llvm::Statistic VARNAME = {"mcexpr", "VARNAME", DESC, {
0}, {false}}
\
160 static llvm::Statistic VARNAME = {DEBUG_TYPE"mcexpr", #VARNAME, DESC, {0}, {false}}
161
162/// \brief Enable the collection and printing of statistics.
163void EnableStatistics(bool PrintOnExit = true);
164
165/// \brief Check if statistics are enabled.
166bool AreStatisticsEnabled();
167
168/// \brief Return a file stream to print our output on.
169std::unique_ptr<raw_fd_ostream> CreateInfoOutputFile();
170
171/// \brief Print statistics to the file returned by CreateInfoOutputFile().
172void PrintStatistics();
173
174/// \brief Print statistics to the given output stream.
175void PrintStatistics(raw_ostream &OS);
176
177/// Print statistics in JSON format. This does include all global timers (\see
178/// Timer, TimerGroup). Note that the timers are cleared after printing and will
179/// not be printed in human readable form or in a second call of
180/// PrintStatisticsJSON().
181void PrintStatisticsJSON(raw_ostream &OS);
182
183} // end namespace llvm
184
185#endif // LLVM_ADT_STATISTIC_H