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