blob: 5f1958ad0b66577643042a3500e8b70bf6442c76 [file] [edit]
//===- AttributeTableEmitter.h ----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Helpers for emitting compact tables of IR attributes. AttributeSetTable
// uniques attribute sets and emits the cases of a switch constructing each one.
// AttributeSequenceTable uniques per-entity sequences of argument attribute
// entries and emits them as one table, sharing storage between sequences.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_UTILS_TABLEGEN_BASIC_ATTRIBUTETABLEEMITTER_H
#define LLVM_UTILS_TABLEGEN_BASIC_ATTRIBUTETABLEEMITTER_H
#include "SequenceToOffsetTable.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/UniqueVector.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
/// Uniques attribute sets, keyed by \p KeyT, and assigns them dense IDs in
/// insertion order.
template <typename KeyT> class AttributeSetTable {
UniqueVector<KeyT> Sets;
public:
/// Returns the ID of the set \p Attrs.
unsigned add(const KeyT &Attrs) { return Sets.insert(Attrs) - 1; }
unsigned size() const { return static_cast<unsigned>(Sets.size()); }
/// Emits a switch case returning each set, in ID order. \p Print emits the
/// attributes of a non-empty set. If provided, \p WriteComment writes a
/// comment for the case of each ID.
void emitCases(
raw_ostream &OS, function_ref<void(raw_ostream &, const KeyT &)> Print,
function_ref<void(raw_ostream &, unsigned)> WriteComment = {}) const {
for (const auto &[ID, Attrs] : enumerate(Sets)) {
OS << "\n case " << ID << ':';
if (WriteComment) {
OS << " // ";
WriteComment(OS, ID);
}
if (Attrs.empty()) {
OS << "\n return AttributeSet();";
continue;
}
OS << "\n return AttributeSet::get(C, {\n";
Print(OS, Attrs);
OS << " });";
}
}
};
/// Uniques sequences of argument attribute entries, assigning them dense IDs in
/// insertion order, and lays them out in a single table where a sequence that
/// is a suffix of another shares its storage.
template <typename EntryT> class AttributeSequenceTable {
public:
using Sequence = SmallVector<EntryT, 0>;
private:
SequenceToOffsetTable<Sequence> Table{std::nullopt};
UniqueVector<Sequence> Seqs;
public:
/// Returns the ID of \p Seq. Must be called before the table is laid out.
unsigned add(const Sequence &Seq) {
size_t NumSeqs = Seqs.size();
unsigned ID = Seqs.insert(Seq) - 1;
if (Seqs.size() != NumSeqs && !Seq.empty())
Table.add(Seq);
return ID;
}
void layout() { Table.layout(); }
/// Number of sequences.
unsigned numSequences() const { return static_cast<unsigned>(Seqs.size()); }
/// Number of entries in the laid out table.
unsigned size() const { return Table.size(); }
/// Emits the entries of the laid out table.
void emitEntries(raw_ostream &OS,
function_ref<void(raw_ostream &, EntryT)> Print) const {
Table.emit(OS, Print);
}
/// Emits the start index and length of each sequence, in ID order.
void emitInfo(raw_ostream &OS) const {
for (const Sequence &Seq : Seqs) {
unsigned Start = Seq.empty() ? 0 : Table.get(Seq);
OS << formatv(" {{{}, {}},\n", Start, Seq.size());
}
}
};
} // namespace llvm
#endif // LLVM_UTILS_TABLEGEN_BASIC_ATTRIBUTETABLEEMITTER_H