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