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 20using namespace llvm; 21 22// 23// ConstantPool implementation 24// 25// Emit the contents of the constant pool using the provided streamer. 26void ConstantPool::emitEntries(MCStreamer &Streamer) { 27 if (Entries.empty()) 28 return; 29 Streamer.EmitDataRegion(MCDR_DataRegion); 30 for (const ConstantPoolEntry &Entry : Entries) { 31 Streamer.EmitCodeAlignment(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 39const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context, 40 unsigned Size, SMLoc Loc) { 41 const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Value); 42 43 // Check if there is existing entry for the same constant. If so, reuse it. 44 auto Itr = C ? CachedEntries.find(C->getValue()) : CachedEntries.end(); 45 if (Itr != CachedEntries.end()) 46 return Itr->second; 47 48 MCSymbol *CPEntryLabel = Context.createTempSymbol(); 49 50 Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc)); 51 const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context); 52 if (C) 53 CachedEntries[C->getValue()] = SymRef; 54 return SymRef; 55} 56 57bool ConstantPool::empty() { return Entries.empty(); } 58 59void ConstantPool::clearCache() { 60 CachedEntries.clear(); 61} 62 63// 64// AssemblerConstantPools implementation 65// 66ConstantPool *AssemblerConstantPools::getConstantPool(MCSection *Section) { 67 ConstantPoolMapTy::iterator CP = ConstantPools.find(Section); 68 if (CP == ConstantPools.end()) 69 return nullptr; 70 71 return &CP->second; 72} 73 74ConstantPool & 75AssemblerConstantPools::getOrCreateConstantPool(MCSection *Section) { 76 return ConstantPools[Section]; 77} 78 79static void emitConstantPool(MCStreamer &Streamer, MCSection *Section, 80 ConstantPool &CP) { 81 if (!CP.empty()) { 82 Streamer.SwitchSection(Section); 83 CP.emitEntries(Streamer); 84 } 85} 86 87void AssemblerConstantPools::emitAll(MCStreamer &Streamer) { 88 // Dump contents of assembler constant pools. 89 for (auto &CPI : ConstantPools) { 90 MCSection *Section = CPI.first; 91 ConstantPool &CP = CPI.second; 92 93 emitConstantPool(Streamer, Section, CP); 94 } 95} 96 97void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) { 98 MCSection *Section = Streamer.getCurrentSectionOnly(); 99 if (ConstantPool *CP = getConstantPool(Section)) 100 emitConstantPool(Streamer, Section, *CP); 101} 102 103void AssemblerConstantPools::clearCacheForCurrentSection(MCStreamer &Streamer) { 104 MCSection *Section = Streamer.getCurrentSectionOnly(); 105 if (ConstantPool *CP = getConstantPool(Section)) 106 CP->clearCache(); 107} 108 109const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer, 110 const MCExpr *Expr, 111 unsigned Size, SMLoc Loc) { 112 MCSection *Section = Streamer.getCurrentSectionOnly(); 113 return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(), 114 Size, Loc); 115} 116