[llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp

Chris Lattner lattner at apoc.cs.uiuc.edu
Fri Sep 20 18:27:01 PDT 2002


Changes in directory llvm/lib/CWriter:

Writer.cpp updated: 1.51 -> 1.52

---
Log message:

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.


---
Diffs of the changes:

Index: llvm/lib/CWriter/Writer.cpp
diff -u llvm/lib/CWriter/Writer.cpp:1.51 llvm/lib/CWriter/Writer.cpp:1.52
--- llvm/lib/CWriter/Writer.cpp:1.51	Fri Sep 20 17:32:30 2002
+++ llvm/lib/CWriter/Writer.cpp	Fri Sep 20 18:26:33 2002
@@ -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 @@
     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 @@
     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 @@
       << "#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
@@ -709,6 +723,26 @@
       printType((*I)->getType(), getValueName(*I));
       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) {
@@ -748,6 +782,7 @@
   
   Out << "}\n\n";
   Table->purgeFunction();
+  FPConstantMap.clear();
 }
 
 // Specific Instruction type classes... note that all of the casts are





More information about the llvm-commits mailing list