#include "CodeGenSchedule.h"
#include "CodeGenInstruction.h"
#include "CodeGenTarget.h"
#include "Utils.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include <algorithm>
#include <iterator>
#include <utility>
usingnamespacellvm;
#define DEBUG_TYPE …
#ifndef NDEBUG
static void dumpIdxVec(ArrayRef<unsigned> V) {
for (unsigned Idx : V)
dbgs() << Idx << ", ";
}
#endif
namespace {
struct InstrsOp : public SetTheory::Operator { … };
struct InstRegexOp : public SetTheory::Operator { … };
}
CodeGenSchedModels::CodeGenSchedModels(const RecordKeeper &RK,
const CodeGenTarget &TGT)
: … { … }
void CodeGenSchedModels::checkSTIPredicates() const { … }
static APInt constructOperandMask(ArrayRef<int64_t> Indices) { … }
static void processSTIPredicate(STIPredicateFunction &Fn,
const ProcModelMapTy &ProcModelMap) { … }
void CodeGenSchedModels::collectSTIPredicates() { … }
void OpcodeInfo::addPredicateForProcModel(const llvm::APInt &CpuMask,
const llvm::APInt &OperandMask,
const Record *Predicate) { … }
void CodeGenSchedModels::checkMCInstPredicates() const { … }
void CodeGenSchedModels::collectRetireControlUnits() { … }
void CodeGenSchedModels::collectLoadStoreQueueInfo() { … }
void CodeGenSchedModels::collectOptionalProcessorInfo() { … }
void CodeGenSchedModels::collectProcModels() { … }
void CodeGenSchedModels::addProcModel(const Record *ProcDef) { … }
static void scanSchedRW(const Record *RWDef, ConstRecVec &RWDefs,
SmallPtrSet<const Record *, 16> &RWSet) { … }
void CodeGenSchedModels::collectSchedRW() { … }
std::string CodeGenSchedModels::genRWName(ArrayRef<unsigned> Seq, bool IsRead) { … }
unsigned CodeGenSchedModels::getSchedRWIdx(const Record *Def,
bool IsRead) const { … }
static void splitSchedReadWrites(const ConstRecVec &RWDefs,
ConstRecVec &WriteDefs,
ConstRecVec &ReadDefs) { … }
void CodeGenSchedModels::findRWs(const ConstRecVec &RWDefs, IdxVec &Writes,
IdxVec &Reads) const { … }
void CodeGenSchedModels::findRWs(const ConstRecVec &RWDefs, IdxVec &RWs,
bool IsRead) const { … }
void CodeGenSchedModels::expandRWSequence(unsigned RWIdx, IdxVec &RWSeq,
bool IsRead) const { … }
void CodeGenSchedModels::expandRWSeqForProc(
unsigned RWIdx, IdxVec &RWSeq, bool IsRead,
const CodeGenProcModel &ProcModel) const { … }
unsigned CodeGenSchedModels::findRWForSequence(ArrayRef<unsigned> Seq,
bool IsRead) { … }
unsigned CodeGenSchedModels::findOrInsertRW(ArrayRef<unsigned> Seq,
bool IsRead) { … }
void CodeGenSchedModels::collectSchedClasses() { … }
unsigned
CodeGenSchedModels::getSchedClassIdx(const CodeGenInstruction &Inst) const { … }
std::string
CodeGenSchedModels::createSchedClassName(const Record *ItinClassDef,
ArrayRef<unsigned> OperWrites,
ArrayRef<unsigned> OperReads) { … }
std::string
CodeGenSchedModels::createSchedClassName(const ConstRecVec &InstDefs) { … }
unsigned CodeGenSchedModels::addSchedClass(const Record *ItinClassDef,
ArrayRef<unsigned> OperWrites,
ArrayRef<unsigned> OperReads,
ArrayRef<unsigned> ProcIndices) { … }
void CodeGenSchedModels::createInstRWClass(const Record *InstRWDef) { … }
bool CodeGenSchedModels::hasItineraries() const { … }
void CodeGenSchedModels::collectProcItins() { … }
void CodeGenSchedModels::collectProcItinRW() { … }
void CodeGenSchedModels::collectProcUnsupportedFeatures() { … }
void CodeGenSchedModels::inferSchedClasses() { … }
void CodeGenSchedModels::inferFromItinClass(const Record *ItinClassDef,
unsigned FromClassIdx) { … }
void CodeGenSchedModels::inferFromInstRWs(unsigned SCIdx) { … }
namespace {
struct TransVariant { … };
struct PredCheck { … };
struct PredTransition { … };
class PredTransitions { … };
}
bool PredTransitions::mutuallyExclusive(const Record *PredDef,
ArrayRef<const Record *> Preds,
ArrayRef<PredCheck> Term) { … }
static std::vector<const Record *>
getAllPredicates(ArrayRef<TransVariant> Variants, unsigned ProcId) { … }
void PredTransitions::getIntersectingVariants(
const CodeGenSchedRW &SchedRW, unsigned TransIdx,
std::vector<TransVariant> &IntersectingVariants) { … }
void PredTransitions::pushVariant(const TransVariant &VInfo, bool IsRead) { … }
bool PredTransitions::substituteVariantOperand(
const SmallVectorImpl<unsigned> &RWSeq, bool IsRead, unsigned StartIdx) { … }
bool PredTransitions::substituteVariants(const PredTransition &Trans) { … }
static void addSequences(CodeGenSchedModels &SchedModels,
const SmallVectorImpl<SmallVector<unsigned, 4>> &Seqs,
IdxVec &Result, bool IsRead) { … }
#ifndef NDEBUG
static void dumpRecVec(const ConstRecVec &RV) {
for (const Record *R : RV)
dbgs() << R->getName() << ", ";
}
#endif
static void dumpTransition(const CodeGenSchedModels &SchedModels,
const CodeGenSchedClass &FromSC,
const CodeGenSchedTransition &SCTrans,
const ConstRecVec &Preds) { … }
static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
unsigned FromClassIdx,
CodeGenSchedModels &SchedModels) { … }
std::vector<unsigned> CodeGenSchedModels::getAllProcIndices() const { … }
static std::vector<PredTransition>
makePerProcessorTransitions(const PredTransition &Trans,
ArrayRef<unsigned> ProcIndices) { … }
void CodeGenSchedModels::inferFromRW(ArrayRef<unsigned> OperWrites,
ArrayRef<unsigned> OperReads,
unsigned FromClassIdx,
ArrayRef<unsigned> ProcIndices) { … }
bool CodeGenSchedModels::hasSuperGroup(ConstRecVec &SubUnits,
CodeGenProcModel &PM) { … }
void CodeGenSchedModels::verifyProcResourceGroups(CodeGenProcModel &PM) { … }
void CodeGenSchedModels::collectRegisterFiles() { … }
void CodeGenSchedModels::collectProcResources() { … }
void CodeGenSchedModels::checkCompleteness() { … }
void CodeGenSchedModels::collectItinProcResources(const Record *ItinClassDef) { … }
void CodeGenSchedModels::collectRWResources(unsigned RWIdx, bool IsRead,
ArrayRef<unsigned> ProcIndices) { … }
void CodeGenSchedModels::collectRWResources(ArrayRef<unsigned> Writes,
ArrayRef<unsigned> Reads,
ArrayRef<unsigned> ProcIndices) { … }
const Record *CodeGenSchedModels::findProcResUnits(const Record *ProcResKind,
const CodeGenProcModel &PM,
ArrayRef<SMLoc> Loc) const { … }
void CodeGenSchedModels::addProcResource(const Record *ProcResKind,
CodeGenProcModel &PM,
ArrayRef<SMLoc> Loc) { … }
void CodeGenSchedModels::addWriteRes(const Record *ProcWriteResDef,
unsigned PIdx) { … }
void CodeGenSchedModels::addReadAdvance(const Record *ProcReadAdvanceDef,
unsigned PIdx) { … }
unsigned CodeGenProcModel::getProcResourceIdx(const Record *PRDef) const { … }
bool CodeGenProcModel::isUnsupported(const CodeGenInstruction &Inst) const { … }
bool CodeGenProcModel::hasReadOfWrite(const Record *WriteDef) const { … }
#ifndef NDEBUG
void CodeGenProcModel::dump() const {
dbgs() << Index << ": " << ModelName << " "
<< (ModelDef ? ModelDef->getName() : "inferred") << " "
<< (ItinsDef ? ItinsDef->getName() : "no itinerary") << '\n';
}
void CodeGenSchedRW::dump() const {
dbgs() << Name << (IsVariadic ? " (V) " : " ");
if (IsSequence) {
dbgs() << "(";
dumpIdxVec(Sequence);
dbgs() << ")";
}
}
void CodeGenSchedClass::dump(const CodeGenSchedModels *SchedModels) const {
dbgs() << "SCHEDCLASS " << Index << ":" << Name << '\n' << " Writes: ";
for (unsigned i = 0, N = Writes.size(); i < N; ++i) {
SchedModels->getSchedWrite(Writes[i]).dump();
if (i < N - 1) {
dbgs() << '\n';
dbgs().indent(10);
}
}
dbgs() << "\n Reads: ";
for (unsigned i = 0, N = Reads.size(); i < N; ++i) {
SchedModels->getSchedRead(Reads[i]).dump();
if (i < N - 1) {
dbgs() << '\n';
dbgs().indent(10);
}
}
dbgs() << "\n ProcIdx: ";
dumpIdxVec(ProcIndices);
if (!Transitions.empty()) {
dbgs() << "\n Transitions for Proc ";
for (const CodeGenSchedTransition &Transition : Transitions) {
dbgs() << Transition.ProcIndex << ", ";
}
}
dbgs() << '\n';
}
void PredTransitions::dump() const {
dbgs() << "Expanded Variants:\n";
for (const auto &TI : TransVec) {
dbgs() << "{";
ListSeparator LS;
for (const PredCheck &PC : TI.PredTerm)
dbgs() << LS << SchedModels.getSchedRW(PC.RWIdx, PC.IsRead).Name << ":"
<< PC.Predicate->getName();
dbgs() << "},\n => {";
for (SmallVectorImpl<SmallVector<unsigned, 4>>::const_iterator
WSI = TI.WriteSequences.begin(),
WSE = TI.WriteSequences.end();
WSI != WSE; ++WSI) {
dbgs() << "(";
ListSeparator LS;
for (unsigned N : *WSI)
dbgs() << LS << SchedModels.getSchedWrite(N).Name;
dbgs() << "),";
}
dbgs() << "}\n";
}
}
#endif