/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/MC/ConstantPools.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- ConstantPools.cpp - ConstantPool class -----------------------------===// |
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 implements the ConstantPool and AssemblerConstantPools classes. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "llvm/MC/ConstantPools.h" |
15 | | #include "llvm/MC/MCContext.h" |
16 | | #include "llvm/MC/MCDirectives.h" |
17 | | #include "llvm/MC/MCExpr.h" |
18 | | #include "llvm/MC/MCStreamer.h" |
19 | | #include "llvm/Support/Casting.h" |
20 | | |
21 | | using namespace llvm; |
22 | | |
23 | | // |
24 | | // ConstantPool implementation |
25 | | // |
26 | | // Emit the contents of the constant pool using the provided streamer. |
27 | 190 | void ConstantPool::emitEntries(MCStreamer &Streamer) { |
28 | 190 | if (Entries.empty()) |
29 | 0 | return; |
30 | 190 | Streamer.EmitDataRegion(MCDR_DataRegion); |
31 | 298 | for (const ConstantPoolEntry &Entry : Entries) { |
32 | 298 | Streamer.EmitCodeAlignment(Entry.Size); // align naturally |
33 | 298 | Streamer.EmitLabel(Entry.Label); |
34 | 298 | Streamer.EmitValue(Entry.Value, Entry.Size, Entry.Loc); |
35 | 298 | } |
36 | 190 | Streamer.EmitDataRegion(MCDR_DataRegionEnd); |
37 | 190 | Entries.clear(); |
38 | 190 | } |
39 | | |
40 | | const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context, |
41 | 322 | unsigned Size, SMLoc Loc) { |
42 | 322 | const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Value); |
43 | 322 | |
44 | 322 | // Check if there is existing entry for the same constant. If so, reuse it. |
45 | 322 | auto Itr = C ? CachedEntries.find(C->getValue())233 : CachedEntries.end()89 ; |
46 | 322 | if (Itr != CachedEntries.end()) |
47 | 20 | return Itr->second; |
48 | 302 | |
49 | 302 | MCSymbol *CPEntryLabel = Context.createTempSymbol(); |
50 | 302 | |
51 | 302 | Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc)); |
52 | 302 | const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context); |
53 | 302 | if (C) |
54 | 213 | CachedEntries[C->getValue()] = SymRef; |
55 | 322 | return SymRef; |
56 | 322 | } |
57 | | |
58 | 210 | bool ConstantPool::empty() { return Entries.empty(); } |
59 | | |
60 | 34 | void ConstantPool::clearCache() { |
61 | 34 | CachedEntries.clear(); |
62 | 34 | } |
63 | | |
64 | | // |
65 | | // AssemblerConstantPools implementation |
66 | | // |
67 | 88 | ConstantPool *AssemblerConstantPools::getConstantPool(MCSection *Section) { |
68 | 88 | ConstantPoolMapTy::iterator CP = ConstantPools.find(Section); |
69 | 88 | if (CP == ConstantPools.end()) |
70 | 20 | return nullptr; |
71 | 68 | |
72 | 68 | return &CP->second; |
73 | 68 | } |
74 | | |
75 | | ConstantPool & |
76 | 322 | AssemblerConstantPools::getOrCreateConstantPool(MCSection *Section) { |
77 | 322 | return ConstantPools[Section]; |
78 | 322 | } |
79 | | |
80 | | static void emitConstantPool(MCStreamer &Streamer, MCSection *Section, |
81 | 210 | ConstantPool &CP) { |
82 | 210 | if (!CP.empty()210 ) { |
83 | 190 | Streamer.SwitchSection(Section); |
84 | 190 | CP.emitEntries(Streamer); |
85 | 190 | } |
86 | 210 | } |
87 | | |
88 | 6.97k | void AssemblerConstantPools::emitAll(MCStreamer &Streamer) { |
89 | 6.97k | // Dump contents of assembler constant pools. |
90 | 176 | for (auto &CPI : ConstantPools) { |
91 | 176 | MCSection *Section = CPI.first; |
92 | 176 | ConstantPool &CP = CPI.second; |
93 | 176 | |
94 | 176 | emitConstantPool(Streamer, Section, CP); |
95 | 176 | } |
96 | 6.97k | } |
97 | | |
98 | 44 | void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) { |
99 | 44 | MCSection *Section = Streamer.getCurrentSectionOnly(); |
100 | 44 | if (ConstantPool *CP44 = getConstantPool(Section)) { |
101 | 34 | emitConstantPool(Streamer, Section, *CP); |
102 | 34 | } |
103 | 44 | } |
104 | | |
105 | 44 | void AssemblerConstantPools::clearCacheForCurrentSection(MCStreamer &Streamer) { |
106 | 44 | MCSection *Section = Streamer.getCurrentSectionOnly(); |
107 | 44 | if (ConstantPool *CP44 = getConstantPool(Section)) { |
108 | 34 | CP->clearCache(); |
109 | 34 | } |
110 | 44 | } |
111 | | |
112 | | const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer, |
113 | | const MCExpr *Expr, |
114 | 322 | unsigned Size, SMLoc Loc) { |
115 | 322 | MCSection *Section = Streamer.getCurrentSectionOnly(); |
116 | 322 | return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(), |
117 | 322 | Size, Loc); |
118 | 322 | } |