1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00
llvm-mirror/utils/TableGen/DFAEmitter.h
James Molloy 5445e7fafa [TableGen] Introduce a generic automaton (DFA) backend
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
2019-10-04 09:03:36 +00:00

108 lines
4.0 KiB
C++

//===--------------------- DfaEmitter.h -----------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// Defines a generic automaton builder. This takes a set of transitions and
// states that represent a nondeterministic finite state automaton (NFA) and
// emits a determinized DFA in a form that include/llvm/Support/Automaton.h can
// drive.
//
// See file llvm/TableGen/Automaton.td for the TableGen API definition.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_UTILS_TABLEGEN_DFAEMITTER_H
#define LLVM_UTILS_TABLEGEN_DFAEMITTER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/UniqueVector.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Record.h"
#include <set>
#include <unordered_map>
namespace llvm {
class raw_ostream;
/// Construct a deterministic finite state automaton from possible
/// nondeterministic state and transition data.
///
/// The state type is a 64-bit unsigned integer. The generated automaton is
/// invariant to the sparsity of the state representation - its size is only
/// a function of the cardinality of the set of states.
///
/// The inputs to this emitter are considered to define a nondeterministic
/// finite state automaton (NFA). This is then converted to a DFA during
/// emission. The emitted tables can be used to by
/// include/llvm/Support/Automaton.h.
class DfaEmitter {
public:
// The type of an NFA state. The initial state is always zero.
using state_type = uint64_t;
// The type of an action.
using action_type = uint64_t;
DfaEmitter() = default;
virtual ~DfaEmitter() = default;
void addTransition(state_type From, state_type To, action_type A);
void emit(StringRef Name, raw_ostream &OS);
protected:
/// Emit the C++ type of an action to OS.
virtual void printActionType(raw_ostream &OS);
/// Emit the C++ value of an action A to OS.
virtual void printActionValue(action_type A, raw_ostream &OS);
private:
/// The state type of deterministic states. These are only used internally to
/// this class. This is an ID into the DfaStates UniqueVector.
using dfa_state_type = unsigned;
/// The actual representation of a DFA state, which is a union of one or more
/// NFA states.
using DfaState = SmallVector<state_type, 4>;
/// A DFA transition consists of a set of NFA states transitioning to a
/// new set of NFA states. The DfaTransitionInfo tracks, for every
/// transitioned-from NFA state, a set of valid transitioned-to states.
///
/// Emission of this transition relation allows algorithmic determination of
/// the possible candidate NFA paths taken under a given input sequence to
/// reach a given DFA state.
using DfaTransitionInfo = SmallVector<std::pair<state_type, state_type>, 4>;
/// The set of all possible actions.
std::set<action_type> Actions;
/// The set of nondeterministic transitions. A state-action pair can
/// transition to multiple target states.
std::map<std::pair<state_type, action_type>, std::vector<state_type>>
NfaTransitions;
std::set<state_type> NfaStates;
unsigned NumNfaTransitions = 0;
/// The set of deterministic states. DfaStates.getId(DfaState) returns an ID,
/// which is dfa_state_type. Note that because UniqueVector reserves state
/// zero, the initial DFA state is always 1.
UniqueVector<DfaState> DfaStates;
/// The set of deterministic transitions. A state-action pair has only a
/// single target state.
std::map<std::pair<dfa_state_type, action_type>,
std::pair<dfa_state_type, DfaTransitionInfo>>
DfaTransitions;
/// Visit all NFA states and construct the DFA.
void constructDfa();
/// Visit a single DFA state and construct all possible transitions to new DFA
/// states.
void visitDfaState(DfaState DS);
};
} // namespace llvm
#endif