1//===-- LLVMContextImpl.cpp - Implement LLVMContextImpl -------------------===//
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 opaque LLVMContextImpl.
11//
12//===----------------------------------------------------------------------===//
13
14#include "LLVMContextImpl.h"
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/IR/Attributes.h"
17#include "llvm/IR/DiagnosticInfo.h"
18#include "llvm/IR/Module.h"
19#include <algorithm>
20using namespace llvm;
21
22LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
23  : TheTrueVal(nullptr), TheFalseVal(nullptr),
24    VoidTy(C, Type::VoidTyID),
25    LabelTy(C, Type::LabelTyID),
26    HalfTy(C, Type::HalfTyID),
27    FloatTy(C, Type::FloatTyID),
28    DoubleTy(C, Type::DoubleTyID),
29    MetadataTy(C, Type::MetadataTyID),
30    TokenTy(C, Type::TokenTyID),
31    X86_FP80Ty(C, Type::X86_FP80TyID),
32    FP128Ty(C, Type::FP128TyID),
33    PPC_FP128Ty(C, Type::PPC_FP128TyID),
34    X86_MMXTy(C, Type::X86_MMXTyID),
35    Int1Ty(C, 1),
36    Int8Ty(C, 8),
37    Int16Ty(C, 16),
38    Int32Ty(C, 32),
39    Int64Ty(C, 64),
40    Int128Ty(C, 128) {
41  InlineAsmDiagHandler = nullptr;
42  InlineAsmDiagContext = nullptr;
43  DiagnosticHandler = nullptr;
44  DiagnosticContext = nullptr;
45  RespectDiagnosticFilters = false;
46  YieldCallback = nullptr;
47  YieldOpaqueHandle = nullptr;
48  NamedStructTypesUniqueID = 0;
49}
50
51namespace {
52struct DropReferences {
53  // Takes the value_type of a ConstantUniqueMap's internal map, whose 'second'
54  // is a Constant*.
55  template <typename PairT> void operator()(const PairT &P) {
56    P.second->dropAllReferences();
57  }
58};
59
60// Temporary - drops pair.first instead of second.
61struct DropFirst {
62  // Takes the value_type of a ConstantUniqueMap's internal map, whose 'second'
63  // is a Constant*.
64  template<typename PairT>
65  void operator()(const PairT &P) {
66    P.first->dropAllReferences();
67  }
68};
69}
70
71LLVMContextImpl::~LLVMContextImpl() {
72  // NOTE: We need to delete the contents of OwnedModules, but Module's dtor
73  // will call LLVMContextImpl::removeModule, thus invalidating iterators into
74  // the container. Avoid iterators during this operation:
75  while (!OwnedModules.empty())
76    delete *OwnedModules.begin();
77
78  // Drop references for MDNodes.  Do this before Values get deleted to avoid
79  // unnecessary RAUW when nodes are still unresolved.
80  for (auto *I : DistinctMDNodes)
81    I->dropAllReferences();
82#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)                                    \
83  for (auto *I : CLASS##s)                                                     \
84    I->dropAllReferences();
85#include "llvm/IR/Metadata.def"
86
87  // Also drop references that come from the Value bridges.
88  for (auto &Pair : ValuesAsMetadata)
89    Pair.second->dropUsers();
90  for (auto &Pair : MetadataAsValues)
91    Pair.second->dropUse();
92
93  // Destroy MDNodes.
94  for (MDNode *I : DistinctMDNodes)
95    I->deleteAsSubclass();
96#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)                                    \
97  for (CLASS * I : CLASS##s)                                                   \
98    delete I;
99#include "llvm/IR/Metadata.def"
100
101  // Free the constants.
102  std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(),
103                DropFirst());
104  std::for_each(ArrayConstants.map_begin(), ArrayConstants.map_end(),
105                DropFirst());
106  std::for_each(StructConstants.map_begin(), StructConstants.map_end(),
107                DropFirst());
108  std::for_each(VectorConstants.map_begin(), VectorConstants.map_end(),
109                DropFirst());
110  ExprConstants.freeConstants();
111  ArrayConstants.freeConstants();
112  StructConstants.freeConstants();
113  VectorConstants.freeConstants();
114  DeleteContainerSeconds(CAZConstants);
115  DeleteContainerSeconds(CPNConstants);
116  DeleteContainerSeconds(UVConstants);
117  InlineAsms.freeConstants();
118  DeleteContainerSeconds(IntConstants);
119  DeleteContainerSeconds(FPConstants);
120
121  for (StringMap<ConstantDataSequential*>::iterator I = CDSConstants.begin(),
122       E = CDSConstants.end(); I != E; ++I)
123    delete I->second;
124  CDSConstants.clear();
125
126  // Destroy attributes.
127  for (FoldingSetIterator<AttributeImpl> I = AttrsSet.begin(),
128         E = AttrsSet.end(); I != E; ) {
129    FoldingSetIterator<AttributeImpl> Elem = I++;
130    delete &*Elem;
131  }
132
133  // Destroy attribute lists.
134  for (FoldingSetIterator<AttributeSetImpl> I = AttrsLists.begin(),
135         E = AttrsLists.end(); I != E; ) {
136    FoldingSetIterator<AttributeSetImpl> Elem = I++;
137    delete &*Elem;
138  }
139
140  // Destroy attribute node lists.
141  for (FoldingSetIterator<AttributeSetNode> I = AttrsSetNodes.begin(),
142         E = AttrsSetNodes.end(); I != E; ) {
143    FoldingSetIterator<AttributeSetNode> Elem = I++;
144    delete &*Elem;
145  }
146
147  // Destroy MetadataAsValues.
148  {
149    SmallVector<MetadataAsValue *, 8> MDVs;
150    MDVs.reserve(MetadataAsValues.size());
151    for (auto &Pair : MetadataAsValues)
152      MDVs.push_back(Pair.second);
153    MetadataAsValues.clear();
154    for (auto *V : MDVs)
155      delete V;
156  }
157
158  // Destroy ValuesAsMetadata.
159  for (auto &Pair : ValuesAsMetadata)
160    delete Pair.second;
161
162  // Destroy MDStrings.
163  MDStringCache.clear();
164}
165
166void LLVMContextImpl::dropTriviallyDeadConstantArrays() {
167  bool Changed;
168  do {
169    Changed = false;
170
171    for (auto I = ArrayConstants.map_begin(), E = ArrayConstants.map_end();
172         I != E; ) {
173      auto *C = I->first;
174      I++;
175      if (C->use_empty()) {
176        Changed = true;
177        C->destroyConstant();
178      }
179    }
180
181  } while (Changed);
182}
183
184void Module::dropTriviallyDeadConstantArrays() {
185  Context.pImpl->dropTriviallyDeadConstantArrays();
186}
187
188namespace llvm {
189/// \brief Make MDOperand transparent for hashing.
190///
191/// This overload of an implementation detail of the hashing library makes
192/// MDOperand hash to the same value as a \a Metadata pointer.
193///
194/// Note that overloading \a hash_value() as follows:
195///
196/// \code
197///     size_t hash_value(const MDOperand &X) { return hash_value(X.get()); }
198/// \endcode
199///
200/// does not cause MDOperand to be transparent.  In particular, a bare pointer
201/// doesn't get hashed before it's combined, whereas \a MDOperand would.
202static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }
203}
204
205unsigned MDNodeOpsKey::calculateHash(MDNode *N, unsigned Offset) {
206  unsigned Hash = hash_combine_range(N->op_begin() + Offset, N->op_end());
207#ifndef NDEBUG
208  {
209    SmallVector<Metadata *, 8> MDs(N->op_begin() + Offset, N->op_end());
210    unsigned RawHash = calculateHash(MDs);
211    assert(Hash == RawHash &&
212           "Expected hash of MDOperand to equal hash of Metadata*");
213  }
214#endif
215  return Hash;
216}
217
218unsigned MDNodeOpsKey::calculateHash(ArrayRef<Metadata *> Ops) {
219  return hash_combine_range(Ops.begin(), Ops.end());
220}
221
222StringMapEntry<uint32_t> *LLVMContextImpl::getOrInsertBundleTag(StringRef Tag) {
223  uint32_t NewIdx = BundleTagCache.size();
224  return &*(BundleTagCache.insert(std::make_pair(Tag, NewIdx)).first);
225}
226
227void LLVMContextImpl::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
228  Tags.resize(BundleTagCache.size());
229  for (const auto &T : BundleTagCache)
230    Tags[T.second] = T.first();
231}
232
233uint32_t LLVMContextImpl::getOperandBundleTagID(StringRef Tag) const {
234  auto I = BundleTagCache.find(Tag);
235  assert(I != BundleTagCache.end() && "Unknown tag!");
236  return I->second;
237}
238
239// ConstantsContext anchors
240void UnaryConstantExpr::anchor() { }
241
242void BinaryConstantExpr::anchor() { }
243
244void SelectConstantExpr::anchor() { }
245
246void ExtractElementConstantExpr::anchor() { }
247
248void InsertElementConstantExpr::anchor() { }
249
250void ShuffleVectorConstantExpr::anchor() { }
251
252void ExtractValueConstantExpr::anchor() { }
253
254void InsertValueConstantExpr::anchor() { }
255
256void GetElementPtrConstantExpr::anchor() { }
257
258void CompareConstantExpr::anchor() { }
259
260