Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/MC/ConstantPools.cpp
35233 views
1
//===- ConstantPools.cpp - ConstantPool class -----------------------------===//
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
// This file implements the ConstantPool and AssemblerConstantPools classes.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/MC/ConstantPools.h"
14
#include "llvm/MC/MCContext.h"
15
#include "llvm/MC/MCDirectives.h"
16
#include "llvm/MC/MCExpr.h"
17
#include "llvm/MC/MCStreamer.h"
18
#include "llvm/Support/Casting.h"
19
20
using namespace llvm;
21
22
//
23
// ConstantPool implementation
24
//
25
// Emit the contents of the constant pool using the provided streamer.
26
void ConstantPool::emitEntries(MCStreamer &Streamer) {
27
if (Entries.empty())
28
return;
29
Streamer.emitDataRegion(MCDR_DataRegion);
30
for (const ConstantPoolEntry &Entry : Entries) {
31
Streamer.emitValueToAlignment(Align(Entry.Size)); // align naturally
32
Streamer.emitLabel(Entry.Label);
33
Streamer.emitValue(Entry.Value, Entry.Size, Entry.Loc);
34
}
35
Streamer.emitDataRegion(MCDR_DataRegionEnd);
36
Entries.clear();
37
}
38
39
const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context,
40
unsigned Size, SMLoc Loc) {
41
const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Value);
42
const MCSymbolRefExpr *S = dyn_cast<MCSymbolRefExpr>(Value);
43
44
// Check if there is existing entry for the same constant. If so, reuse it.
45
if (C) {
46
auto CItr = CachedConstantEntries.find(std::make_pair(C->getValue(), Size));
47
if (CItr != CachedConstantEntries.end())
48
return CItr->second;
49
}
50
51
// Check if there is existing entry for the same symbol. If so, reuse it.
52
if (S) {
53
auto SItr =
54
CachedSymbolEntries.find(std::make_pair(&(S->getSymbol()), Size));
55
if (SItr != CachedSymbolEntries.end())
56
return SItr->second;
57
}
58
59
MCSymbol *CPEntryLabel = Context.createTempSymbol();
60
61
Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc));
62
const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context);
63
if (C)
64
CachedConstantEntries[std::make_pair(C->getValue(), Size)] = SymRef;
65
if (S)
66
CachedSymbolEntries[std::make_pair(&(S->getSymbol()), Size)] = SymRef;
67
return SymRef;
68
}
69
70
bool ConstantPool::empty() { return Entries.empty(); }
71
72
void ConstantPool::clearCache() {
73
CachedConstantEntries.clear();
74
CachedSymbolEntries.clear();
75
}
76
77
//
78
// AssemblerConstantPools implementation
79
//
80
ConstantPool *AssemblerConstantPools::getConstantPool(MCSection *Section) {
81
ConstantPoolMapTy::iterator CP = ConstantPools.find(Section);
82
if (CP == ConstantPools.end())
83
return nullptr;
84
85
return &CP->second;
86
}
87
88
ConstantPool &
89
AssemblerConstantPools::getOrCreateConstantPool(MCSection *Section) {
90
return ConstantPools[Section];
91
}
92
93
static void emitConstantPool(MCStreamer &Streamer, MCSection *Section,
94
ConstantPool &CP) {
95
if (!CP.empty()) {
96
Streamer.switchSection(Section);
97
CP.emitEntries(Streamer);
98
}
99
}
100
101
void AssemblerConstantPools::emitAll(MCStreamer &Streamer) {
102
// Dump contents of assembler constant pools.
103
for (auto &CPI : ConstantPools) {
104
MCSection *Section = CPI.first;
105
ConstantPool &CP = CPI.second;
106
107
emitConstantPool(Streamer, Section, CP);
108
}
109
}
110
111
void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) {
112
MCSection *Section = Streamer.getCurrentSectionOnly();
113
if (ConstantPool *CP = getConstantPool(Section))
114
emitConstantPool(Streamer, Section, *CP);
115
}
116
117
void AssemblerConstantPools::clearCacheForCurrentSection(MCStreamer &Streamer) {
118
MCSection *Section = Streamer.getCurrentSectionOnly();
119
if (ConstantPool *CP = getConstantPool(Section))
120
CP->clearCache();
121
}
122
123
const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer,
124
const MCExpr *Expr,
125
unsigned Size, SMLoc Loc) {
126
MCSection *Section = Streamer.getCurrentSectionOnly();
127
return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(),
128
Size, Loc);
129
}
130
131