From: Brian Gaeke Date: Tue, 17 Jun 2003 23:55:35 +0000 (+0000) Subject: lib/CWriter/Writer.cpp: Copy AsmWriter's ConstantFP checking code here X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b471a23a8506b7476890ee34a25ffbd1b553f3ff;p=oota-llvm.git lib/CWriter/Writer.cpp: Copy AsmWriter's ConstantFP checking code here into a new function FPCSafeToPrint(), and use it in printConstant() and printFunction() to decide whether we should output ConstantFPs as floating-point constants or as references to stack-allocated variables. lib/VMCore/AsmWriter.cpp: Fix an apparent typo in the code mentioned above. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6762 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 1d2a85abe11..ce44f3ce308 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -360,6 +360,27 @@ void CWriter::printConstantArray(ConstantArray *CPA) { } } +/// FPCSafeToPrint - Returns true if we may assume that CFP may be +/// written out textually as a double (rather than as a reference to a +/// stack-allocated variable). We decide this by converting CFP to a +/// string and back into a double, and then checking whether the +/// conversion results in a bit-equal double to the original value of +/// CFP. This depends on us and the target C compiler agreeing on the +/// conversion process (which is pretty likely since we only deal in +/// IEEE FP.) This is adapted from similar code in +/// lib/VMCore/AsmWriter.cpp:WriteConstantInt(). +static bool FPCSafeToPrint (const ConstantFP *CFP) { + std::string StrVal = ftostr(CFP->getValue()); + // Check to make sure that the stringized number is not some string like + // "Inf" or NaN, that atof will accept, but the lexer will not. Check that + // the string matches the "[-+]?[0-9]" regex. + if ((StrVal[0] >= '0' && StrVal[0] <= '9') || + ((StrVal[0] == '-' || StrVal[0] == '+') && + (StrVal[1] >= '0' && StrVal[1] <= '9'))) + // Reparse stringized version! + return (atof(StrVal.c_str()) == CFP->getValue()); + return false; +} // printConstant - The LLVM Constant to C Constant converter. void CWriter::printConstant(Constant *CPV) { @@ -435,7 +456,11 @@ void CWriter::printConstant(Constant *CPV) { Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double") << "*)&FloatConstant" << I->second << ")"; } else { - Out << FPC->getValue(); + if (FPCSafeToPrint (FPC)) { + Out << ftostr (FPC->getValue ()); + } else { + Out << FPC->getValue(); // Who knows? Give it our best shot... + } } break; } @@ -795,7 +820,6 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { } - void CWriter::printFunction(Function *F) { if (F->isExternal()) return; @@ -826,12 +850,14 @@ void CWriter::printFunction(Function *F) { // Scan the function for floating point constants. If any FP constant is used // in the function, we want to redirect it here so that we do not depend on - // the precision of the printed form. + // the precision of the printed form, unless the printed form preserves + // precision. // unsigned FPCounter = 0; for (constant_iterator I = constant_begin(F), E = constant_end(F); I != E;++I) if (const ConstantFP *FPC = dyn_cast(*I)) - if (FPConstantMap.find(FPC) == FPConstantMap.end()) { + if ((!FPCSafeToPrint(FPC)) // Do not put in FPConstantMap if safe. + && (FPConstantMap.find(FPC) == FPConstantMap.end())) { double Val = FPC->getValue(); FPConstantMap[FPC] = FPCounter; // Number the FP constants diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index 1d2a85abe11..ce44f3ce308 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -360,6 +360,27 @@ void CWriter::printConstantArray(ConstantArray *CPA) { } } +/// FPCSafeToPrint - Returns true if we may assume that CFP may be +/// written out textually as a double (rather than as a reference to a +/// stack-allocated variable). We decide this by converting CFP to a +/// string and back into a double, and then checking whether the +/// conversion results in a bit-equal double to the original value of +/// CFP. This depends on us and the target C compiler agreeing on the +/// conversion process (which is pretty likely since we only deal in +/// IEEE FP.) This is adapted from similar code in +/// lib/VMCore/AsmWriter.cpp:WriteConstantInt(). +static bool FPCSafeToPrint (const ConstantFP *CFP) { + std::string StrVal = ftostr(CFP->getValue()); + // Check to make sure that the stringized number is not some string like + // "Inf" or NaN, that atof will accept, but the lexer will not. Check that + // the string matches the "[-+]?[0-9]" regex. + if ((StrVal[0] >= '0' && StrVal[0] <= '9') || + ((StrVal[0] == '-' || StrVal[0] == '+') && + (StrVal[1] >= '0' && StrVal[1] <= '9'))) + // Reparse stringized version! + return (atof(StrVal.c_str()) == CFP->getValue()); + return false; +} // printConstant - The LLVM Constant to C Constant converter. void CWriter::printConstant(Constant *CPV) { @@ -435,7 +456,11 @@ void CWriter::printConstant(Constant *CPV) { Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double") << "*)&FloatConstant" << I->second << ")"; } else { - Out << FPC->getValue(); + if (FPCSafeToPrint (FPC)) { + Out << ftostr (FPC->getValue ()); + } else { + Out << FPC->getValue(); // Who knows? Give it our best shot... + } } break; } @@ -795,7 +820,6 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { } - void CWriter::printFunction(Function *F) { if (F->isExternal()) return; @@ -826,12 +850,14 @@ void CWriter::printFunction(Function *F) { // Scan the function for floating point constants. If any FP constant is used // in the function, we want to redirect it here so that we do not depend on - // the precision of the printed form. + // the precision of the printed form, unless the printed form preserves + // precision. // unsigned FPCounter = 0; for (constant_iterator I = constant_begin(F), E = constant_end(F); I != E;++I) if (const ConstantFP *FPC = dyn_cast(*I)) - if (FPConstantMap.find(FPC) == FPConstantMap.end()) { + if ((!FPCSafeToPrint(FPC)) // Do not put in FPConstantMap if safe. + && (FPConstantMap.find(FPC) == FPConstantMap.end())) { double Val = FPC->getValue(); FPConstantMap[FPC] = FPCounter; // Number the FP constants diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 7695fcb7500..afc4b6d63c6 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -234,7 +234,7 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, // if ((StrVal[0] >= '0' && StrVal[0] <= '9') || ((StrVal[0] == '-' || StrVal[0] == '+') && - (StrVal[0] >= '0' && StrVal[0] <= '9'))) + (StrVal[1] >= '0' && StrVal[1] <= '9'))) // Reparse stringized version! if (atof(StrVal.c_str()) == CFP->getValue()) { Out << StrVal; return;