[llvm-commits] [dragonegg] r128792 - /dragonegg/trunk/Constants.cpp
Duncan Sands
baldrick at free.fr
Sun Apr 3 12:44:18 PDT 2011
Author: baldrick
Date: Sun Apr 3 14:44:18 2011
New Revision: 128792
URL: http://llvm.org/viewvc/llvm-project?rev=128792&view=rev
Log:
Have default initialized struct fields turn up as a zero of the appropriate
type rather than an array of bytes. This makes the IR easier to read but
probably doesn't otherwise matter.
Modified:
dragonegg/trunk/Constants.cpp
Modified: dragonegg/trunk/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=128792&r1=128791&r2=128792&view=diff
==============================================================================
--- dragonegg/trunk/Constants.cpp (original)
+++ dragonegg/trunk/Constants.cpp Sun Apr 3 14:44:18 2011
@@ -739,11 +739,13 @@
/// the constant in which case any extra bits have an undefined value.
class FieldContents {
SignedRange R; // The range of bits occupied by the constant.
- Constant *C; // The constant. May be null, in which case all bits are zero.
+ Constant *C; // The constant. May be null if the range is empty.
int Starts; // The first bit of the constant is positioned at this offset.
FieldContents(SignedRange r, Constant *c, int starts)
- : R(r), C(c), Starts(starts) {}
+ : R(r), C(c), Starts(starts) {
+ assert((R.empty() || C) && "Need constant when range not empty!");
+ }
/// getAsBits - Return the bits in the range as an integer (or null if the
/// range is empty).
@@ -751,8 +753,6 @@
if (R.empty())
return 0;
const Type *IntTy = IntegerType::get(Context, R.getWidth());
- if (!C) // Implicit zero.
- return Constant::getNullValue(IntTy);
return InterpretAsType(C, IntTy, R.getFirst() - Starts);
}
@@ -760,7 +760,8 @@
/// constant properly represents the bits in the range and so can be handed to
/// the user as is.
bool isSafeToReturnContentsDirectly(const TargetData &TD) const {
- // Implicit zeros need to be made explicit before being passed to the user.
+ // If there is no constant (allowed when the range is empty) then one needs
+ // to be created.
if (!C)
return false;
// If the first bit of the constant is not the first bit of the range then
@@ -778,16 +779,11 @@
/// FieldContents - Default constructor: empty bit range.
FieldContents() : R(), C(0), Starts(0) {}
- /// getConstant - Fill the range [first, last) with the given constant.
- static FieldContents getConstant(int first, int last, Constant *c) {
+ /// get - Fill the range [first, last) with the given constant.
+ static FieldContents get(int first, int last, Constant *c) {
return FieldContents(SignedRange(first, last), c, first);
}
- /// getZero - Fill the range [first, last) with zero.
- static FieldContents getZero(int first, int last) {
- return getConstant(first, last, 0);
- }
-
/// getRange - Return the range occupied by this field.
SignedRange getRange() const { return R; }
@@ -809,18 +805,16 @@
/// in the range then just return it.
if (isSafeToReturnContentsDirectly(TD))
return C;
- assert(R.getWidth() % BITS_PER_UNIT == 0 && "Boundaries not aligned?");
- unsigned Units = R.getWidth() / BITS_PER_UNIT;
- // If this was an implicit zero then make it an explicit zero. This also
- // handles the case of an empty range holding a constant of non-zero size.
- if (!C || R.empty()) {
- // Return an array of zero bytes. Remember the returned value as an
- // optimization in case we are called again.
- C = Constant::getNullValue(GetUnitType(Context, Units));
- Starts = R.empty() ? 0 : R.getFirst();
+ // If the range is empty then return a constant with zero size.
+ if (R.empty()) {
+ // Return an empty array. Remember the returned value as an optimization
+ // in case we are called again.
+ C = Constant::getNullValue(GetUnitType(Context, 0));
assert(isSafeToReturnContentsDirectly(TD) && "Unit over aligned?");
return C;
}
+ assert(R.getWidth() % BITS_PER_UNIT == 0 && "Boundaries not aligned?");
+ unsigned Units = R.getWidth() / BITS_PER_UNIT;
// Turn the contents into a bunch of bits. Remember the returned value as
// an optimization in case we are called again.
// TODO: If the contents only need to be truncated and have struct or array
@@ -878,6 +872,7 @@
assert(FirstBit <= TypeSize && "Field off end of type!");
// Determine the width of the field.
uint64_t BitWidth;
+ const Type *FieldTy = ConvertType(TREE_TYPE(field));
if (isInt64(DECL_SIZE(field), true)) {
// The field has a size and it is a constant, so use it. Note that
// this size may be smaller than the type size. For example, if the
@@ -888,7 +883,6 @@
} else {
// If the field has variable or unknown size then use the size of the
// LLVM type instead as it gives the minimum size the field may have.
- const Type *FieldTy = ConvertType(TREE_TYPE(field));
if (!FieldTy->isSized())
// An incomplete type - this field cannot be default initialized.
continue;
@@ -898,8 +892,11 @@
}
uint64_t LastBit = FirstBit + BitWidth;
- // Zero the bits occupied by the field.
- Layout.AddInterval(FieldContents::getZero(FirstBit, LastBit));
+ // Zero the bits occupied by the field. It is safe to use FieldTy here as
+ // it is guaranteed to cover all parts of the GCC type that can be default
+ // initialized. This makes for nicer IR than just using a bunch of bytes.
+ Constant *Zero = Constant::getNullValue(FieldTy);
+ Layout.AddInterval(FieldContents::get(FirstBit, LastBit, Zero));
}
}
@@ -935,7 +932,7 @@
uint64_t LastBit = FirstBit + BitWidth;
// Set the bits occupied by the field to the initial value.
- Layout.AddInterval(FieldContents::getConstant(FirstBit, LastBit, Init));
+ Layout.AddInterval(FieldContents::get(FirstBit, LastBit, Init));
}
// Force all fields to begin and end on a byte boundary. This automagically
More information about the llvm-commits
mailing list