From 914e50c841bbc248ab94144c11813b5785b1292d Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 16 Jul 2009 19:05:41 +0000 Subject: [PATCH] Privatize the ConstantFP table. I'm on a roll! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76097 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/tutorial/LangImpl3.html | 14 ++-- docs/tutorial/LangImpl4.html | 4 +- docs/tutorial/LangImpl5.html | 18 ++--- docs/tutorial/LangImpl6.html | 10 +-- docs/tutorial/LangImpl7.html | 14 ++-- examples/Kaleidoscope/toy.cpp | 15 ++-- include/llvm/Constants.h | 4 +- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 +- .../SelectionDAG/SelectionDAGBuild.cpp | 5 +- lib/VMCore/Constants.cpp | 70 ------------------- lib/VMCore/LLVMContext.cpp | 2 +- lib/VMCore/LLVMContextImpl.cpp | 33 +++++++++ lib/VMCore/LLVMContextImpl.h | 37 +++++++++- 13 files changed, 113 insertions(+), 115 deletions(-) diff --git a/docs/tutorial/LangImpl3.html b/docs/tutorial/LangImpl3.html index 5028a639de3..499b4c20a73 100644 --- a/docs/tutorial/LangImpl3.html +++ b/docs/tutorial/LangImpl3.html @@ -159,7 +159,7 @@ we'll do numeric literals:

 Value *NumberExprAST::Codegen() {
-  return ConstantFP::get(APFloat(Val));
+  return getGlobalContext().getConstantFP(APFloat(Val));
 }
 
@@ -170,7 +170,7 @@ internally (APFloat has the capability of holding floating point constants of Arbitrary Precision). This code basically just creates and returns a ConstantFP. 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(..)".

+uses "the Context.get..." idiom instead of "new foo(..)" or "foo::Create(..)".

@@ -308,7 +308,7 @@ bodies and external function declarations.  The code starts with:

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);
@@ -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.

-

The call to FunctionType::get creates +

The call to Context.get creates the FunctionType 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 FunctionType::get +a vector of "N" LLVM double types. It then uses the Context.get 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<std::string, Value*> 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<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); diff --git a/docs/tutorial/LangImpl4.html b/docs/tutorial/LangImpl4.html index f08665d64cd..ca5968273e1 100644 --- a/docs/tutorial/LangImpl4.html +++ b/docs/tutorial/LangImpl4.html @@ -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<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); diff --git a/docs/tutorial/LangImpl5.html b/docs/tutorial/LangImpl5.html index f3630d06ac5..cad05f70454 100644 --- a/docs/tutorial/LangImpl5.html +++ b/docs/tutorial/LangImpl5.html @@ -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");

@@ -796,7 +796,7 @@ references to it will naturally find it in the symbol table.

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.

// 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"); @@ -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()->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<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); diff --git a/docs/tutorial/LangImpl6.html b/docs/tutorial/LangImpl6.html index c0c396b8a34..b10a15f6353 100644 --- a/docs/tutorial/LangImpl6.html +++ b/docs/tutorial/LangImpl6.html @@ -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()->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<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); diff --git a/docs/tutorial/LangImpl7.html b/docs/tutorial/LangImpl7.html index 157b7dda459..9424223fd77 100644 --- a/docs/tutorial/LangImpl7.html +++ b/docs/tutorial/LangImpl7.html @@ -923,7 +923,7 @@ that we replace in OldBindings.

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); @@ -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()->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->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<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); diff --git a/examples/Kaleidoscope/toy.cpp b/examples/Kaleidoscope/toy.cpp index 134742516d3..4fd80a93634 100644 --- a/examples/Kaleidoscope/toy.cpp +++ b/examples/Kaleidoscope/toy.cpp @@ -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 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. diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index df086416a8e..199355baf41 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -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; } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 4491eb262b9..85ade6fc715 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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){ diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 4f90bb31fcf..3c85118cada 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -2146,7 +2146,8 @@ void SelectionDAGLowering::visitFSub(User &I) { const VectorType *DestTy = cast(I.getType()); const Type *ElTy = DestTy->getElementType(); unsigned VL = DestTy->getNumElements(); - std::vector NZ(VL, Context->getConstantFPNegativeZero(ElTy)); + std::vector 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(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)); diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 680aed59025..6092eb150ae 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -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 FPMapTy; - -static ManagedStatic 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 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 //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 0372f31e674..c869ab013e2 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -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) { diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index a92c19fe04a..4c6319ea92c 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -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 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 diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index fbf29fdfc49..27bd4513393 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -16,12 +16,14 @@ #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 ConstantsLock; @@ -57,6 +86,10 @@ class LLVMContextImpl { DenseMapAPIntKeyInfo> IntMapTy; IntMapTy IntConstants; + typedef DenseMap 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); }; }