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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69597 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan Sands 2009-04-20 16:03:21 +00:00
parent 5b7ff35503
commit c3bbf579ae

View File

@ -16,6 +16,7 @@
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include <cassert> #include <cassert>
#include <climits>
#include <map> #include <map>
#include <vector> #include <vector>
@ -37,26 +38,41 @@ namespace llvm {
Never Never
}; };
int Cost : 30; // This is a do-it-yourself implementation of
unsigned Type : 2; // 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) { Kind getType() const {
assert(Cost == C && "Cost exceeds InlineCost precision"); 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: public:
static InlineCost get(int Cost) { return InlineCost(Cost, Value); } static InlineCost get(int Cost) { return InlineCost(Cost, Value); }
static InlineCost getAlways() { return InlineCost(0, Always); } 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 isVariable() const { return getType() == Value; }
bool isAlways() const { return Type == Always; } bool isAlways() const { return getType() == Always; }
bool isNever() const { return Type == Never; } bool isNever() const { return getType() == Never; }
/// getValue() - Return a "variable" inline cost's amount. It is /// getValue() - Return a "variable" inline cost's amount. It is
/// an error to call this on an "always" or "never" InlineCost. /// an error to call this on an "always" or "never" InlineCost.
int getValue() const { int getValue() const {
assert(Type == Value && "Invalid access of InlineCost"); assert(getType() == Value && "Invalid access of InlineCost");
return Cost; return getCost();
} }
}; };