Privatize the ConstantFP table. I'm on a roll!
authorOwen Anderson <resistor@mac.com>
Thu, 16 Jul 2009 19:05:41 +0000 (19:05 +0000)
committerOwen Anderson <resistor@mac.com>
Thu, 16 Jul 2009 19:05:41 +0000 (19:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76097 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
docs/tutorial/LangImpl3.html
docs/tutorial/LangImpl4.html
docs/tutorial/LangImpl5.html
docs/tutorial/LangImpl6.html
docs/tutorial/LangImpl7.html
examples/Kaleidoscope/toy.cpp
include/llvm/Constants.h
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
lib/VMCore/Constants.cpp
lib/VMCore/LLVMContext.cpp
lib/VMCore/LLVMContextImpl.cpp
lib/VMCore/LLVMContextImpl.h

index 5028a639de34554e040531585ece696b7451a3e7..499b4c20a73d16ccf9271c6576a7f23aad6eac70 100644 (file)
@@ -159,7 +159,7 @@ we'll do numeric literals:</p>
 <div class="doc_code">
 <pre>
 Value *NumberExprAST::Codegen() {
-  return ConstantFP::get(APFloat(Val));
+  return getGlobalContext().getConstantFP(APFloat(Val));
 }
 </pre>
 </div>
@@ -170,7 +170,7 @@ internally (<tt>APFloat</tt> has the capability of holding floating point
 constants of <em>A</em>rbitrary <em>P</em>recision).  This code basically just
 creates and returns a <tt>ConstantFP</tt>.  Note that in the LLVM IR
 that constants are all uniqued together and shared.  For this reason, the API
-uses "the foo::get(..)" idiom instead of "new foo(..)" or "foo::Create(..)".</p>
+uses "the Context.get..." idiom instead of "new foo(..)" or "foo::Create(..)".</p>
 
 <div class="doc_code">
 <pre>
@@ -308,7 +308,7 @@ bodies and external function declarations.  The code starts with:</p>
 Function *PrototypeAST::Codegen() {
   // Make the function type:  double(double,double) etc.
   std::vector&lt;const Type*&gt; Doubles(Args.size(), Type::DoubleTy);
-  FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
+  FunctionType *FT = getGlobalContext().getFunctionType(Type::DoubleTy, Doubles, false);
   
   Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
 </pre>
@@ -320,10 +320,10 @@ really talks about the external interface for a function (not the value computed
 by an expression), it makes sense for it to return the LLVM Function it
 corresponds to when codegen'd.</p>
 
-<p>The call to <tt>FunctionType::get</tt> creates
+<p>The call to <tt>Context.get</tt> creates
 the <tt>FunctionType</tt> that should be used for a given Prototype.  Since all
 function arguments in Kaleidoscope are of type double, the first line creates
-a vector of "N" LLVM double types.  It then uses the <tt>FunctionType::get</tt>
+a vector of "N" LLVM double types.  It then uses the <tt>Context.get</tt>
 method to create a function type that takes "N" doubles as arguments, returns
 one double as a result, and that is not vararg (the false parameter indicates
 this).  Note that Types in LLVM are uniqued just like Constants are, so you
@@ -1034,7 +1034,7 @@ static std::map&lt;std::string, Value*&gt; NamedValues;
 Value *ErrorV(const char *Str) { Error(Str); return 0; }
 
 Value *NumberExprAST::Codegen() {
-  return ConstantFP::get(APFloat(Val));
+  return getGlobalContext().getConstantFP(APFloat(Val));
 }
 
 Value *VariableExprAST::Codegen() {
@@ -1082,7 +1082,7 @@ Value *CallExprAST::Codegen() {
 Function *PrototypeAST::Codegen() {
   // Make the function type:  double(double,double) etc.
   std::vector&lt;const Type*&gt; Doubles(Args.size(), Type::DoubleTy);
-  FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
+  FunctionType *FT = getGlobalContext().getFunctionType(Type::DoubleTy, Doubles, false);
   
   Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
   
index f08665d64cd47e44226d58f2c301581bb2c18b70..ca5968273e14492ec8e5fba14d3c63c82ab672c5 100644 (file)
@@ -869,7 +869,7 @@ static FunctionPassManager *TheFPM;
 Value *ErrorV(const char *Str) { Error(Str); return 0; }
 
 Value *NumberExprAST::Codegen() {
-  return ConstantFP::get(APFloat(Val));
+  return getGlobalContext().getConstantFP(APFloat(Val));
 }
 
 Value *VariableExprAST::Codegen() {
@@ -917,7 +917,7 @@ Value *CallExprAST::Codegen() {
 Function *PrototypeAST::Codegen() {
   // Make the function type:  double(double,double) etc.
   std::vector&lt;const Type*&gt; Doubles(Args.size(), Type::DoubleTy);
-  FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
+  FunctionType *FT = getGlobalContext().getFunctionType(Type::DoubleTy, Doubles, false);
   
   Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
   
index f3630d06ac5582e989af2309d2607ab5f13d8b5d..cad05f7045401da909365794c18329978d88528f 100644 (file)
@@ -364,7 +364,7 @@ Value *IfExprAST::Codegen() {
   
   // Convert condition to a bool by comparing equal to 0.0.
   CondV = Builder.CreateFCmpONE(CondV, 
-                                ConstantFP::get(APFloat(0.0)),
+                                getGlobalContext().getConstantFP(APFloat(0.0)),
                                 "ifcond");
 </pre>
 </div>
@@ -796,7 +796,7 @@ references to it will naturally find it in the symbol table.</p>
     if (StepVal == 0) return 0;
   } else {
     // If not specified, use 1.0.
-    StepVal = ConstantFP::get(APFloat(1.0));
+    StepVal = getGlobalContext().getConstantFP(APFloat(1.0));
   }
   
   Value *NextVar = Builder.CreateAdd(Variable, StepVal, "nextvar");
@@ -815,7 +815,7 @@ will be the value of the loop variable on the next iteration of the loop.</p>
   
   // Convert condition to a bool by comparing equal to 0.0.
   EndCond = Builder.CreateFCmpONE(EndCond, 
-                                  ConstantFP::get(APFloat(0.0)),
+                                  getGlobalContext().getConstantFP(APFloat(0.0)),
                                   "loopcond");
 </pre>
 </div>
@@ -1360,7 +1360,7 @@ static FunctionPassManager *TheFPM;
 Value *ErrorV(const char *Str) { Error(Str); return 0; }
 
 Value *NumberExprAST::Codegen() {
-  return ConstantFP::get(APFloat(Val));
+  return getGlobalContext().getConstantFP(APFloat(Val));
 }
 
 Value *VariableExprAST::Codegen() {
@@ -1411,7 +1411,7 @@ Value *IfExprAST::Codegen() {
   
   // Convert condition to a bool by comparing equal to 0.0.
   CondV = Builder.CreateFCmpONE(CondV, 
-                                ConstantFP::get(APFloat(0.0)),
+                                getGlobalContext().getConstantFP(APFloat(0.0)),
                                 "ifcond");
   
   Function *TheFunction = Builder.GetInsertBlock()-&gt;getParent();
@@ -1510,7 +1510,7 @@ Value *ForExprAST::Codegen() {
     if (StepVal == 0) return 0;
   } else {
     // If not specified, use 1.0.
-    StepVal = ConstantFP::get(APFloat(1.0));
+    StepVal = getGlobalContext().getConstantFP(APFloat(1.0));
   }
   
   Value *NextVar = Builder.CreateAdd(Variable, StepVal, "nextvar");
@@ -1521,7 +1521,7 @@ Value *ForExprAST::Codegen() {
   
   // Convert condition to a bool by comparing equal to 0.0.
   EndCond = Builder.CreateFCmpONE(EndCond, 
-                                  ConstantFP::get(APFloat(0.0)),
+                                  getGlobalContext().getConstantFP(APFloat(0.0)),
                                   "loopcond");
   
   // Create the "after loop" block and insert it.
@@ -1545,13 +1545,13 @@ Value *ForExprAST::Codegen() {
 
   
   // for expr always returns 0.0.
-  return Constant::getNullValue(Type::DoubleTy);
+  return getGlobalContext().getNullValue(Type::DoubleTy);
 }
 
 Function *PrototypeAST::Codegen() {
   // Make the function type:  double(double,double) etc.
   std::vector&lt;const Type*&gt; Doubles(Args.size(), Type::DoubleTy);
-  FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
+  FunctionType *FT = getGlobalContext().getFunctionType(Type::DoubleTy, Doubles, false);
   
   Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
   
index c0c396b8a342be97653df77a62b976cbeb5415bb..b10a15f6353b7ba298585f7dbe9033f63b314076 100644 (file)
@@ -1365,7 +1365,7 @@ static FunctionPassManager *TheFPM;
 Value *ErrorV(const char *Str) { Error(Str); return 0; }
 
 Value *NumberExprAST::Codegen() {
-  return ConstantFP::get(APFloat(Val));
+  return getGlobalContext().getConstantFP(APFloat(Val));
 }
 
 Value *VariableExprAST::Codegen() {
@@ -1436,7 +1436,7 @@ Value *IfExprAST::Codegen() {
   
   // Convert condition to a bool by comparing equal to 0.0.
   CondV = Builder.CreateFCmpONE(CondV, 
-                                ConstantFP::get(APFloat(0.0)),
+                                getGlobalContext().getConstantFP(APFloat(0.0)),
                                 "ifcond");
   
   Function *TheFunction = Builder.GetInsertBlock()-&gt;getParent();
@@ -1535,7 +1535,7 @@ Value *ForExprAST::Codegen() {
     if (StepVal == 0) return 0;
   } else {
     // If not specified, use 1.0.
-    StepVal = ConstantFP::get(APFloat(1.0));
+    StepVal = getGlobalContext().getConstantFP(APFloat(1.0));
   }
   
   Value *NextVar = Builder.CreateAdd(Variable, StepVal, "nextvar");
@@ -1546,7 +1546,7 @@ Value *ForExprAST::Codegen() {
   
   // Convert condition to a bool by comparing equal to 0.0.
   EndCond = Builder.CreateFCmpONE(EndCond, 
-                                  ConstantFP::get(APFloat(0.0)),
+                                  getGlobalContext().getConstantFP(APFloat(0.0)),
                                   "loopcond");
   
   // Create the "after loop" block and insert it.
@@ -1576,7 +1576,7 @@ Value *ForExprAST::Codegen() {
 Function *PrototypeAST::Codegen() {
   // Make the function type:  double(double,double) etc.
   std::vector&lt;const Type*&gt; Doubles(Args.size(), Type::DoubleTy);
-  FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
+  FunctionType *FT = getGlobalContext().getFunctionType(Type::DoubleTy, Doubles, false);
   
   Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
   
index 157b7dda459289f7334e1cba6e1e996ddffd044b..9424223fd777e19231b5cf69ff9a3146a83e458c 100644 (file)
@@ -923,7 +923,7 @@ that we replace in OldBindings.</p>
       InitVal = Init-&gt;Codegen();
       if (InitVal == 0) return 0;
     } else { // If not specified, use 0.0.
-      InitVal = ConstantFP::get(APFloat(0.0));
+      InitVal = getGlobalContext().getConstantFP(APFloat(0.0));
     }
     
     AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
@@ -1623,7 +1623,7 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
 
 
 Value *NumberExprAST::Codegen() {
-  return ConstantFP::get(APFloat(Val));
+  return getGlobalContext().getConstantFP(APFloat(Val));
 }
 
 Value *VariableExprAST::Codegen() {
@@ -1716,7 +1716,7 @@ Value *IfExprAST::Codegen() {
   
   // Convert condition to a bool by comparing equal to 0.0.
   CondV = Builder.CreateFCmpONE(CondV, 
-                                ConstantFP::get(APFloat(0.0)),
+                                getGlobalContext().getConstantFP(APFloat(0.0)),
                                 "ifcond");
   
   Function *TheFunction = Builder.GetInsertBlock()-&gt;getParent();
@@ -1822,7 +1822,7 @@ Value *ForExprAST::Codegen() {
     if (StepVal == 0) return 0;
   } else {
     // If not specified, use 1.0.
-    StepVal = ConstantFP::get(APFloat(1.0));
+    StepVal = getGlobalContext().getConstantFP(APFloat(1.0));
   }
   
   // Compute the end condition.
@@ -1837,7 +1837,7 @@ Value *ForExprAST::Codegen() {
   
   // Convert condition to a bool by comparing equal to 0.0.
   EndCond = Builder.CreateFCmpONE(EndCond, 
-                                  ConstantFP::get(APFloat(0.0)),
+                                  getGlobalContext().getConstantFP(APFloat(0.0)),
                                   "loopcond");
   
   // Create the "after loop" block and insert it.
@@ -1881,7 +1881,7 @@ Value *VarExprAST::Codegen() {
       InitVal = Init-&gt;Codegen();
       if (InitVal == 0) return 0;
     } else { // If not specified, use 0.0.
-      InitVal = ConstantFP::get(APFloat(0.0));
+      InitVal = getGlobalContext().getConstantFP(APFloat(0.0));
     }
     
     AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
@@ -1911,7 +1911,7 @@ Value *VarExprAST::Codegen() {
 Function *PrototypeAST::Codegen() {
   // Make the function type:  double(double,double) etc.
   std::vector&lt;const Type*&gt; Doubles(Args.size(), Type::DoubleTy);
-  FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
+  FunctionType *FT = getGlobalContext().getFunctionType(Type::DoubleTy, Doubles, false);
   
   Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
   
index 134742516d3d69965d3f1e5c37854331703ce877..4fd80a936343c7e33e75ae8430424ff4a873b45c 100644 (file)
@@ -621,7 +621,7 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
 
 
 Value *NumberExprAST::Codegen() {
-  return ConstantFP::get(APFloat(Val));
+  return getGlobalContext().getConstantFP(APFloat(Val));
 }
 
 Value *VariableExprAST::Codegen() {
@@ -714,7 +714,7 @@ Value *IfExprAST::Codegen() {
   
   // Convert condition to a bool by comparing equal to 0.0.
   CondV = Builder.CreateFCmpONE(CondV, 
-                                ConstantFP::get(APFloat(0.0)),
+                                getGlobalContext().getConstantFP(APFloat(0.0)),
                                 "ifcond");
   
   Function *TheFunction = Builder.GetInsertBlock()->getParent();
@@ -819,7 +819,7 @@ Value *ForExprAST::Codegen() {
     if (StepVal == 0) return 0;
   } else {
     // If not specified, use 1.0.
-    StepVal = ConstantFP::get(APFloat(1.0));
+    StepVal = getGlobalContext().getConstantFP(APFloat(1.0));
   }
   
   // Compute the end condition.
@@ -834,7 +834,7 @@ Value *ForExprAST::Codegen() {
   
   // Convert condition to a bool by comparing equal to 0.0.
   EndCond = Builder.CreateFCmpONE(EndCond, 
-                                  ConstantFP::get(APFloat(0.0)),
+                                getGlobalContext().getConstantFP(APFloat(0.0)),
                                   "loopcond");
   
   // Create the "after loop" block and insert it.
@@ -877,7 +877,7 @@ Value *VarExprAST::Codegen() {
       InitVal = Init->Codegen();
       if (InitVal == 0) return 0;
     } else { // If not specified, use 0.0.
-      InitVal = ConstantFP::get(APFloat(0.0));
+      InitVal = getGlobalContext().getConstantFP(APFloat(0.0));
     }
     
     AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
@@ -907,7 +907,8 @@ Value *VarExprAST::Codegen() {
 Function *PrototypeAST::Codegen() {
   // Make the function type:  double(double,double) etc.
   std::vector<const Type*> Doubles(Args.size(), Type::DoubleTy);
-  FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
+  FunctionType *FT =
+    getGlobalContext().getFunctionType(Type::DoubleTy, Doubles, false);
   
   Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
   
@@ -1084,7 +1085,7 @@ double printd(double X) {
 
 int main() {
   InitializeNativeTarget();
-  LLVMContext Context;
+  LLVMContext &Context = getGlobalContext();
   
   // Install standard binary operators.
   // 1 is lowest precedence.
index df086416a8e333e90643194466a4646460a7bfd1..199355baf413cf1ea2c1310348a61d4bd8579fff 100644 (file)
@@ -213,6 +213,7 @@ class ConstantFP : public Constant {
   APFloat Val;
   void *operator new(size_t, unsigned);// DO NOT IMPLEMENT
   ConstantFP(const ConstantFP &);      // DO NOT IMPLEMENT
+  friend class LLVMContextImpl;
 protected:
   ConstantFP(const Type *Ty, const APFloat& V);
 protected:
@@ -221,9 +222,6 @@ protected:
     return User::operator new(s, 0);
   }
 public:
-  /// get() - Static factory methods - Return objects of the specified value
-  static ConstantFP *get(const APFloat &V);
-
   /// isValueValidForType - return true if Ty is big enough to represent V.
   static bool isValueValidForType(const Type *Ty, const APFloat& V);
   inline const APFloat& getValueAPF() const { return Val; }
index 4491eb262b907c8bb7b416c62316fb7983e304b3..85ade6fc71503c4f629534dfcc7f1bc66cdb87d7 100644 (file)
@@ -916,7 +916,7 @@ SDValue SelectionDAG::getIntPtrConstant(uint64_t Val, bool isTarget) {
 
 
 SDValue SelectionDAG::getConstantFP(const APFloat& V, MVT VT, bool isTarget) {
-  return getConstantFP(*ConstantFP::get(V), VT, isTarget);
+  return getConstantFP(*Context->getConstantFP(V), VT, isTarget);
 }
 
 SDValue SelectionDAG::getConstantFP(const ConstantFP& V, MVT VT, bool isTarget){
index 4f90bb31fcf1f9ab50b00a94edac90330b51ab41..3c85118cadacca30822b378f8b89663e23bab416 100644 (file)
@@ -2146,7 +2146,8 @@ void SelectionDAGLowering::visitFSub(User &I) {
       const VectorType *DestTy = cast<VectorType>(I.getType());
       const Type *ElTy = DestTy->getElementType();
       unsigned VL = DestTy->getNumElements();
-      std::vector<Constant*> NZ(VL, Context->getConstantFPNegativeZero(ElTy));
+      std::vector<Constant*> NZ(VL, 
+                            DAG.getContext()->getConstantFPNegativeZero(ElTy));
       Constant *CNZ = DAG.getContext()->getConstantVector(&NZ[0], NZ.size());
       if (CV == CNZ) {
         SDValue Op2 = getValue(I.getOperand(1));
@@ -2158,7 +2159,7 @@ void SelectionDAGLowering::visitFSub(User &I) {
   }
   if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0)))
     if (CFP->isExactlyValue(
-                       Context->getConstantFPNegativeZero(Ty)->getValueAPF())) {
+             DAG.getContext()->getConstantFPNegativeZero(Ty)->getValueAPF())) {
       SDValue Op2 = getValue(I.getOperand(1));
       setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(),
                                Op2.getValueType(), Op2));
index 680aed59025fadb5a1f4a0d02afbe4c5022defeb..6092eb150ae2086cc0dcceef8731e5c69bb2a6b6 100644 (file)
@@ -222,76 +222,6 @@ bool ConstantFP::isExactlyValue(const APFloat& V) const {
   return Val.bitwiseIsEqual(V);
 }
 
-namespace {
-  struct DenseMapAPFloatKeyInfo {
-    struct KeyTy {
-      APFloat val;
-      KeyTy(const APFloat& V) : val(V){}
-      KeyTy(const KeyTy& that) : val(that.val) {}
-      bool operator==(const KeyTy& that) const {
-        return this->val.bitwiseIsEqual(that.val);
-      }
-      bool operator!=(const KeyTy& that) const {
-        return !this->operator==(that);
-      }
-    };
-    static inline KeyTy getEmptyKey() { 
-      return KeyTy(APFloat(APFloat::Bogus,1));
-    }
-    static inline KeyTy getTombstoneKey() { 
-      return KeyTy(APFloat(APFloat::Bogus,2)); 
-    }
-    static unsigned getHashValue(const KeyTy &Key) {
-      return Key.val.getHashValue();
-    }
-    static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
-      return LHS == RHS;
-    }
-    static bool isPod() { return false; }
-  };
-}
-
-//---- ConstantFP::get() implementation...
-//
-typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*, 
-                 DenseMapAPFloatKeyInfo> FPMapTy;
-
-static ManagedStatic<FPMapTy> FPConstants;
-
-ConstantFP *ConstantFP::get(const APFloat &V) {
-  DenseMapAPFloatKeyInfo::KeyTy Key(V);
-  
-  ConstantsLock->reader_acquire();
-  ConstantFP *&Slot = (*FPConstants)[Key];
-  ConstantsLock->reader_release();
-    
-  if (!Slot) {
-    sys::SmartScopedWriter<true> Writer(*ConstantsLock);
-    ConstantFP *&NewSlot = (*FPConstants)[Key];
-    if (!NewSlot) {
-      const Type *Ty;
-      if (&V.getSemantics() == &APFloat::IEEEsingle)
-        Ty = Type::FloatTy;
-      else if (&V.getSemantics() == &APFloat::IEEEdouble)
-        Ty = Type::DoubleTy;
-      else if (&V.getSemantics() == &APFloat::x87DoubleExtended)
-        Ty = Type::X86_FP80Ty;
-      else if (&V.getSemantics() == &APFloat::IEEEquad)
-        Ty = Type::FP128Ty;
-      else {
-        assert(&V.getSemantics() == &APFloat::PPCDoubleDouble && 
-               "Unknown FP format");
-        Ty = Type::PPC_FP128Ty;
-      }
-      NewSlot = new ConstantFP(Ty, V);
-    }
-    
-    return NewSlot;
-  }
-  
-  return Slot;
-}
-
 //===----------------------------------------------------------------------===//
 //                            ConstantXXX Classes
 //===----------------------------------------------------------------------===//
index 0372f31e674014ebd73e9f96d8f1f4f3041448cc..c869ab013e2c28bcd1c10b2711bc2d4878704efb 100644 (file)
@@ -482,7 +482,7 @@ Constant* LLVMContext::getZeroValueForNegation(const Type* Ty) {
 
 // ConstantFP accessors.
 ConstantFP* LLVMContext::getConstantFP(const APFloat& V) {
-  return ConstantFP::get(V);
+  return pImpl->getConstantFP(V);
 }
 
 static const fltSemantics *TypeToFloatSemantics(const Type *Ty) {
index a92c19fe04ab69209f7fdfc821dfd813cef1edb0..4c6319ea92ccc64732baf1ec8595a5bbf0c7040b 100644 (file)
@@ -46,3 +46,36 @@ ConstantInt *LLVMContextImpl::getConstantInt(const APInt& V) {
   }
 }
 
+ConstantFP *LLVMContextImpl::getConstantFP(const APFloat &V) {
+  DenseMapAPFloatKeyInfo::KeyTy Key(V);
+  
+  ConstantsLock.reader_acquire();
+  ConstantFP *&Slot = FPConstants[Key];
+  ConstantsLock.reader_release();
+    
+  if (!Slot) {
+    sys::SmartScopedWriter<true> Writer(ConstantsLock);
+    ConstantFP *&NewSlot = FPConstants[Key];
+    if (!NewSlot) {
+      const Type *Ty;
+      if (&V.getSemantics() == &APFloat::IEEEsingle)
+        Ty = Type::FloatTy;
+      else if (&V.getSemantics() == &APFloat::IEEEdouble)
+        Ty = Type::DoubleTy;
+      else if (&V.getSemantics() == &APFloat::x87DoubleExtended)
+        Ty = Type::X86_FP80Ty;
+      else if (&V.getSemantics() == &APFloat::IEEEquad)
+        Ty = Type::FP128Ty;
+      else {
+        assert(&V.getSemantics() == &APFloat::PPCDoubleDouble && 
+               "Unknown FP format");
+        Ty = Type::PPC_FP128Ty;
+      }
+      NewSlot = new ConstantFP(Ty, V);
+    }
+    
+    return NewSlot;
+  }
+  
+  return Slot;
+}
\ No newline at end of file
index fbf29fdfc49cece9b348490bc31024563a1403d6..27bd45133937d7913b93c37f3e4f4501135793bc 100644 (file)
 #define LLVM_LLVMCONTEXT_IMPL_H
 
 #include "llvm/System/RWMutex.h"
+#include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/DenseMap.h"
 
 namespace llvm {
 
 class ConstantInt;
+class ConstantFP;
 class LLVMContext;
 class Type;
 
@@ -50,6 +52,33 @@ struct DenseMapAPIntKeyInfo {
   static bool isPod() { return false; }
 };
 
+struct DenseMapAPFloatKeyInfo {
+  struct KeyTy {
+    APFloat val;
+    KeyTy(const APFloat& V) : val(V){}
+    KeyTy(const KeyTy& that) : val(that.val) {}
+    bool operator==(const KeyTy& that) const {
+      return this->val.bitwiseIsEqual(that.val);
+    }
+    bool operator!=(const KeyTy& that) const {
+      return !this->operator==(that);
+    }
+  };
+  static inline KeyTy getEmptyKey() { 
+    return KeyTy(APFloat(APFloat::Bogus,1));
+  }
+  static inline KeyTy getTombstoneKey() { 
+    return KeyTy(APFloat(APFloat::Bogus,2)); 
+  }
+  static unsigned getHashValue(const KeyTy &Key) {
+    return Key.val.getHashValue();
+  }
+  static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
+    return LHS == RHS;
+  }
+  static bool isPod() { return false; }
+};
+
 class LLVMContextImpl {
   sys::SmartRWMutex<true> ConstantsLock;
   
@@ -57,6 +86,10 @@ class LLVMContextImpl {
                    DenseMapAPIntKeyInfo> IntMapTy;
   IntMapTy IntConstants;
   
+  typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*, 
+                   DenseMapAPFloatKeyInfo> FPMapTy;
+  FPMapTy FPConstants;
+  
   LLVMContext &Context;
   LLVMContextImpl();
   LLVMContextImpl(const LLVMContextImpl&);
@@ -65,7 +98,9 @@ public:
   
   /// Return a ConstantInt with the specified value and an implied Type. The
   /// type is the integer type that corresponds to the bit width of the value.
-  ConstantInt* getConstantInt(const APInt &V);
+  ConstantInt *getConstantInt(const APInt &V);
+  
+  ConstantFP *getConstantFP(const APFloat &V);
 };
 
 }