[Bitcode] Refactor attribute group writing to avoid getSlotAttributes

Summary:
That API creates a temporary AttributeList to carry an index and a
single AttributeSet. We need to carry the index in addition to the set,
because that is how attribute groups are currently encoded.

NFC

Reviewers: pcc

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D32262

llvm-svn: 301245
This commit is contained in:
Reid Kleckner 2017-04-24 20:38:30 +00:00
parent b2c390e9f5
commit b4a2d18777
5 changed files with 65 additions and 54 deletions

View File

@ -511,6 +511,9 @@ public:
/// \brief Return the attributes at the given slot.
AttributeList getSlotAttributes(unsigned Slot) const;
/// \brief Return the attributes at the given slot.
AttributeSet getSlotSet(unsigned Slot) const;
void dump() const;
};

View File

@ -726,54 +726,50 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
}
void ModuleBitcodeWriter::writeAttributeGroupTable() {
const std::vector<AttributeList> &AttrGrps = VE.getAttributeGroups();
const std::vector<ValueEnumerator::IndexAndAttrSet> &AttrGrps =
VE.getAttributeGroups();
if (AttrGrps.empty()) return;
Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3);
SmallVector<uint64_t, 64> Record;
for (unsigned i = 0, e = AttrGrps.size(); i != e; ++i) {
AttributeList AS = AttrGrps[i];
for (unsigned i = 0, e = AS.getNumSlots(); i != e; ++i) {
AttributeList A = AS.getSlotAttributes(i);
for (ValueEnumerator::IndexAndAttrSet Pair : AttrGrps) {
unsigned AttrListIndex = Pair.first;
AttributeSet AS = Pair.second;
Record.push_back(VE.getAttributeGroupID(Pair));
Record.push_back(AttrListIndex);
Record.push_back(VE.getAttributeGroupID(A));
Record.push_back(AS.getSlotIndex(i));
for (Attribute Attr : AS) {
if (Attr.isEnumAttribute()) {
Record.push_back(0);
Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
} else if (Attr.isIntAttribute()) {
Record.push_back(1);
Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
Record.push_back(Attr.getValueAsInt());
} else {
StringRef Kind = Attr.getKindAsString();
StringRef Val = Attr.getValueAsString();
for (AttributeList::iterator I = AS.begin(0), E = AS.end(0); I != E;
++I) {
Attribute Attr = *I;
if (Attr.isEnumAttribute()) {
Record.push_back(Val.empty() ? 3 : 4);
Record.append(Kind.begin(), Kind.end());
Record.push_back(0);
if (!Val.empty()) {
Record.append(Val.begin(), Val.end());
Record.push_back(0);
Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
} else if (Attr.isIntAttribute()) {
Record.push_back(1);
Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
Record.push_back(Attr.getValueAsInt());
} else {
StringRef Kind = Attr.getKindAsString();
StringRef Val = Attr.getValueAsString();
Record.push_back(Val.empty() ? 3 : 4);
Record.append(Kind.begin(), Kind.end());
Record.push_back(0);
if (!Val.empty()) {
Record.append(Val.begin(), Val.end());
Record.push_back(0);
}
}
}
Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record);
Record.clear();
}
Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record);
Record.clear();
}
Stream.ExitBlock();
}
void ModuleBitcodeWriter::writeAttributeTable() {
const std::vector<AttributeList> &Attrs = VE.getAttributes();
const std::vector<AttributeList> &Attrs = VE.getAttributeLists();
if (Attrs.empty()) return;
Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3);
@ -782,7 +778,8 @@ void ModuleBitcodeWriter::writeAttributeTable() {
for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
const AttributeList &A = Attrs[i];
for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i)
Record.push_back(VE.getAttributeGroupID(A.getSlotAttributes(i)));
Record.push_back(
VE.getAttributeGroupID({A.getSlotIndex(i), A.getSlotSet(i)}));
Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record);
Record.clear();
@ -1270,7 +1267,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
Vals.push_back(F.getCallingConv());
Vals.push_back(F.isDeclaration());
Vals.push_back(getEncodedLinkage(F));
Vals.push_back(VE.getAttributeID(F.getAttributes()));
Vals.push_back(VE.getAttributeListID(F.getAttributes()));
Vals.push_back(Log2_32(F.getAlignment())+1);
Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
Vals.push_back(getEncodedVisibility(F));
@ -2616,7 +2613,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
Code = bitc::FUNC_CODE_INST_INVOKE;
Vals.push_back(VE.getAttributeID(II->getAttributes()));
Vals.push_back(VE.getAttributeListID(II->getAttributes()));
Vals.push_back(II->getCallingConv() | 1 << 13);
Vals.push_back(VE.getValueID(II->getNormalDest()));
Vals.push_back(VE.getValueID(II->getUnwindDest()));
@ -2808,7 +2805,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
Code = bitc::FUNC_CODE_INST_CALL;
Vals.push_back(VE.getAttributeID(CI.getAttributes()));
Vals.push_back(VE.getAttributeListID(CI.getAttributes()));
unsigned Flags = getOptimizationFlags(&I);
Vals.push_back(CI.getCallingConv() << bitc::CALL_CCONV |

View File

@ -891,19 +891,19 @@ void ValueEnumerator::EnumerateAttributes(AttributeList PAL) {
if (PAL.isEmpty()) return; // null is always 0.
// Do a lookup.
unsigned &Entry = AttributeMap[PAL];
unsigned &Entry = AttributeListMap[PAL];
if (Entry == 0) {
// Never saw this before, add it.
Attribute.push_back(PAL);
Entry = Attribute.size();
AttributeLists.push_back(PAL);
Entry = AttributeLists.size();
}
// Do lookups for all attribute groups.
for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) {
AttributeList AS = PAL.getSlotAttributes(i);
unsigned &Entry = AttributeGroupMap[AS];
IndexAndAttrSet Pair = {PAL.getSlotIndex(i), PAL.getSlotSet(i)};
unsigned &Entry = AttributeGroupMap[Pair];
if (Entry == 0) {
AttributeGroups.push_back(AS);
AttributeGroups.push_back(Pair);
Entry = AttributeGroups.size();
}
}

View File

@ -48,6 +48,10 @@ public:
// For each value, we remember its Value* and occurrence frequency.
typedef std::vector<std::pair<const Value*, unsigned> > ValueList;
/// Attribute groups as encoded in bitcode are almost AttributeSets, but they
/// include the AttributeList index, so we have to track that in our map.
typedef std::pair<unsigned, AttributeSet> IndexAndAttrSet;
UseListOrderStack UseListOrders;
private:
@ -102,13 +106,13 @@ private:
bool ShouldPreserveUseListOrder;
typedef DenseMap<AttributeList, unsigned> AttributeGroupMapType;
typedef DenseMap<IndexAndAttrSet, unsigned> AttributeGroupMapType;
AttributeGroupMapType AttributeGroupMap;
std::vector<AttributeList> AttributeGroups;
std::vector<IndexAndAttrSet> AttributeGroups;
typedef DenseMap<AttributeList, unsigned> AttributeMapType;
AttributeMapType AttributeMap;
std::vector<AttributeList> Attribute;
typedef DenseMap<AttributeList, unsigned> AttributeListMapType;
AttributeListMapType AttributeListMap;
std::vector<AttributeList> AttributeLists;
/// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
/// the "getGlobalBasicBlockID" method.
@ -166,16 +170,17 @@ public:
unsigned getInstructionID(const Instruction *I) const;
void setInstructionID(const Instruction *I);
unsigned getAttributeID(AttributeList PAL) const {
unsigned getAttributeListID(AttributeList PAL) const {
if (PAL.isEmpty()) return 0; // Null maps to zero.
AttributeMapType::const_iterator I = AttributeMap.find(PAL);
assert(I != AttributeMap.end() && "Attribute not in ValueEnumerator!");
AttributeListMapType::const_iterator I = AttributeListMap.find(PAL);
assert(I != AttributeListMap.end() && "Attribute not in ValueEnumerator!");
return I->second;
}
unsigned getAttributeGroupID(AttributeList PAL) const {
if (PAL.isEmpty()) return 0; // Null maps to zero.
AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(PAL);
unsigned getAttributeGroupID(IndexAndAttrSet Group) const {
if (!Group.second.hasAttributes())
return 0; // Null maps to zero.
AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(Group);
assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!");
return I->second;
}
@ -206,8 +211,8 @@ public:
const std::vector<const BasicBlock*> &getBasicBlocks() const {
return BasicBlocks;
}
const std::vector<AttributeList> &getAttributes() const { return Attribute; }
const std::vector<AttributeList> &getAttributeGroups() const {
const std::vector<AttributeList> &getAttributeLists() const { return AttributeLists; }
const std::vector<IndexAndAttrSet> &getAttributeGroups() const {
return AttributeGroups;
}

View File

@ -1257,6 +1257,12 @@ AttributeList AttributeList::getSlotAttributes(unsigned Slot) const {
return pImpl->getSlotAttributes(Slot);
}
AttributeSet AttributeList::getSlotSet(unsigned Slot) const {
assert(pImpl && Slot < pImpl->getNumSlots() &&
"Slot # out of range!");
return pImpl->getSlotNode(Slot);
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void AttributeList::dump() const {
dbgs() << "PAL[\n";