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 
19 using namespace llvm;
20 //
21 // ConstantPool implementation
22 //
23 // Emit the contents of the constant pool using the provided streamer.
emitEntries(MCStreamer & Streamer)24 void 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, I->Loc);
33   }
34   Streamer.EmitDataRegion(MCDR_DataRegionEnd);
35   Entries.clear();
36 }
37 
addEntry(const MCExpr * Value,MCContext & Context,unsigned Size,SMLoc Loc)38 const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context,
39                                      unsigned Size, SMLoc Loc) {
40   MCSymbol *CPEntryLabel = Context.createTempSymbol();
41 
42   Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc));
43   return MCSymbolRefExpr::create(CPEntryLabel, Context);
44 }
45 
empty()46 bool ConstantPool::empty() { return Entries.empty(); }
47 
48 //
49 // AssemblerConstantPools implementation
50 //
getConstantPool(MCSection * Section)51 ConstantPool *AssemblerConstantPools::getConstantPool(MCSection *Section) {
52   ConstantPoolMapTy::iterator CP = ConstantPools.find(Section);
53   if (CP == ConstantPools.end())
54     return nullptr;
55 
56   return &CP->second;
57 }
58 
59 ConstantPool &
getOrCreateConstantPool(MCSection * Section)60 AssemblerConstantPools::getOrCreateConstantPool(MCSection *Section) {
61   return ConstantPools[Section];
62 }
63 
emitConstantPool(MCStreamer & Streamer,MCSection * Section,ConstantPool & CP)64 static void emitConstantPool(MCStreamer &Streamer, MCSection *Section,
65                              ConstantPool &CP) {
66   if (!CP.empty()) {
67     Streamer.SwitchSection(Section);
68     CP.emitEntries(Streamer);
69   }
70 }
71 
emitAll(MCStreamer & Streamer)72 void AssemblerConstantPools::emitAll(MCStreamer &Streamer) {
73   // Dump contents of assembler constant pools.
74   for (ConstantPoolMapTy::iterator CPI = ConstantPools.begin(),
75                                    CPE = ConstantPools.end();
76        CPI != CPE; ++CPI) {
77     MCSection *Section = CPI->first;
78     ConstantPool &CP = CPI->second;
79 
80     emitConstantPool(Streamer, Section, CP);
81   }
82 }
83 
emitForCurrentSection(MCStreamer & Streamer)84 void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) {
85   MCSection *Section = Streamer.getCurrentSection().first;
86   if (ConstantPool *CP = getConstantPool(Section)) {
87     emitConstantPool(Streamer, Section, *CP);
88   }
89 }
90 
addEntry(MCStreamer & Streamer,const MCExpr * Expr,unsigned Size,SMLoc Loc)91 const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer,
92                                                const MCExpr *Expr,
93                                                unsigned Size, SMLoc Loc) {
94   MCSection *Section = Streamer.getCurrentSection().first;
95   return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(),
96                                                    Size, Loc);
97 }
98