Skip to content

[DataLayout] Remove clear and reset methods (NFC) #102993

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions llvm/include/llvm/IR/DataLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,10 @@ class DataLayout {
/// if the string is malformed.
Error parseSpecifier(StringRef Desc);

// Free all internal data structures.
void clear();

public:
/// Constructs a DataLayout from a specification string. See reset().
explicit DataLayout(StringRef LayoutDescription) {
reset(LayoutDescription);
}
/// Constructs a DataLayout from a specification string.
/// WARNING: Aborts execution if the string is malformed. Use parse() instead.
explicit DataLayout(StringRef LayoutString);

DataLayout(const DataLayout &DL) { *this = DL; }

Expand All @@ -203,9 +199,6 @@ class DataLayout {
bool operator==(const DataLayout &Other) const;
bool operator!=(const DataLayout &Other) const { return !(*this == Other); }

/// Parse a data layout string (with fallback to default values).
void reset(StringRef LayoutDescription);

/// Parse a data layout string and return the layout. Return an error
/// description on failure.
static Expected<DataLayout> parse(StringRef LayoutDescription);
Expand Down
77 changes: 29 additions & 48 deletions llvm/lib/IR/DataLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,27 @@ unsigned StructLayout::getElementContainingOffset(uint64_t FixedOffset) const {
return SI - MemberOffsets.begin();
}

namespace {

class StructLayoutMap {
using LayoutInfoTy = DenseMap<StructType *, StructLayout *>;
LayoutInfoTy LayoutInfo;

public:
~StructLayoutMap() {
// Remove any layouts.
for (const auto &I : LayoutInfo) {
StructLayout *Value = I.second;
Value->~StructLayout();
free(Value);
}
}

StructLayout *&operator[](StructType *STy) { return LayoutInfo[STy]; }
};

} // end anonymous namespace

//===----------------------------------------------------------------------===//
// LayoutAlignElem, LayoutAlign support
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -191,36 +212,31 @@ static const std::pair<AlignTypeEnum, LayoutAlignElem> DefaultAlignments[] = {
{VECTOR_ALIGN, {128, Align(16), Align(16)}}, // v16i8, v8i16, v4i32, ...
};

void DataLayout::reset(StringRef Desc) {
clear();

LayoutMap = nullptr;
DataLayout::DataLayout(StringRef LayoutString) {
BigEndian = false;
AllocaAddrSpace = 0;
StackNaturalAlign.reset();
ProgramAddrSpace = 0;
DefaultGlobalsAddrSpace = 0;
FunctionPtrAlign.reset();
TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;
ManglingMode = MM_None;
NonIntegralAddressSpaces.clear();
StructAlignment = LayoutAlignElem::get(Align(1), Align(8), 0);

// Default alignments
for (const auto &[Kind, Layout] : DefaultAlignments) {
if (Error Err = setAlignment(Kind, Layout.ABIAlign, Layout.PrefAlign,
Layout.TypeBitWidth))
return report_fatal_error(std::move(Err));
report_fatal_error(std::move(Err));
}
if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64))
return report_fatal_error(std::move(Err));
report_fatal_error(std::move(Err));

if (Error Err = parseSpecifier(Desc))
return report_fatal_error(std::move(Err));
if (Error Err = parseSpecifier(LayoutString))
report_fatal_error(std::move(Err));
}

DataLayout &DataLayout::operator=(const DataLayout &Other) {
clear();
delete static_cast<StructLayoutMap *>(LayoutMap);
LayoutMap = nullptr;
StringRepresentation = Other.StringRepresentation;
BigEndian = Other.BigEndian;
AllocaAddrSpace = Other.AllocaAddrSpace;
Expand Down Expand Up @@ -693,42 +709,7 @@ Align DataLayout::getIntegerAlignment(uint32_t BitWidth,
return abi_or_pref ? I->ABIAlign : I->PrefAlign;
}

namespace {

class StructLayoutMap {
using LayoutInfoTy = DenseMap<StructType*, StructLayout*>;
LayoutInfoTy LayoutInfo;

public:
~StructLayoutMap() {
// Remove any layouts.
for (const auto &I : LayoutInfo) {
StructLayout *Value = I.second;
Value->~StructLayout();
free(Value);
}
}

StructLayout *&operator[](StructType *STy) {
return LayoutInfo[STy];
}
};

} // end anonymous namespace

void DataLayout::clear() {
LegalIntWidths.clear();
IntAlignments.clear();
FloatAlignments.clear();
VectorAlignments.clear();
Pointers.clear();
delete static_cast<StructLayoutMap *>(LayoutMap);
LayoutMap = nullptr;
}

DataLayout::~DataLayout() {
clear();
}
DataLayout::~DataLayout() { delete static_cast<StructLayoutMap *>(LayoutMap); }

const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
if (!LayoutMap)
Expand Down
4 changes: 1 addition & 3 deletions llvm/lib/IR/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,9 +388,7 @@ void Module::setModuleFlag(ModFlagBehavior Behavior, StringRef Key,
setModuleFlag(Behavior, Key, ConstantInt::get(Int32Ty, Val));
}

void Module::setDataLayout(StringRef Desc) {
DL.reset(Desc);
}
void Module::setDataLayout(StringRef Desc) { DL = DataLayout(Desc); }

void Module::setDataLayout(const DataLayout &Other) { DL = Other; }

Expand Down
21 changes: 21 additions & 0 deletions llvm/unittests/IR/DataLayoutTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,27 @@ using namespace llvm;

namespace {

TEST(DataLayoutTest, CopyAssignmentInvalidatesStructLayout) {
DataLayout DL1 = cantFail(DataLayout::parse("p:32:32"));
DataLayout DL2 = cantFail(DataLayout::parse("p:64:64"));

LLVMContext Ctx;
StructType *Ty = StructType::get(PointerType::getUnqual(Ctx));

// Initialize struct layout caches.
EXPECT_EQ(DL1.getStructLayout(Ty)->getSizeInBits(), 32U);
EXPECT_EQ(DL1.getStructLayout(Ty)->getAlignment(), Align(4));
EXPECT_EQ(DL2.getStructLayout(Ty)->getSizeInBits(), 64U);
EXPECT_EQ(DL2.getStructLayout(Ty)->getAlignment(), Align(8));

// The copy should invalidate DL1's cache.
DL1 = DL2;
EXPECT_EQ(DL1.getStructLayout(Ty)->getSizeInBits(), 64U);
EXPECT_EQ(DL1.getStructLayout(Ty)->getAlignment(), Align(8));
EXPECT_EQ(DL2.getStructLayout(Ty)->getSizeInBits(), 64U);
EXPECT_EQ(DL2.getStructLayout(Ty)->getAlignment(), Align(8));
}

TEST(DataLayoutTest, FunctionPtrAlign) {
EXPECT_EQ(MaybeAlign(0), DataLayout("").getFunctionPtrAlign());
EXPECT_EQ(MaybeAlign(1), DataLayout("Fi8").getFunctionPtrAlign());
Expand Down
Loading