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(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 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 57 bool ConstantPool::empty() { return Entries.empty(); } 58 59 void ConstantPool::clearCache() { 60 CachedEntries.clear(); 61 } 62 63 // 64 // AssemblerConstantPools implementation 65 // 66 ConstantPool *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 74 ConstantPool & 75 AssemblerConstantPools::getOrCreateConstantPool(MCSection *Section) { 76 return ConstantPools[Section]; 77 } 78 79 static void emitConstantPool(MCStreamer &Streamer, MCSection *Section, 80 ConstantPool &CP) { 81 if (!CP.empty()) { 82 Streamer.SwitchSection(Section); 83 CP.emitEntries(Streamer); 84 } 85 } 86 87 void 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 97 void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) { 98 MCSection *Section = Streamer.getCurrentSectionOnly(); 99 if (ConstantPool *CP = getConstantPool(Section)) 100 emitConstantPool(Streamer, Section, *CP); 101 } 102 103 void AssemblerConstantPools::clearCacheForCurrentSection(MCStreamer &Streamer) { 104 MCSection *Section = Streamer.getCurrentSectionOnly(); 105 if (ConstantPool *CP = getConstantPool(Section)) 106 CP->clearCache(); 107 } 108 109 const 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