003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/utils/TableGen
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
utils
/
TableGen
/
📁
..
📄
AsmMatcherEmitter.cpp
(149.98 KB)
📄
AsmWriterEmitter.cpp
(46.29 KB)
📄
AsmWriterInst.cpp
(7.57 KB)
📄
AsmWriterInst.h
(3.83 KB)
📄
Attributes.cpp
(3.12 KB)
📄
CTagsEmitter.cpp
(2.52 KB)
📄
CallingConvEmitter.cpp
(11.74 KB)
📄
CodeEmitterGen.cpp
(22.5 KB)
📄
CodeGenDAGPatterns.cpp
(168.72 KB)
📄
CodeGenDAGPatterns.h
(47.85 KB)
📄
CodeGenHwModes.cpp
(3.45 KB)
📄
CodeGenHwModes.h
(1.84 KB)
📄
CodeGenInstruction.cpp
(30.97 KB)
📄
CodeGenInstruction.h
(13.7 KB)
📄
CodeGenIntrinsics.h
(6.6 KB)
📄
CodeGenMapTable.cpp
(23.38 KB)
📄
CodeGenRegisters.cpp
(90.68 KB)
📄
CodeGenRegisters.h
(29.9 KB)
📄
CodeGenSchedule.cpp
(84.92 KB)
📄
CodeGenSchedule.h
(23.14 KB)
📄
CodeGenTarget.cpp
(32.63 KB)
📄
CodeGenTarget.h
(7.22 KB)
📄
DAGISelEmitter.cpp
(6.92 KB)
📄
DAGISelMatcher.cpp
(13.53 KB)
📄
DAGISelMatcher.h
(37.72 KB)
📄
DAGISelMatcherEmitter.cpp
(37.44 KB)
📄
DAGISelMatcherGen.cpp
(44.06 KB)
📄
DAGISelMatcherOpt.cpp
(17.35 KB)
📄
DFAEmitter.cpp
(13.11 KB)
📄
DFAEmitter.h
(3.96 KB)
📄
DFAPacketizerEmitter.cpp
(13.02 KB)
📄
DirectiveEmitter.cpp
(20.15 KB)
📄
DisassemblerEmitter.cpp
(7.02 KB)
📄
ExegesisEmitter.cpp
(7.39 KB)
📄
FastISelEmitter.cpp
(30.83 KB)
📄
FixedLenDecoderEmitter.cpp
(90.04 KB)
📄
GICombinerEmitter.cpp
(40.12 KB)
📁
GlobalISel
📄
GlobalISelEmitter.cpp
(215.56 KB)
📄
InfoByHwMode.cpp
(6.69 KB)
📄
InfoByHwMode.h
(5.74 KB)
📄
InstrDocsEmitter.cpp
(7.05 KB)
📄
InstrInfoEmitter.cpp
(31.52 KB)
📄
IntrinsicEmitter.cpp
(32.87 KB)
📄
OptEmitter.cpp
(2.9 KB)
📄
OptEmitter.h
(575 B)
📄
OptParserEmitter.cpp
(15.16 KB)
📄
OptRSTEmitter.cpp
(2.71 KB)
📄
PredicateExpander.cpp
(17.39 KB)
📄
PredicateExpander.h
(5.19 KB)
📄
PseudoLoweringEmitter.cpp
(11.8 KB)
📄
RISCVCompressInstEmitter.cpp
(39.23 KB)
📄
RegisterBankEmitter.cpp
(12.52 KB)
📄
RegisterInfoEmitter.cpp
(61.32 KB)
📄
SDNodeProperties.cpp
(1.9 KB)
📄
SDNodeProperties.h
(985 B)
📄
SearchableTableEmitter.cpp
(26.81 KB)
📄
SequenceToOffsetTable.h
(8.49 KB)
📄
SubtargetEmitter.cpp
(70.77 KB)
📄
SubtargetFeatureInfo.cpp
(5.72 KB)
📄
SubtargetFeatureInfo.h
(4.05 KB)
📄
TableGen.cpp
(9.7 KB)
📄
TableGenBackends.h
(4.62 KB)
📄
Types.cpp
(1.46 KB)
📄
Types.h
(900 B)
📄
WebAssemblyDisassemblerEmitter.cpp
(6.79 KB)
📄
WebAssemblyDisassemblerEmitter.h
(980 B)
📄
X86DisassemblerShared.h
(1.88 KB)
📄
X86DisassemblerTables.cpp
(42.64 KB)
📄
X86DisassemblerTables.h
(11.7 KB)
📄
X86EVEX2VEXTablesEmitter.cpp
(8.77 KB)
📄
X86FoldTablesEmitter.cpp
(26.09 KB)
📄
X86ModRMFilters.cpp
(636 B)
📄
X86ModRMFilters.h
(4.69 KB)
📄
X86RecognizableInstr.cpp
(47.05 KB)
📄
X86RecognizableInstr.h
(14.13 KB)
Editing: DFAPacketizerEmitter.cpp
//===- DFAPacketizerEmitter.cpp - Packetization DFA for a VLIW machine ----===// // // 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 // //===----------------------------------------------------------------------===// // // This class parses the Schedule.td file and produces an API that can be used // to reason about whether an instruction can be added to a packet on a VLIW // architecture. The class internally generates a deterministic finite // automaton (DFA) that models all possible mappings of machine instructions // to functional units as instructions are added to a packet. // //===----------------------------------------------------------------------===// #define DEBUG_TYPE "dfa-emitter" #include "CodeGenSchedule.h" #include "CodeGenTarget.h" #include "DFAEmitter.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/TableGenBackend.h" #include <cassert> #include <cstdint> #include <map> #include <set> #include <string> #include <unordered_map> #include <vector> using namespace llvm; // We use a uint64_t to represent a resource bitmask. #define DFA_MAX_RESOURCES 64 namespace { using ResourceVector = SmallVector<uint64_t, 4>; struct ScheduleClass { /// The parent itinerary index (processor model ID). unsigned ItineraryID; /// Index within this itinerary of the schedule class. unsigned Idx; /// The index within the uniqued set of required resources of Resources. unsigned ResourcesIdx; /// Conjunctive list of resource requirements: /// {a|b, b|c} => (a OR b) AND (b or c). /// Resources are unique across all itineraries. ResourceVector Resources; }; // Generates and prints out the DFA for resource tracking. class DFAPacketizerEmitter { private: std::string TargetName; RecordKeeper &Records; UniqueVector<ResourceVector> UniqueResources; std::vector<ScheduleClass> ScheduleClasses; std::map<std::string, uint64_t> FUNameToBitsMap; std::map<unsigned, uint64_t> ComboBitToBitsMap; public: DFAPacketizerEmitter(RecordKeeper &R); // Construct a map of function unit names to bits. int collectAllFuncUnits( ArrayRef<const CodeGenProcModel *> ProcModels); // Construct a map from a combo function unit bit to the bits of all included // functional units. int collectAllComboFuncs(ArrayRef<Record *> ComboFuncList); ResourceVector getResourcesForItinerary(Record *Itinerary); void createScheduleClasses(unsigned ItineraryIdx, const RecVec &Itineraries); // Emit code for a subset of itineraries. void emitForItineraries(raw_ostream &OS, std::vector<const CodeGenProcModel *> &ProcItinList, std::string DFAName); void run(raw_ostream &OS); }; } // end anonymous namespace DFAPacketizerEmitter::DFAPacketizerEmitter(RecordKeeper &R) : TargetName(std::string(CodeGenTarget(R).getName())), Records(R) {} int DFAPacketizerEmitter::collectAllFuncUnits( ArrayRef<const CodeGenProcModel *> ProcModels) { LLVM_DEBUG(dbgs() << "-------------------------------------------------------" "----------------------\n"); LLVM_DEBUG(dbgs() << "collectAllFuncUnits"); LLVM_DEBUG(dbgs() << " (" << ProcModels.size() << " itineraries)\n"); std::set<Record *> ProcItinList; for (const CodeGenProcModel *Model : ProcModels) ProcItinList.insert(Model->ItinsDef); int totalFUs = 0; // Parse functional units for all the itineraries. for (Record *Proc : ProcItinList) { std::vector<Record *> FUs = Proc->getValueAsListOfDefs("FU"); LLVM_DEBUG(dbgs() << " FU:" << " (" << FUs.size() << " FUs) " << Proc->getName()); // Convert macros to bits for each stage. unsigned numFUs = FUs.size(); for (unsigned j = 0; j < numFUs; ++j) { assert((j < DFA_MAX_RESOURCES) && "Exceeded maximum number of representable resources"); uint64_t FuncResources = 1ULL << j; FUNameToBitsMap[std::string(FUs[j]->getName())] = FuncResources; LLVM_DEBUG(dbgs() << " " << FUs[j]->getName() << ":0x" << Twine::utohexstr(FuncResources)); } totalFUs += numFUs; LLVM_DEBUG(dbgs() << "\n"); } return totalFUs; } int DFAPacketizerEmitter::collectAllComboFuncs(ArrayRef<Record *> ComboFuncList) { LLVM_DEBUG(dbgs() << "-------------------------------------------------------" "----------------------\n"); LLVM_DEBUG(dbgs() << "collectAllComboFuncs"); LLVM_DEBUG(dbgs() << " (" << ComboFuncList.size() << " sets)\n"); int numCombos = 0; for (unsigned i = 0, N = ComboFuncList.size(); i < N; ++i) { Record *Func = ComboFuncList[i]; std::vector<Record *> FUs = Func->getValueAsListOfDefs("CFD"); LLVM_DEBUG(dbgs() << " CFD:" << i << " (" << FUs.size() << " combo FUs) " << Func->getName() << "\n"); // Convert macros to bits for each stage. for (unsigned j = 0, N = FUs.size(); j < N; ++j) { assert((j < DFA_MAX_RESOURCES) && "Exceeded maximum number of DFA resources"); Record *FuncData = FUs[j]; Record *ComboFunc = FuncData->getValueAsDef("TheComboFunc"); const std::vector<Record *> &FuncList = FuncData->getValueAsListOfDefs("FuncList"); const std::string &ComboFuncName = std::string(ComboFunc->getName()); uint64_t ComboBit = FUNameToBitsMap[ComboFuncName]; uint64_t ComboResources = ComboBit; LLVM_DEBUG(dbgs() << " combo: " << ComboFuncName << ":0x" << Twine::utohexstr(ComboResources) << "\n"); for (unsigned k = 0, M = FuncList.size(); k < M; ++k) { std::string FuncName = std::string(FuncList[k]->getName()); uint64_t FuncResources = FUNameToBitsMap[FuncName]; LLVM_DEBUG(dbgs() << " " << FuncName << ":0x" << Twine::utohexstr(FuncResources) << "\n"); ComboResources |= FuncResources; } ComboBitToBitsMap[ComboBit] = ComboResources; numCombos++; LLVM_DEBUG(dbgs() << " => combo bits: " << ComboFuncName << ":0x" << Twine::utohexstr(ComboBit) << " = 0x" << Twine::utohexstr(ComboResources) << "\n"); } } return numCombos; } ResourceVector DFAPacketizerEmitter::getResourcesForItinerary(Record *Itinerary) { ResourceVector Resources; assert(Itinerary); for (Record *StageDef : Itinerary->getValueAsListOfDefs("Stages")) { uint64_t StageResources = 0; for (Record *Unit : StageDef->getValueAsListOfDefs("Units")) { StageResources |= FUNameToBitsMap[std::string(Unit->getName())]; } if (StageResources != 0) Resources.push_back(StageResources); } return Resources; } void DFAPacketizerEmitter::createScheduleClasses(unsigned ItineraryIdx, const RecVec &Itineraries) { unsigned Idx = 0; for (Record *Itinerary : Itineraries) { if (!Itinerary) { ScheduleClasses.push_back({ItineraryIdx, Idx++, 0, ResourceVector{}}); continue; } ResourceVector Resources = getResourcesForItinerary(Itinerary); ScheduleClasses.push_back( {ItineraryIdx, Idx++, UniqueResources.insert(Resources), Resources}); } } // // Run the worklist algorithm to generate the DFA. // void DFAPacketizerEmitter::run(raw_ostream &OS) { OS << "\n" << "#include \"llvm/CodeGen/DFAPacketizer.h\"\n"; OS << "namespace llvm {\n"; CodeGenTarget CGT(Records); CodeGenSchedModels CGS(Records, CGT); std::unordered_map<std::string, std::vector<const CodeGenProcModel *>> ItinsByNamespace; for (const CodeGenProcModel &ProcModel : CGS.procModels()) { if (ProcModel.hasItineraries()) { auto NS = ProcModel.ItinsDef->getValueAsString("PacketizerNamespace"); ItinsByNamespace[std::string(NS)].push_back(&ProcModel); } } for (auto &KV : ItinsByNamespace) emitForItineraries(OS, KV.second, KV.first); OS << "} // end namespace llvm\n"; } void DFAPacketizerEmitter::emitForItineraries( raw_ostream &OS, std::vector<const CodeGenProcModel *> &ProcModels, std::string DFAName) { OS << "} // end namespace llvm\n\n"; OS << "namespace {\n"; collectAllFuncUnits(ProcModels); collectAllComboFuncs(Records.getAllDerivedDefinitions("ComboFuncUnits")); // Collect the itineraries. DenseMap<const CodeGenProcModel *, unsigned> ProcModelStartIdx; for (const CodeGenProcModel *Model : ProcModels) { assert(Model->hasItineraries()); ProcModelStartIdx[Model] = ScheduleClasses.size(); createScheduleClasses(Model->Index, Model->ItinDefList); } // Output the mapping from ScheduleClass to ResourcesIdx. unsigned Idx = 0; OS << "constexpr unsigned " << TargetName << DFAName << "ResourceIndices[] = {"; for (const ScheduleClass &SC : ScheduleClasses) { if (Idx++ % 32 == 0) OS << "\n "; OS << SC.ResourcesIdx << ", "; } OS << "\n};\n\n"; // And the mapping from Itinerary index into the previous table. OS << "constexpr unsigned " << TargetName << DFAName << "ProcResourceIndexStart[] = {\n"; OS << " 0, // NoSchedModel\n"; for (const CodeGenProcModel *Model : ProcModels) { OS << " " << ProcModelStartIdx[Model] << ", // " << Model->ModelName << "\n"; } OS << ScheduleClasses.size() << "\n};\n\n"; // The type of a state in the nondeterministic automaton we're defining. using NfaStateTy = uint64_t; // Given a resource state, return all resource states by applying // InsnClass. auto applyInsnClass = [&](const ResourceVector &InsnClass, NfaStateTy State) -> std::deque<NfaStateTy> { std::deque<NfaStateTy> V(1, State); // Apply every stage in the class individually. for (NfaStateTy Stage : InsnClass) { // Apply this stage to every existing member of V in turn. size_t Sz = V.size(); for (unsigned I = 0; I < Sz; ++I) { NfaStateTy S = V.front(); V.pop_front(); // For this stage, state combination, try all possible resources. for (unsigned J = 0; J < DFA_MAX_RESOURCES; ++J) { NfaStateTy ResourceMask = 1ULL << J; if ((ResourceMask & Stage) == 0) // This resource isn't required by this stage. continue; NfaStateTy Combo = ComboBitToBitsMap[ResourceMask]; if (Combo && ((~S & Combo) != Combo)) // This combo units bits are not available. continue; NfaStateTy ResultingResourceState = S | ResourceMask | Combo; if (ResultingResourceState == S) continue; V.push_back(ResultingResourceState); } } } return V; }; // Given a resource state, return a quick (conservative) guess as to whether // InsnClass can be applied. This is a filter for the more heavyweight // applyInsnClass. auto canApplyInsnClass = [](const ResourceVector &InsnClass, NfaStateTy State) -> bool { for (NfaStateTy Resources : InsnClass) { if ((State | Resources) == State) return false; } return true; }; DfaEmitter Emitter; std::deque<NfaStateTy> Worklist(1, 0); std::set<NfaStateTy> SeenStates; SeenStates.insert(Worklist.front()); while (!Worklist.empty()) { NfaStateTy State = Worklist.front(); Worklist.pop_front(); for (const ResourceVector &Resources : UniqueResources) { if (!canApplyInsnClass(Resources, State)) continue; unsigned ResourcesID = UniqueResources.idFor(Resources); for (uint64_t NewState : applyInsnClass(Resources, State)) { if (SeenStates.emplace(NewState).second) Worklist.emplace_back(NewState); Emitter.addTransition(State, NewState, ResourcesID); } } } std::string TargetAndDFAName = TargetName + DFAName; Emitter.emit(TargetAndDFAName, OS); OS << "} // end anonymous namespace\n\n"; std::string SubTargetClassName = TargetName + "GenSubtargetInfo"; OS << "namespace llvm {\n"; OS << "DFAPacketizer *" << SubTargetClassName << "::" << "create" << DFAName << "DFAPacketizer(const InstrItineraryData *IID) const {\n" << " static Automaton<uint64_t> A(ArrayRef<" << TargetAndDFAName << "Transition>(" << TargetAndDFAName << "Transitions), " << TargetAndDFAName << "TransitionInfo);\n" << " unsigned ProcResIdxStart = " << TargetAndDFAName << "ProcResourceIndexStart[IID->SchedModel.ProcID];\n" << " unsigned ProcResIdxNum = " << TargetAndDFAName << "ProcResourceIndexStart[IID->SchedModel.ProcID + 1] - " "ProcResIdxStart;\n" << " return new DFAPacketizer(IID, A, {&" << TargetAndDFAName << "ResourceIndices[ProcResIdxStart], ProcResIdxNum});\n" << "\n}\n\n"; } namespace llvm { void EmitDFAPacketizer(RecordKeeper &RK, raw_ostream &OS) { emitSourceFileHeader("Target DFA Packetizer Tables", OS); DFAPacketizerEmitter(RK).run(OS); } } // end namespace llvm
Upload File
Create Folder