LLVMContextImpl.h revision f53c371983908f02678b0e12c5d18466dcc70ffd
1//===----------------- LLVMContextImpl.h - Implementation ------*- 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 declares LLVMContextImpl, the opaque implementation
11//  of LLVMContext.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_LLVMCONTEXT_IMPL_H
16#define LLVM_LLVMCONTEXT_IMPL_H
17
18#include "llvm/LLVMContext.h"
19#include "llvm/DerivedTypes.h"
20#include "llvm/System/RWMutex.h"
21#include "llvm/ADT/APFloat.h"
22#include "llvm/ADT/APInt.h"
23#include "llvm/ADT/DenseMap.h"
24#include "llvm/ADT/FoldingSet.h"
25#include "llvm/ADT/StringMap.h"
26
27namespace llvm {
28
29class ConstantInt;
30class ConstantFP;
31class MDString;
32class MDNode;
33class LLVMContext;
34class Type;
35class Value;
36
37struct DenseMapAPIntKeyInfo {
38  struct KeyTy {
39    APInt val;
40    const Type* type;
41    KeyTy(const APInt& V, const Type* Ty) : val(V), type(Ty) {}
42    KeyTy(const KeyTy& that) : val(that.val), type(that.type) {}
43    bool operator==(const KeyTy& that) const {
44      return type == that.type && this->val == that.val;
45    }
46    bool operator!=(const KeyTy& that) const {
47      return !this->operator==(that);
48    }
49  };
50  static inline KeyTy getEmptyKey() { return KeyTy(APInt(1,0), 0); }
51  static inline KeyTy getTombstoneKey() { return KeyTy(APInt(1,1), 0); }
52  static unsigned getHashValue(const KeyTy &Key) {
53    return DenseMapInfo<void*>::getHashValue(Key.type) ^
54      Key.val.getHashValue();
55  }
56  static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
57    return LHS == RHS;
58  }
59  static bool isPod() { return false; }
60};
61
62struct DenseMapAPFloatKeyInfo {
63  struct KeyTy {
64    APFloat val;
65    KeyTy(const APFloat& V) : val(V){}
66    KeyTy(const KeyTy& that) : val(that.val) {}
67    bool operator==(const KeyTy& that) const {
68      return this->val.bitwiseIsEqual(that.val);
69    }
70    bool operator!=(const KeyTy& that) const {
71      return !this->operator==(that);
72    }
73  };
74  static inline KeyTy getEmptyKey() {
75    return KeyTy(APFloat(APFloat::Bogus,1));
76  }
77  static inline KeyTy getTombstoneKey() {
78    return KeyTy(APFloat(APFloat::Bogus,2));
79  }
80  static unsigned getHashValue(const KeyTy &Key) {
81    return Key.val.getHashValue();
82  }
83  static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
84    return LHS == RHS;
85  }
86  static bool isPod() { return false; }
87};
88
89class LLVMContextImpl {
90  sys::SmartRWMutex<true> ConstantsLock;
91
92  typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*,
93                   DenseMapAPIntKeyInfo> IntMapTy;
94  IntMapTy IntConstants;
95
96  typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*,
97                   DenseMapAPFloatKeyInfo> FPMapTy;
98  FPMapTy FPConstants;
99
100  StringMap<MDString*> MDStringCache;
101
102  FoldingSet<MDNode> MDNodeSet;
103
104  LLVMContext &Context;
105  ConstantInt *TheTrueVal;
106  ConstantInt *TheFalseVal;
107
108  LLVMContextImpl();
109  LLVMContextImpl(const LLVMContextImpl&);
110public:
111  LLVMContextImpl(LLVMContext &C) : Context(C), TheTrueVal(0), TheFalseVal(0) {}
112
113  /// Return a ConstantInt with the specified value and an implied Type. The
114  /// type is the integer type that corresponds to the bit width of the value.
115  ConstantInt *getConstantInt(const APInt &V);
116
117  ConstantFP *getConstantFP(const APFloat &V);
118
119  MDString *getMDString(const char *StrBegin, const char *StrEnd);
120
121  MDNode *getMDNode(Value*const* Vals, unsigned NumVals);
122
123  ConstantInt *getConstantIntTrue() {
124    if (TheTrueVal)
125      return TheTrueVal;
126    else
127      return (TheTrueVal = Context.getConstantInt(IntegerType::get(1), 1));
128  }
129
130  ConstantInt *getConstantIntFalse() {
131    if (TheFalseVal)
132      return TheFalseVal;
133    else
134      return (TheFalseVal = Context.getConstantInt(IntegerType::get(1), 0));
135  }
136
137  void erase(MDString *M);
138  void erase(MDNode *M);
139};
140
141}
142
143#endif
144