Fix resetting the DataLayout in a Module.

No tool does this currently, but as everything else in a module we should be
able to change its DataLayout.

Most of the fix is in DataLayout to make sure it can be reset properly.

The test uses Module::setDataLayout since the fact that we mutate a DataLayout
is an implementation detail. The module could hold a OwningPtr<DataLayout> and
the DataLayout itself could be immutable.

Thanks to Philip Reames for pushing me in the right direction.

llvm-svn: 202198
This commit is contained in:
Rafael Espindola 2014-02-25 22:23:04 +00:00
parent afc9eb33fd
commit 248ac13975
4 changed files with 38 additions and 11 deletions

View File

@ -110,7 +110,7 @@ private:
/// Alignments - Where the primitive type alignment data is stored. /// Alignments - Where the primitive type alignment data is stored.
/// ///
/// @sa init(). /// @sa reset().
/// @note Could support multiple size pointer alignments, e.g., 32-bit /// @note Could support multiple size pointer alignments, e.g., 32-bit
/// pointers vs. 64-bit pointers by extending LayoutAlignment, but for now, /// pointers vs. 64-bit pointers by extending LayoutAlignment, but for now,
/// we don't. /// we don't.
@ -161,30 +161,35 @@ private:
/// malformed. /// malformed.
void parseSpecifier(StringRef LayoutDescription); void parseSpecifier(StringRef LayoutDescription);
// Free all internal data structures.
void clear();
public: public:
/// Constructs a DataLayout from a specification string. See init(). /// Constructs a DataLayout from a specification string. See reset().
explicit DataLayout(StringRef LayoutDescription) { init(LayoutDescription); } explicit DataLayout(StringRef LayoutDescription) : LayoutMap(0) {
reset(LayoutDescription);
}
/// Initialize target data from properties stored in the module. /// Initialize target data from properties stored in the module.
explicit DataLayout(const Module *M); explicit DataLayout(const Module *M);
DataLayout(const DataLayout &DL) { *this = DL; } DataLayout(const DataLayout &DL) : LayoutMap(0) { *this = DL; }
DataLayout &operator=(const DataLayout &DL) { DataLayout &operator=(const DataLayout &DL) {
clear();
LittleEndian = DL.isLittleEndian(); LittleEndian = DL.isLittleEndian();
StackNaturalAlign = DL.StackNaturalAlign; StackNaturalAlign = DL.StackNaturalAlign;
ManglingMode = DL.ManglingMode; ManglingMode = DL.ManglingMode;
LegalIntWidths = DL.LegalIntWidths; LegalIntWidths = DL.LegalIntWidths;
Alignments = DL.Alignments; Alignments = DL.Alignments;
Pointers = DL.Pointers; Pointers = DL.Pointers;
LayoutMap = 0;
return *this; return *this;
} }
~DataLayout(); // Not virtual, do not subclass this class ~DataLayout(); // Not virtual, do not subclass this class
/// Parse a data layout string (with fallback to default values). /// Parse a data layout string (with fallback to default values).
void init(StringRef LayoutDescription); void reset(StringRef LayoutDescription);
/// Layout endianness... /// Layout endianness...
bool isLittleEndian() const { return LittleEndian; } bool isLittleEndian() const { return LittleEndian; }

View File

@ -176,7 +176,9 @@ static const LayoutAlignElem DefaultAlignments[] = {
{ AGGREGATE_ALIGN, 0, 0, 8 } // struct { AGGREGATE_ALIGN, 0, 0, 8 } // struct
}; };
void DataLayout::init(StringRef Desc) { void DataLayout::reset(StringRef Desc) {
clear();
LayoutMap = 0; LayoutMap = 0;
LittleEndian = false; LittleEndian = false;
StackNaturalAlign = 0; StackNaturalAlign = 0;
@ -344,12 +346,12 @@ void DataLayout::parseSpecifier(StringRef Desc) {
} }
} }
DataLayout::DataLayout(const Module *M) { DataLayout::DataLayout(const Module *M) : LayoutMap(0) {
const DataLayout *Other = M->getDataLayout(); const DataLayout *Other = M->getDataLayout();
if (Other) if (Other)
*this = *Other; *this = *Other;
else else
init(""); reset("");
} }
void void
@ -469,8 +471,16 @@ public:
} // end anonymous namespace } // end anonymous namespace
DataLayout::~DataLayout() { void DataLayout::clear() {
LegalIntWidths.clear();
Alignments.clear();
Pointers.clear();
delete static_cast<StructLayoutMap *>(LayoutMap); delete static_cast<StructLayoutMap *>(LayoutMap);
LayoutMap = 0;
}
DataLayout::~DataLayout() {
clear();
} }
const StructLayout *DataLayout::getStructLayout(StructType *Ty) const { const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {

View File

@ -339,17 +339,21 @@ void Module::addModuleFlag(MDNode *Node) {
} }
void Module::setDataLayout(StringRef Desc) { void Module::setDataLayout(StringRef Desc) {
DL.reset(Desc);
if (Desc.empty()) { if (Desc.empty()) {
DataLayoutStr = ""; DataLayoutStr = "";
} else { } else {
DL.init(Desc);
DataLayoutStr = DL.getStringRepresentation(); DataLayoutStr = DL.getStringRepresentation();
// DataLayoutStr is now equivalent to Desc, but since the representation
// is not unique, they may not be identical.
} }
} }
void Module::setDataLayout(const DataLayout *Other) { void Module::setDataLayout(const DataLayout *Other) {
if (!Other) { if (!Other) {
DataLayoutStr = ""; DataLayoutStr = "";
DL.reset("");
} else { } else {
DL = *Other; DL = *Other;
DataLayoutStr = DL.getStringRepresentation(); DataLayoutStr = DL.getStringRepresentation();

View File

@ -108,6 +108,14 @@ TEST_F(IRBuilderTest, LandingPadName) {
EXPECT_EQ(LP->getName(), "LP"); EXPECT_EQ(LP->getName(), "LP");
} }
TEST_F(IRBuilderTest, DataLayout) {
OwningPtr<Module> M(new Module("test", Ctx));
M->setDataLayout("e-n32");
EXPECT_TRUE(M->getDataLayout()->isLegalInteger(32));
M->setDataLayout("e");
EXPECT_FALSE(M->getDataLayout()->isLegalInteger(32));
}
TEST_F(IRBuilderTest, GetIntTy) { TEST_F(IRBuilderTest, GetIntTy) {
IRBuilder<> Builder(BB); IRBuilder<> Builder(BB);
IntegerType *Ty1 = Builder.getInt1Ty(); IntegerType *Ty1 = Builder.getInt1Ty();