1//===- ConstantPools.cpp - ConstantPool 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 implements the ConstantPool and  AssemblerConstantPools classes.
11//
12//===----------------------------------------------------------------------===//
13#include "llvm/ADT/MapVector.h"
14#include "llvm/MC/ConstantPools.h"
15#include "llvm/MC/MCContext.h"
16#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCStreamer.h"
18
19using namespace llvm;
20//
21// ConstantPool implementation
22//
23// Emit the contents of the constant pool using the provided streamer.
24void ConstantPool::emitEntries(MCStreamer &Streamer) {
25  if (Entries.empty())
26    return;
27  Streamer.EmitDataRegion(MCDR_DataRegion);
28  for (EntryVecTy::const_iterator I = Entries.begin(), E = Entries.end();
29       I != E; ++I) {
30    Streamer.EmitCodeAlignment(I->Size); // align naturally
31    Streamer.EmitLabel(I->Label);
32    Streamer.EmitValue(I->Value, I->Size);
33  }
34  Streamer.EmitDataRegion(MCDR_DataRegionEnd);
35  Entries.clear();
36}
37
38const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context,
39                                     unsigned Size) {
40  MCSymbol *CPEntryLabel = Context.CreateTempSymbol();
41
42  Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size));
43  return MCSymbolRefExpr::Create(CPEntryLabel, Context);
44}
45
46bool ConstantPool::empty() { return Entries.empty(); }
47
48//
49// AssemblerConstantPools implementation
50//
51ConstantPool *
52AssemblerConstantPools::getConstantPool(const MCSection *Section) {
53  ConstantPoolMapTy::iterator CP = ConstantPools.find(Section);
54  if (CP == ConstantPools.end())
55    return nullptr;
56
57  return &CP->second;
58}
59
60ConstantPool &
61AssemblerConstantPools::getOrCreateConstantPool(const MCSection *Section) {
62  return ConstantPools[Section];
63}
64
65static void emitConstantPool(MCStreamer &Streamer, const MCSection *Section,
66                             ConstantPool &CP) {
67  if (!CP.empty()) {
68    Streamer.SwitchSection(Section);
69    CP.emitEntries(Streamer);
70  }
71}
72
73void AssemblerConstantPools::emitAll(MCStreamer &Streamer) {
74  // Dump contents of assembler constant pools.
75  for (ConstantPoolMapTy::iterator CPI = ConstantPools.begin(),
76                                   CPE = ConstantPools.end();
77       CPI != CPE; ++CPI) {
78    const MCSection *Section = CPI->first;
79    ConstantPool &CP = CPI->second;
80
81    emitConstantPool(Streamer, Section, CP);
82  }
83}
84
85void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) {
86  const MCSection *Section = Streamer.getCurrentSection().first;
87  if (ConstantPool *CP = getConstantPool(Section)) {
88    emitConstantPool(Streamer, Section, *CP);
89  }
90}
91
92const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer,
93                                               const MCExpr *Expr,
94                                               unsigned Size) {
95  const MCSection *Section = Streamer.getCurrentSection().first;
96  return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(),
97                                                   Size);
98}
99