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