[llvm-commits] [llvm] r69597 - /llvm/trunk/include/llvm/Transforms/Utils/InlineCost.h

Duncan Sands baldrick at free.fr
Mon Apr 20 09:03:21 PDT 2009


Author: baldrick
Date: Mon Apr 20 11:03:21 2009
New Revision: 69597

URL: http://llvm.org/viewvc/llvm-project?rev=69597&view=rev
Log:
These bitfields were being miscompiled on some
64 bit platforms when building with optimization.
So replace them by a hand-coded implementation.
This fixes PR3822.

Modified:
    llvm/trunk/include/llvm/Transforms/Utils/InlineCost.h

Modified: llvm/trunk/include/llvm/Transforms/Utils/InlineCost.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/InlineCost.h?rev=69597&r1=69596&r2=69597&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/InlineCost.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/InlineCost.h Mon Apr 20 11:03:21 2009
@@ -16,6 +16,7 @@
 
 #include "llvm/ADT/SmallPtrSet.h"
 #include <cassert>
+#include <climits>
 #include <map>
 #include <vector>
 
@@ -37,26 +38,41 @@
       Never
     };
 
-    int Cost : 30;
-    unsigned Type :  2;
+    // This is a do-it-yourself implementation of
+    //   int Cost : 30;
+    //   unsigned Type : 2;
+    // We used to use bitfields, but they were sometimes miscompiled (PR3822).
+    enum { TYPE_BITS = 2 };
+    enum { COST_BITS = unsigned(sizeof(unsigned)) * CHAR_BIT - TYPE_BITS };
+    unsigned TypedCost; // int Cost : COST_BITS; unsigned Type : TYPE_BITS;
 
-    InlineCost(int C, int T) : Cost(C), Type(T) {
-      assert(Cost == C && "Cost exceeds InlineCost precision");
+    Kind getType() const {
+      return Kind(TypedCost >> COST_BITS);
+    }
+
+    int getCost() const {
+      // Sign-extend the bottom COST_BITS bits.
+      return (int(TypedCost << TYPE_BITS)) >> TYPE_BITS;
+    }
+
+    InlineCost(int C, int T) {
+      TypedCost = (unsigned(C << TYPE_BITS) >> TYPE_BITS) | (T << COST_BITS);
+      assert(getCost() == C && "Cost exceeds InlineCost precision");
     }
   public:
     static InlineCost get(int Cost) { return InlineCost(Cost, Value); }
     static InlineCost getAlways() { return InlineCost(0, Always); }
-    static InlineCost getNever() { return InlineCost(0, Never); } 
+    static InlineCost getNever() { return InlineCost(0, Never); }
 
-    bool isVariable() const { return Type == Value; }
-    bool isAlways() const { return Type == Always; }
-    bool isNever() const { return Type == Never; }
+    bool isVariable() const { return getType() == Value; }
+    bool isAlways() const { return getType() == Always; }
+    bool isNever() const { return getType() == Never; }
 
     /// getValue() - Return a "variable" inline cost's amount. It is
     /// an error to call this on an "always" or "never" InlineCost.
-    int getValue() const { 
-      assert(Type == Value && "Invalid access of InlineCost");
-      return Cost;
+    int getValue() const {
+      assert(getType() == Value && "Invalid access of InlineCost");
+      return getCost();
     }
   };
   





More information about the llvm-commits mailing list