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