mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
5445e7fafa
Summary: This patch introduces -gen-automata, a backend for generating deterministic finite-state automata. DFAs are already generated by the -gen-dfa-packetizer backend. This backend is more generic and will hopefully be used to implement the DFA generation (and determinization) for the packetizer in the future. This backend allows not only generation of a DFA from an NFA (nondeterministic finite-state automaton), it also emits sidetables that allow a path through the DFA under a sequence of inputs to be analyzed, and the equivalent set of all possible NFA transitions extracted. This allows a user to not just answer "can my problem be solved?" but also "what is the solution?". Clearly this analysis is more expensive than just playing a DFA forwards so is opt-in. The DFAPacketizer has this behaviour already but this is a more compact and generic representation. Examples are bundled in unittests/TableGen/Automata.td. Some are trivial, but the BinPacking example is a stripped-down version of the original target problem I set out to solve, where we pack values (actually immediates) into bins (an immediate pool in a VLIW bundle) subject to a set of esoteric constraints. Reviewers: t.p.northover Subscribers: mgorny, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D67968 llvm-svn: 373718
287 lines
9.0 KiB
C++
287 lines
9.0 KiB
C++
//===- TableGen.cpp - Top-Level TableGen implementation for LLVM ----------===//
|
|
//
|
|
// 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 file contains the main function for LLVM's TableGen.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "TableGenBackends.h" // Declares all backends.
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/ManagedStatic.h"
|
|
#include "llvm/Support/PrettyStackTrace.h"
|
|
#include "llvm/Support/Signals.h"
|
|
#include "llvm/TableGen/Main.h"
|
|
#include "llvm/TableGen/Record.h"
|
|
#include "llvm/TableGen/SetTheory.h"
|
|
|
|
using namespace llvm;
|
|
|
|
enum ActionType {
|
|
PrintRecords,
|
|
DumpJSON,
|
|
GenEmitter,
|
|
GenRegisterInfo,
|
|
GenInstrInfo,
|
|
GenInstrDocs,
|
|
GenAsmWriter,
|
|
GenAsmMatcher,
|
|
GenDisassembler,
|
|
GenPseudoLowering,
|
|
GenCompressInst,
|
|
GenCallingConv,
|
|
GenDAGISel,
|
|
GenDFAPacketizer,
|
|
GenFastISel,
|
|
GenSubtarget,
|
|
GenIntrinsicEnums,
|
|
GenIntrinsicImpl,
|
|
GenTgtIntrinsicEnums,
|
|
GenTgtIntrinsicImpl,
|
|
PrintEnums,
|
|
PrintSets,
|
|
GenOptParserDefs,
|
|
GenCTags,
|
|
GenAttributes,
|
|
GenSearchableTables,
|
|
GenGlobalISel,
|
|
GenGICombiner,
|
|
GenX86EVEX2VEXTables,
|
|
GenX86FoldTables,
|
|
GenRegisterBank,
|
|
GenExegesis,
|
|
GenAutomata,
|
|
};
|
|
|
|
namespace llvm {
|
|
/// Storage for TimeRegionsOpt as a global so that backends aren't required to
|
|
/// include CommandLine.h
|
|
bool TimeRegions = false;
|
|
} // end namespace llvm
|
|
|
|
namespace {
|
|
cl::opt<ActionType> Action(
|
|
cl::desc("Action to perform:"),
|
|
cl::values(
|
|
clEnumValN(PrintRecords, "print-records",
|
|
"Print all records to stdout (default)"),
|
|
clEnumValN(DumpJSON, "dump-json",
|
|
"Dump all records as machine-readable JSON"),
|
|
clEnumValN(GenEmitter, "gen-emitter", "Generate machine code emitter"),
|
|
clEnumValN(GenRegisterInfo, "gen-register-info",
|
|
"Generate registers and register classes info"),
|
|
clEnumValN(GenInstrInfo, "gen-instr-info",
|
|
"Generate instruction descriptions"),
|
|
clEnumValN(GenInstrDocs, "gen-instr-docs",
|
|
"Generate instruction documentation"),
|
|
clEnumValN(GenCallingConv, "gen-callingconv",
|
|
"Generate calling convention descriptions"),
|
|
clEnumValN(GenAsmWriter, "gen-asm-writer", "Generate assembly writer"),
|
|
clEnumValN(GenDisassembler, "gen-disassembler",
|
|
"Generate disassembler"),
|
|
clEnumValN(GenPseudoLowering, "gen-pseudo-lowering",
|
|
"Generate pseudo instruction lowering"),
|
|
clEnumValN(GenCompressInst, "gen-compress-inst-emitter",
|
|
"Generate RISCV compressed instructions."),
|
|
clEnumValN(GenAsmMatcher, "gen-asm-matcher",
|
|
"Generate assembly instruction matcher"),
|
|
clEnumValN(GenDAGISel, "gen-dag-isel",
|
|
"Generate a DAG instruction selector"),
|
|
clEnumValN(GenDFAPacketizer, "gen-dfa-packetizer",
|
|
"Generate DFA Packetizer for VLIW targets"),
|
|
clEnumValN(GenFastISel, "gen-fast-isel",
|
|
"Generate a \"fast\" instruction selector"),
|
|
clEnumValN(GenSubtarget, "gen-subtarget",
|
|
"Generate subtarget enumerations"),
|
|
clEnumValN(GenIntrinsicEnums, "gen-intrinsic-enums",
|
|
"Generate intrinsic enums"),
|
|
clEnumValN(GenIntrinsicImpl, "gen-intrinsic-impl",
|
|
"Generate intrinsic information"),
|
|
clEnumValN(GenTgtIntrinsicEnums, "gen-tgt-intrinsic-enums",
|
|
"Generate target intrinsic enums"),
|
|
clEnumValN(GenTgtIntrinsicImpl, "gen-tgt-intrinsic-impl",
|
|
"Generate target intrinsic information"),
|
|
clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"),
|
|
clEnumValN(PrintSets, "print-sets",
|
|
"Print expanded sets for testing DAG exprs"),
|
|
clEnumValN(GenOptParserDefs, "gen-opt-parser-defs",
|
|
"Generate option definitions"),
|
|
clEnumValN(GenCTags, "gen-ctags", "Generate ctags-compatible index"),
|
|
clEnumValN(GenAttributes, "gen-attrs", "Generate attributes"),
|
|
clEnumValN(GenSearchableTables, "gen-searchable-tables",
|
|
"Generate generic binary-searchable table"),
|
|
clEnumValN(GenGlobalISel, "gen-global-isel",
|
|
"Generate GlobalISel selector"),
|
|
clEnumValN(GenGICombiner, "gen-global-isel-combiner",
|
|
"Generate GlobalISel combiner"),
|
|
clEnumValN(GenX86EVEX2VEXTables, "gen-x86-EVEX2VEX-tables",
|
|
"Generate X86 EVEX to VEX compress tables"),
|
|
clEnumValN(GenX86FoldTables, "gen-x86-fold-tables",
|
|
"Generate X86 fold tables"),
|
|
clEnumValN(GenRegisterBank, "gen-register-bank",
|
|
"Generate registers bank descriptions"),
|
|
clEnumValN(GenExegesis, "gen-exegesis",
|
|
"Generate llvm-exegesis tables"),
|
|
clEnumValN(GenAutomata, "gen-automata",
|
|
"Generate generic automata")));
|
|
|
|
cl::OptionCategory PrintEnumsCat("Options for -print-enums");
|
|
cl::opt<std::string> Class("class", cl::desc("Print Enum list for this class"),
|
|
cl::value_desc("class name"),
|
|
cl::cat(PrintEnumsCat));
|
|
|
|
cl::opt<bool, true>
|
|
TimeRegionsOpt("time-regions",
|
|
cl::desc("Time regions of tablegens execution"),
|
|
cl::location(TimeRegions));
|
|
|
|
bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
|
|
switch (Action) {
|
|
case PrintRecords:
|
|
OS << Records; // No argument, dump all contents
|
|
break;
|
|
case DumpJSON:
|
|
EmitJSON(Records, OS);
|
|
break;
|
|
case GenEmitter:
|
|
EmitCodeEmitter(Records, OS);
|
|
break;
|
|
case GenRegisterInfo:
|
|
EmitRegisterInfo(Records, OS);
|
|
break;
|
|
case GenInstrInfo:
|
|
EmitInstrInfo(Records, OS);
|
|
break;
|
|
case GenInstrDocs:
|
|
EmitInstrDocs(Records, OS);
|
|
break;
|
|
case GenCallingConv:
|
|
EmitCallingConv(Records, OS);
|
|
break;
|
|
case GenAsmWriter:
|
|
EmitAsmWriter(Records, OS);
|
|
break;
|
|
case GenAsmMatcher:
|
|
EmitAsmMatcher(Records, OS);
|
|
break;
|
|
case GenDisassembler:
|
|
EmitDisassembler(Records, OS);
|
|
break;
|
|
case GenPseudoLowering:
|
|
EmitPseudoLowering(Records, OS);
|
|
break;
|
|
case GenCompressInst:
|
|
EmitCompressInst(Records, OS);
|
|
break;
|
|
case GenDAGISel:
|
|
EmitDAGISel(Records, OS);
|
|
break;
|
|
case GenDFAPacketizer:
|
|
EmitDFAPacketizer(Records, OS);
|
|
break;
|
|
case GenFastISel:
|
|
EmitFastISel(Records, OS);
|
|
break;
|
|
case GenSubtarget:
|
|
EmitSubtarget(Records, OS);
|
|
break;
|
|
case GenIntrinsicEnums:
|
|
EmitIntrinsicEnums(Records, OS);
|
|
break;
|
|
case GenIntrinsicImpl:
|
|
EmitIntrinsicImpl(Records, OS);
|
|
break;
|
|
case GenTgtIntrinsicEnums:
|
|
EmitIntrinsicEnums(Records, OS, true);
|
|
break;
|
|
case GenTgtIntrinsicImpl:
|
|
EmitIntrinsicImpl(Records, OS, true);
|
|
break;
|
|
case GenOptParserDefs:
|
|
EmitOptParser(Records, OS);
|
|
break;
|
|
case PrintEnums:
|
|
{
|
|
for (Record *Rec : Records.getAllDerivedDefinitions(Class))
|
|
OS << Rec->getName() << ", ";
|
|
OS << "\n";
|
|
break;
|
|
}
|
|
case PrintSets:
|
|
{
|
|
SetTheory Sets;
|
|
Sets.addFieldExpander("Set", "Elements");
|
|
for (Record *Rec : Records.getAllDerivedDefinitions("Set")) {
|
|
OS << Rec->getName() << " = [";
|
|
const std::vector<Record*> *Elts = Sets.expand(Rec);
|
|
assert(Elts && "Couldn't expand Set instance");
|
|
for (Record *Elt : *Elts)
|
|
OS << ' ' << Elt->getName();
|
|
OS << " ]\n";
|
|
}
|
|
break;
|
|
}
|
|
case GenCTags:
|
|
EmitCTags(Records, OS);
|
|
break;
|
|
case GenAttributes:
|
|
EmitAttributes(Records, OS);
|
|
break;
|
|
case GenSearchableTables:
|
|
EmitSearchableTables(Records, OS);
|
|
break;
|
|
case GenGlobalISel:
|
|
EmitGlobalISel(Records, OS);
|
|
break;
|
|
case GenGICombiner:
|
|
EmitGICombiner(Records, OS);
|
|
break;
|
|
case GenRegisterBank:
|
|
EmitRegisterBank(Records, OS);
|
|
break;
|
|
case GenX86EVEX2VEXTables:
|
|
EmitX86EVEX2VEXTables(Records, OS);
|
|
break;
|
|
case GenX86FoldTables:
|
|
EmitX86FoldTables(Records, OS);
|
|
break;
|
|
case GenExegesis:
|
|
EmitExegesis(Records, OS);
|
|
break;
|
|
case GenAutomata:
|
|
EmitAutomata(Records, OS);
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
sys::PrintStackTraceOnErrorSignal(argv[0]);
|
|
PrettyStackTraceProgram X(argc, argv);
|
|
cl::ParseCommandLineOptions(argc, argv);
|
|
|
|
llvm_shutdown_obj Y;
|
|
|
|
return TableGenMain(argv[0], &LLVMTableGenMain);
|
|
}
|
|
|
|
#ifndef __has_feature
|
|
#define __has_feature(x) 0
|
|
#endif
|
|
|
|
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) || \
|
|
__has_feature(leak_sanitizer)
|
|
|
|
#include <sanitizer/lsan_interface.h>
|
|
// Disable LeakSanitizer for this binary as it has too many leaks that are not
|
|
// very interesting to fix. See compiler-rt/include/sanitizer/lsan_interface.h .
|
|
LLVM_ATTRIBUTE_USED int __lsan_is_turned_off() { return 1; }
|
|
|
|
#endif
|