mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
Fix cwriter to not output FP constants in ascii, output them in hex instead.
This fixes a number of FP precision problems, making the output of the power benchmark closer to the right answer. Unfortunately, this only addresses FP constants used directly in functions. Constants referred to by global constants (such as an array of FP values) aren't helped by this. Until this happens power won't work. llvm-svn: 3871
This commit is contained in:
parent
6874ea0917
commit
b9379750d9
@ -1,8 +1,6 @@
|
||||
//===-- Writer.cpp - Library for converting LLVM code to C ----------------===//
|
||||
//
|
||||
// This library implements the functionality defined in llvm/Assembly/CWriter.h
|
||||
//
|
||||
// TODO : Recursive types.
|
||||
// This library converts LLVM code to C code, compilable by GCC.
|
||||
//
|
||||
//===-----------------------------------------------------------------------==//
|
||||
|
||||
@ -19,6 +17,7 @@
|
||||
#include "llvm/SymbolTable.h"
|
||||
#include "llvm/SlotCalculator.h"
|
||||
#include "llvm/Analysis/FindUsedTypes.h"
|
||||
#include "llvm/Analysis/ConstantsScanner.h"
|
||||
#include "llvm/Support/InstVisitor.h"
|
||||
#include "llvm/Support/InstIterator.h"
|
||||
#include "Support/StringExtras.h"
|
||||
@ -37,6 +36,7 @@ namespace {
|
||||
map<const Type *, string> TypeNames;
|
||||
std::set<const Value*> MangledGlobals;
|
||||
|
||||
map<const ConstantFP *, unsigned> FPConstantMap;
|
||||
public:
|
||||
CWriter(ostream &o) : Out(o) {}
|
||||
|
||||
@ -377,8 +377,19 @@ void CWriter::printConstant(Constant *CPV) {
|
||||
Out << cast<ConstantUInt>(CPV)->getValue() << "ull"; break;
|
||||
|
||||
case Type::FloatTyID:
|
||||
case Type::DoubleTyID:
|
||||
Out << cast<ConstantFP>(CPV)->getValue(); break;
|
||||
case Type::DoubleTyID: {
|
||||
ConstantFP *FPC = cast<ConstantFP>(CPV);
|
||||
map<const ConstantFP *, unsigned>::iterator I = FPConstantMap.find(FPC);
|
||||
if (I != FPConstantMap.end()) {
|
||||
// Because of FP precision problems we must load from a stack allocated
|
||||
// value that holds the value in hex.
|
||||
Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double")
|
||||
<< "*)&FloatConstant" << I->second << ")";
|
||||
} else {
|
||||
Out << FPC->getValue();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Type::ArrayTyID:
|
||||
printConstantArray(cast<ConstantArray>(CPV));
|
||||
@ -509,6 +520,9 @@ void CWriter::printModule(Module *M) {
|
||||
<< "#ifndef NULL\n#define NULL 0\n#endif\n\n"
|
||||
<< "#ifndef __cplusplus\ntypedef unsigned char bool;\n#endif\n"
|
||||
|
||||
<< "\n\n/* Support for floating point constants */\n"
|
||||
<< "typedef unsigned long long ConstantDoubleTy;\n"
|
||||
|
||||
<< "\n\n/* Global Declarations */\n";
|
||||
|
||||
// First output all the declarations for the program, because C requires
|
||||
@ -710,6 +724,26 @@ void CWriter::printFunction(Function *F) {
|
||||
Out << ";\n";
|
||||
}
|
||||
|
||||
Out << "\n";
|
||||
|
||||
// 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.
|
||||
//
|
||||
unsigned FPCounter = 0;
|
||||
for (constant_iterator I = constant_begin(F), E = constant_end(F); I != E;++I)
|
||||
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I))
|
||||
if (FPConstantMap.find(FPC) == FPConstantMap.end()) {
|
||||
double Val = FPC->getValue();
|
||||
|
||||
FPConstantMap[FPC] = FPCounter; // Number the FP constants
|
||||
Out << " const ConstantDoubleTy FloatConstant" << FPCounter++
|
||||
<< " = 0x" << std::hex << *(unsigned long long*)&Val << std::dec
|
||||
<< "; /* " << Val << " */\n";
|
||||
}
|
||||
|
||||
Out << "\n";
|
||||
|
||||
// print the basic blocks
|
||||
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
|
||||
BasicBlock *Prev = BB->getPrev();
|
||||
@ -748,6 +782,7 @@ void CWriter::printFunction(Function *F) {
|
||||
|
||||
Out << "}\n\n";
|
||||
Table->purgeFunction();
|
||||
FPConstantMap.clear();
|
||||
}
|
||||
|
||||
// Specific Instruction type classes... note that all of the casts are
|
||||
|
Loading…
Reference in New Issue
Block a user