1321369Sdim//===- ConstantPools.cpp - ConstantPool class -----------------------------===// 2274955Ssvnmir// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6274955Ssvnmir// 7274955Ssvnmir//===----------------------------------------------------------------------===// 8274955Ssvnmir// 9274955Ssvnmir// This file implements the ConstantPool and AssemblerConstantPools classes. 10274955Ssvnmir// 11274955Ssvnmir//===----------------------------------------------------------------------===// 12321369Sdim 13280031Sdim#include "llvm/MC/ConstantPools.h" 14274955Ssvnmir#include "llvm/MC/MCContext.h" 15321369Sdim#include "llvm/MC/MCDirectives.h" 16274955Ssvnmir#include "llvm/MC/MCExpr.h" 17274955Ssvnmir#include "llvm/MC/MCStreamer.h" 18321369Sdim#include "llvm/Support/Casting.h" 19274955Ssvnmir 20274955Ssvnmirusing namespace llvm; 21321369Sdim 22274955Ssvnmir// 23274955Ssvnmir// ConstantPool implementation 24274955Ssvnmir// 25274955Ssvnmir// Emit the contents of the constant pool using the provided streamer. 26274955Ssvnmirvoid ConstantPool::emitEntries(MCStreamer &Streamer) { 27274955Ssvnmir if (Entries.empty()) 28274955Ssvnmir return; 29274955Ssvnmir Streamer.EmitDataRegion(MCDR_DataRegion); 30309124Sdim for (const ConstantPoolEntry &Entry : Entries) { 31309124Sdim Streamer.EmitCodeAlignment(Entry.Size); // align naturally 32309124Sdim Streamer.EmitLabel(Entry.Label); 33309124Sdim Streamer.EmitValue(Entry.Value, Entry.Size, Entry.Loc); 34274955Ssvnmir } 35274955Ssvnmir Streamer.EmitDataRegion(MCDR_DataRegionEnd); 36274955Ssvnmir Entries.clear(); 37274955Ssvnmir} 38274955Ssvnmir 39274955Ssvnmirconst MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context, 40296417Sdim unsigned Size, SMLoc Loc) { 41314564Sdim const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Value); 42314564Sdim 43314564Sdim // Check if there is existing entry for the same constant. If so, reuse it. 44314564Sdim auto Itr = C ? CachedEntries.find(C->getValue()) : CachedEntries.end(); 45314564Sdim if (Itr != CachedEntries.end()) 46314564Sdim return Itr->second; 47314564Sdim 48288943Sdim MCSymbol *CPEntryLabel = Context.createTempSymbol(); 49274955Ssvnmir 50296417Sdim Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc)); 51314564Sdim const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context); 52314564Sdim if (C) 53314564Sdim CachedEntries[C->getValue()] = SymRef; 54314564Sdim return SymRef; 55274955Ssvnmir} 56274955Ssvnmir 57274955Ssvnmirbool ConstantPool::empty() { return Entries.empty(); } 58274955Ssvnmir 59318655Sdimvoid ConstantPool::clearCache() { 60318655Sdim CachedEntries.clear(); 61318655Sdim} 62318655Sdim 63274955Ssvnmir// 64274955Ssvnmir// AssemblerConstantPools implementation 65274955Ssvnmir// 66288943SdimConstantPool *AssemblerConstantPools::getConstantPool(MCSection *Section) { 67274955Ssvnmir ConstantPoolMapTy::iterator CP = ConstantPools.find(Section); 68274955Ssvnmir if (CP == ConstantPools.end()) 69274955Ssvnmir return nullptr; 70274955Ssvnmir 71274955Ssvnmir return &CP->second; 72274955Ssvnmir} 73274955Ssvnmir 74274955SsvnmirConstantPool & 75288943SdimAssemblerConstantPools::getOrCreateConstantPool(MCSection *Section) { 76274955Ssvnmir return ConstantPools[Section]; 77274955Ssvnmir} 78274955Ssvnmir 79288943Sdimstatic void emitConstantPool(MCStreamer &Streamer, MCSection *Section, 80274955Ssvnmir ConstantPool &CP) { 81274955Ssvnmir if (!CP.empty()) { 82274955Ssvnmir Streamer.SwitchSection(Section); 83274955Ssvnmir CP.emitEntries(Streamer); 84274955Ssvnmir } 85274955Ssvnmir} 86274955Ssvnmir 87274955Ssvnmirvoid AssemblerConstantPools::emitAll(MCStreamer &Streamer) { 88274955Ssvnmir // Dump contents of assembler constant pools. 89309124Sdim for (auto &CPI : ConstantPools) { 90309124Sdim MCSection *Section = CPI.first; 91309124Sdim ConstantPool &CP = CPI.second; 92274955Ssvnmir 93274955Ssvnmir emitConstantPool(Streamer, Section, CP); 94274955Ssvnmir } 95274955Ssvnmir} 96274955Ssvnmir 97274955Ssvnmirvoid AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) { 98314564Sdim MCSection *Section = Streamer.getCurrentSectionOnly(); 99344779Sdim if (ConstantPool *CP = getConstantPool(Section)) 100274955Ssvnmir emitConstantPool(Streamer, Section, *CP); 101274955Ssvnmir} 102274955Ssvnmir 103318655Sdimvoid AssemblerConstantPools::clearCacheForCurrentSection(MCStreamer &Streamer) { 104318655Sdim MCSection *Section = Streamer.getCurrentSectionOnly(); 105344779Sdim if (ConstantPool *CP = getConstantPool(Section)) 106318655Sdim CP->clearCache(); 107318655Sdim} 108318655Sdim 109274955Ssvnmirconst MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer, 110274955Ssvnmir const MCExpr *Expr, 111296417Sdim unsigned Size, SMLoc Loc) { 112314564Sdim MCSection *Section = Streamer.getCurrentSectionOnly(); 113274955Ssvnmir return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(), 114296417Sdim Size, Loc); 115274955Ssvnmir} 116