mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-30 19:35:54 +00:00
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
This commit is contained in:
parent
dfce360306
commit
914e50c841
@ -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<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);
|
||||
</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<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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()->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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -923,7 +923,7 @@ that we replace in OldBindings.</p>
|
||||
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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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; }
|
||||
|
@ -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){
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
@ -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<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);
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user