1include "llvm/TableGen/Automaton.td" 2include "llvm/TableGen/SearchableTable.td" 3 4// Define a set of input token symbols. 5class SymKindTy; 6def SK_a : SymKindTy; 7def SK_b : SymKindTy; 8def SK_c : SymKindTy; 9def SK_d : SymKindTy; 10 11// Emit those as a C++ enum using SearchableTables. 12def SymKind : GenericEnum { 13 let FilterClass = "SymKindTy"; 14} 15 16// Define a transition implementation. 17class SimpleTransition<bits<2> State, SymKindTy A> : Transition { 18 let NewState{1...0} = State; 19 SymKindTy ActionSym = A; 20} 21 22// Token SK_a sets bit 0b01. 23def : SimpleTransition<0b01, SK_a>; 24// Token SK_b sets bits 0b10. 25def : SimpleTransition<0b10, SK_b>; 26// Token SK_c sets both bits 0b11. 27def : SimpleTransition<0b11, SK_c>; 28 29def SimpleAutomaton : GenericAutomaton { 30 let TransitionClass = "SimpleTransition"; 31 let SymbolFields = ["ActionSym"]; 32 // Override the type of ActionSym from SymKindTy to the C++ type SymKind. 33 string TypeOf_ActionSym = "SymKind"; 34} 35 36//===----------------------------------------------------------------------===// 37// TupleActionAutomaton test implementation 38 39// Define a transition implementation. 40class TupleTransition<bits<2> State, SymKindTy s1, SymKindTy s2, string s3> : Transition { 41 let NewState{1...0} = State; 42 SymKindTy S1 = s1; 43 SymKindTy S2 = s2; 44 string S3 = s3; 45} 46 47def : TupleTransition<0b01, SK_a, SK_b, "yeet">; 48def : TupleTransition<0b10, SK_b, SK_b, "foo">; 49def : TupleTransition<0b10, SK_c, SK_a, "foo">; 50 51def TupleAutomaton : GenericAutomaton { 52 let TransitionClass = "TupleTransition"; 53 let SymbolFields = ["S1", "S2", "S3"]; 54 string TypeOf_S1 = "SymKind"; 55 string TypeOf_S2 = "SymKind"; 56} 57 58//===----------------------------------------------------------------------===// 59// NfaAutomaton test implementation 60 61class NfaTransition<bits<2> State, SymKindTy S> : Transition { 62 let NewState{1...0} = State; 63 SymKindTy A = S; 64} 65 66// Symbols a and b can transition to 0b01 or 0b11 (sets bit 0). 67def : NfaTransition<0b01, SK_a>; 68def : NfaTransition<0b01, SK_b>; 69// Symbols a and b can also transition to 0b10 or 0b11 (sets bit 1). 70def : NfaTransition<0b10, SK_a>; 71def : NfaTransition<0b10, SK_b>; 72 73def NfaAutomaton : GenericAutomaton { 74 let TransitionClass = "NfaTransition"; 75 let SymbolFields = ["A"]; 76 string TypeOf_A = "SymKind"; 77} 78 79//===----------------------------------------------------------------------===// 80// BinPacker test implementation 81//===----------------------------------------------------------------------===// 82// This test generates an automaton that can pack values into bins subject to 83// constraints. There are 6 possible bins, and the input tokens are constraint 84// types. Some input types span two bins. 85 86// The symbol type for a bin constraint. We use lists of ints as a tblgen hack 87// to conditionally generate defs within multiclasses based on record 88// information. A bin is nonempty (has a dummy one-element value) if enabled. 89class BinRequirementKind { 90 list<int> Bin0 = []; 91 list<int> Bin1 = []; 92 list<int> Bin2 = []; 93 list<int> Bin3 = []; 94 list<int> Bin4 = []; 95 list<int> Bin5 = []; 96} 97// Can use bins {0-3} 98def BRK_0_to_4 : BinRequirementKind { let Bin0 = [1]; let Bin1 = [1]; let Bin2 = [1]; let Bin3 = [1]; } 99// Can use bins {0-3} but only evens (0 and 2). 100def BRK_0_to_4_lo : BinRequirementKind { let Bin0 = [1]; let Bin2 = [1]; } 101// Can use bins {0-3} but only odds (1 and 3). 102def BRK_0_to_4_hi : BinRequirementKind { let Bin1 = [1]; let Bin3 = [1]; } 103// Can use bins {0-3} but only even-odd pairs (0+1 or 1+2). 104def BRK_0_to_4_dbl : BinRequirementKind { let Bin0 = [1]; let Bin2 = [1]; } 105def BRK_0_to_6 : BinRequirementKind { let Bin0 = [1]; let Bin1 = [1]; let Bin2 = [1]; 106 let Bin3 = [1]; let Bin4 = [1]; let Bin5 = [1]; } 107def BRK_0_to_6_lo : BinRequirementKind { let Bin0 = [1]; let Bin2 = [1]; let Bin4 = [1]; } 108def BRK_0_to_6_hi : BinRequirementKind { let Bin1 = [1]; let Bin3 = [1]; let Bin5 = [1]; } 109def BRK_0_to_6_dbl : BinRequirementKind { let Bin0 = [1]; let Bin2 = [1]; let Bin4 = [1]; } 110def BRK_2_to_6 : BinRequirementKind { let Bin2 = [1]; 111 let Bin3 = [1]; let Bin4 = [1]; let Bin5 = [1]; } 112def BRK_2_to_6_lo : BinRequirementKind { let Bin2 = [1]; let Bin4 = [1]; } 113def BRK_2_to_6_hi : BinRequirementKind { let Bin3 = [1]; let Bin5 = [1];} 114def BRK_2_to_6_dbl : BinRequirementKind { let Bin2 = [1]; let Bin4 = [1]; } 115def BRK_2_to_4 : BinRequirementKind { let Bin2 = [1]; let Bin3 = [1]; } 116def BRK_2_to_4_lo : BinRequirementKind { let Bin2 = [1]; } 117def BRK_2_to_4_hi : BinRequirementKind { let Bin3 = [1]; } 118def BRK_2_to_4_dbl : BinRequirementKind { let Bin2 = [1]; } 119 120def BinRequirementKindEnum : GenericEnum { 121 let FilterClass = "BinRequirementKind"; 122} 123 124// The transition class is trivial; it just contains the constraint symbol. 125class BinTransition : Transition { 126 BinRequirementKind Sym; 127} 128 129// Mixin that occupies a single bin. 130class Bin0 : BinTransition { let NewState{0} = 1; } 131class Bin1 : BinTransition { let NewState{1} = 1; } 132class Bin2 : BinTransition { let NewState{2} = 1;} 133class Bin3 : BinTransition { let NewState{3} = 1; } 134class Bin4 : BinTransition { let NewState{4} = 1;} 135class Bin5 : BinTransition { let NewState{5} = 1; } 136// Mixin that occupies a pair of bins (even-odd pairs). 137class Bin01 : BinTransition { let NewState{0,1} = 0b11; } 138class Bin23 : BinTransition { let NewState{2,3} = 0b11; } 139class Bin45 : BinTransition { let NewState{4,5} = 0b11; } 140 141// Instantiate all possible bin assignments for E. 142multiclass BinAssignments<BinRequirementKind E> { 143 let Sym = E in { 144 // Note the tablegen hack to conditionally instantiate a def based on E. 145 foreach x = E.Bin0 in { def : Bin0; } 146 foreach x = E.Bin1 in { def : Bin1; } 147 foreach x = E.Bin2 in { def : Bin2; } 148 foreach x = E.Bin3 in { def : Bin3; } 149 foreach x = E.Bin4 in { def : Bin4; } 150 foreach x = E.Bin5 in { def : Bin5; } 151 } 152} 153 154// Instantiate all possible bin assignments for E, which spans even-odd pairs. 155multiclass DblBinAssignments<BinRequirementKind E> { 156 let Sym = E in { 157 foreach x = E.Bin0 in { def : Bin01; } 158 foreach x = E.Bin2 in { def : Bin23; } 159 foreach x = E.Bin4 in { def : Bin45; } 160 } 161} 162 163defm : BinAssignments<BRK_0_to_4>; 164defm : DblBinAssignments<BRK_0_to_4_dbl>; 165defm : BinAssignments<BRK_0_to_4_lo>; 166defm : BinAssignments<BRK_0_to_4_hi>; 167defm : BinAssignments<BRK_0_to_6>; 168defm : DblBinAssignments<BRK_0_to_6_dbl>; 169defm : BinAssignments<BRK_0_to_6_lo>; 170defm : BinAssignments<BRK_0_to_6_hi>; 171defm : BinAssignments<BRK_2_to_6>; 172defm : DblBinAssignments<BRK_2_to_6_dbl>; 173defm : BinAssignments<BRK_2_to_6_lo>; 174defm : BinAssignments<BRK_2_to_6_hi>; 175defm : BinAssignments<BRK_2_to_4>; 176defm : DblBinAssignments<BRK_2_to_4_dbl>; 177defm : BinAssignments<BRK_2_to_4_lo>; 178defm : BinAssignments<BRK_2_to_4_hi>; 179 180def BinPackerAutomaton : GenericAutomaton { 181 let TransitionClass = "BinTransition"; 182 let SymbolFields = ["Sym"]; 183 string TypeOf_Sym = "BinRequirementKindEnum"; 184} 185 186 187