summaryrefslogtreecommitdiff
path: root/utils/TableGen/InstrSelectorEmitter.h
blob: 302a98adc3c683e5dd3fd5ba1ad681d5166d7f2c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
//===- InstrInfoEmitter.h - Generate a Instruction Set Desc. ----*- C++ -*-===//
// 
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This tablegen backend is responsible for emitting a description of the target
// instruction set for the code generator.
//
//===----------------------------------------------------------------------===//

#ifndef INSTRSELECTOR_EMITTER_H
#define INSTRSELECTOR_EMITTER_H

#include "TableGenBackend.h"
#include "CodeGenTarget.h"
#include <vector>
#include <map>
#include <cassert>

namespace llvm {

class DagInit;
struct Init;
class InstrSelectorEmitter;

/// NodeType - Represents Information parsed from the DagNode entries.
///
struct NodeType {
  enum ArgResultTypes {
    Any,            // No constraint on type
    Val,            // A non-void type
    Arg0,           // Value matches the type of Arg0
    Arg1,           // Value matches the type of Arg1
    Ptr,            // Tree node is the type of the target pointer
    I8,             // Always bool
    Void,           // Tree node always returns void
  };

  ArgResultTypes ResultType;
  std::vector<ArgResultTypes> ArgTypes;

  NodeType(ArgResultTypes RT, std::vector<ArgResultTypes> &AT) : ResultType(RT){
    AT.swap(ArgTypes);
  }

  NodeType() : ResultType(Val) {}
  NodeType(const NodeType &N) : ResultType(N.ResultType), ArgTypes(N.ArgTypes){}

  static ArgResultTypes Translate(Record *R);
};



/// TreePatternNode - Represent a node of the tree patterns.
///
class TreePatternNode {
  /// Operator - The operation that this node represents... this is null if this
  /// is a leaf.
  Record *Operator;

  /// Type - The inferred value type...
  ///
  MVT::ValueType                Type;

  /// Children - If this is not a leaf (Operator != 0), this is the subtrees
  /// that we contain.
  std::vector<std::pair<TreePatternNode*, std::string> > Children;

  /// Value - If this node is a leaf, this indicates what the thing is.
  ///
  Init *Value;
public:
  TreePatternNode(Record *o, const std::vector<std::pair<TreePatternNode*,
                                                         std::string> > &c)
    : Operator(o), Type(MVT::Other), Children(c), Value(0) {}
  TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {}

  Record *getOperator() const {
    assert(Operator && "This is a leaf node!");
    return Operator;
  }
  MVT::ValueType getType() const { return Type; }
  void setType(MVT::ValueType T) { Type = T; }

  bool isLeaf() const { return Operator == 0; }

  unsigned getNumChildren() const { return Children.size(); }
  TreePatternNode *getChild(unsigned c) const {
    assert(Operator != 0 && "This is a leaf node!");
    assert(c < Children.size() && "Child access out of range!");
    return Children[c].first;
  }
  const std::string &getChildName(unsigned c) const {
    assert(Operator != 0 && "This is a leaf node!");
    assert(c < Children.size() && "Child access out of range!");
    return Children[c].second;
  }

  Init *getValue() const {
    assert(Operator == 0 && "This is not a leaf node!");
    return Value;
  }

  /// getValueRecord - Returns the value of this tree node as a record.  For now
  /// we only allow DefInit's as our leaf values, so this is used.
  Record *getValueRecord() const;

  /// clone - Make a copy of this tree and all of its children.
  ///
  TreePatternNode *clone() const;

  void dump() const;

  /// InstantiateNonterminals - If this pattern refers to any nonterminals which
  /// are not themselves completely resolved, clone the nonterminal and resolve
  /// it with the using context we provide.
  void InstantiateNonterminals(InstrSelectorEmitter &ISE);

  /// UpdateNodeType - Set the node type of N to VT if VT contains information.
  /// If N already contains a conflicting type, then throw an exception.  This
  /// returns true if any information was updated.
  ///
  bool updateNodeType(MVT::ValueType VT, const std::string &RecName);
};

std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N);



/// Pattern - Represent a pattern of one form or another.  Currently, three
/// types of patterns are possible: Instruction's, Nonterminals, and Expanders.
///
struct Pattern {
  enum PatternType {
    Nonterminal, Instruction, Expander
  };
private:
  /// PTy - The type of pattern this is.
  ///
  PatternType PTy;

  /// Tree - The tree pattern which corresponds to this pattern.  Note that if
  /// there was a (set) node on the outside level that it has been stripped off.
  ///
  TreePatternNode *Tree;
  
  /// Result - If this is an instruction or expander pattern, this is the
  /// register result, specified with a (set) in the pattern.
  ///
  std::string ResultName;      // The name of the result value...
  TreePatternNode *ResultNode; // The leaf node for the result register...

  /// TheRecord - The actual TableGen record corresponding to this pattern.
  ///
  Record *TheRecord;

  /// Resolved - This is true of the pattern is useful in practice.  In
  /// particular, some non-terminals will have non-resolvable types.  When a
  /// user of the non-terminal is later found, they will have inferred a type
  /// for the result of the non-terminal, which cause a clone of an unresolved
  /// nonterminal to be made which is "resolved".
  ///
  bool Resolved;

  /// Args - This is a list of all of the arguments to this pattern, which are
  /// the non-void leaf nodes in this pattern.
  std::vector<std::pair<TreePatternNode*, std::string> > Args;

  /// ISE - the instruction selector emitter coordinating this madness.
  ///
  InstrSelectorEmitter &ISE;
public:

  /// Pattern constructor - Parse the specified DagInitializer into the current
  /// record.
  Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
          InstrSelectorEmitter &ise);

  /// Pattern - Constructor used for cloning nonterminal patterns
  Pattern(TreePatternNode *tree, Record *rec, bool res,
          InstrSelectorEmitter &ise)
    : PTy(Nonterminal), Tree(tree), ResultNode(0), TheRecord(rec),
      Resolved(res), ISE(ise) {
    calculateArgs(Tree, "");
  }

  /// getPatternType - Return what flavor of Record this pattern originated from
  ///
  PatternType getPatternType() const { return PTy; }

  /// getTree - Return the tree pattern which corresponds to this pattern.
  ///
  TreePatternNode *getTree() const { return Tree; }
  
  Record *getResult() const {
    return ResultNode ? ResultNode->getValueRecord() : 0;
  }
  const std::string &getResultName() const { return ResultName; }
  TreePatternNode *getResultNode() const { return ResultNode; }

  /// getRecord - Return the actual TableGen record corresponding to this
  /// pattern.
  ///
  Record *getRecord() const { return TheRecord; }

  unsigned getNumArgs() const { return Args.size(); }
  TreePatternNode *getArg(unsigned i) const {
    assert(i < Args.size() && "Argument reference out of range!");
    return Args[i].first;
  }
  Record *getArgRec(unsigned i) const {
    return getArg(i)->getValueRecord();
  }
  Init *getArgVal(unsigned i) const {
    return getArg(i)->getValue();
  }
  const std::string &getArgName(unsigned i) const {
    assert(i < Args.size() && "Argument reference out of range!");
    return Args[i].second;
  }

  bool isResolved() const { return Resolved; }

  /// InferAllTypes - Runs the type inference engine on the current pattern,
  /// stopping when nothing can be inferred, then updating the Resolved field.
  void InferAllTypes();

  /// InstantiateNonterminals - If this pattern refers to any nonterminals which
  /// are not themselves completely resolved, clone the nonterminal and resolve
  /// it with the using context we provide.
  void InstantiateNonterminals() {
    Tree->InstantiateNonterminals(ISE);
  }

  /// clone - This method is used to make an exact copy of the current pattern,
  /// then change the "TheRecord" instance variable to the specified record.
  ///
  Pattern *clone(Record *R) const;

  /// error - Throw an exception, prefixing it with information about this
  /// pattern.
  void error(const std::string &Msg) const;

  /// getSlotName - If this is a leaf node, return the slot name that the
  /// operand will update.
  std::string getSlotName() const;
  static std::string getSlotName(Record *R);

  void dump() const;

private:
  void calculateArgs(TreePatternNode *N, const std::string &Name);
  MVT::ValueType getIntrinsicType(Record *R) const;
  TreePatternNode *ParseTreePattern(DagInit *DI);
  bool InferTypes(TreePatternNode *N, bool &MadeChange);
};

std::ostream &operator<<(std::ostream &OS, const Pattern &P);


/// PatternOrganizer - This class represents all of the patterns which are
/// useful for the instruction selector, neatly catagorized in a hierarchical
/// structure.
struct PatternOrganizer {
  /// PatternsForNode - The list of patterns which can produce a value of a
  /// particular slot type, given a particular root node in the tree.  All of
  /// the patterns in this vector produce the same value type and have the same
  /// root DAG node.
  typedef std::vector<Pattern*> PatternsForNode;

  /// NodesForSlot - This map keeps track of all of the root DAG nodes which can
  /// lead to the production of a value for this slot.  All of the patterns in
  /// this data structure produces values of the same slot.
  typedef std::map<Record*, PatternsForNode> NodesForSlot;

  /// AllPatterns - This data structure contains all patterns in the instruction
  /// selector.
  std::map<std::string, NodesForSlot> AllPatterns;

  // Forwarding functions...
  typedef std::map<std::string, NodesForSlot>::iterator iterator;
  iterator begin() { return AllPatterns.begin(); }
  iterator end()   { return AllPatterns.end(); }


  /// addPattern - Add the specified pattern to the appropriate location in the
  /// collection.
  void addPattern(Pattern *P);
};


/// InstrSelectorEmitter - The top-level class which coordinates construction
/// and emission of the instruction selector.
///
class InstrSelectorEmitter : public TableGenBackend {
  RecordKeeper &Records;
  CodeGenTarget Target;

  std::map<Record*, NodeType> NodeTypes;

  /// Patterns - a list of all of the patterns defined by the target description
  ///
  std::map<Record*, Pattern*> Patterns;

  /// InstantiatedNTs - A data structure to keep track of which nonterminals
  /// have been instantiated already...
  ///
  std::map<std::pair<Pattern*,MVT::ValueType>, Record*> InstantiatedNTs;

  /// ComputableValues - This map indicates which patterns can be used to
  /// generate a value that is used by the selector.  The keys of this map
  /// implicitly define the values that are used by the selector.
  ///
  PatternOrganizer ComputableValues;

public:
  InstrSelectorEmitter(RecordKeeper &R) : Records(R) {}
  
  // run - Output the instruction set description, returning true on failure.
  void run(std::ostream &OS);

  const CodeGenTarget &getTarget() const { return Target; }
  std::map<Record*, NodeType> &getNodeTypes() { return NodeTypes; }
  const NodeType &getNodeType(Record *R) const {
    std::map<Record*, NodeType>::const_iterator I = NodeTypes.find(R);
    assert(I != NodeTypes.end() && "Unknown node type!");
    return I->second;
  }

  /// getPattern - return the pattern corresponding to the specified record, or
  /// null if there is none.
  Pattern *getPattern(Record *R) const {
    std::map<Record*, Pattern*>::const_iterator I = Patterns.find(R);
    return I != Patterns.end() ? I->second : 0;
  }

  /// ReadNonterminal - This method parses the specified record as a
  /// nonterminal, but only if it hasn't been read in already.
  Pattern *ReadNonterminal(Record *R);

  /// InstantiateNonterminal - This method takes the nonterminal specified by
  /// NT, which should not be completely resolved, clones it, applies ResultTy
  /// to its root, then runs the type inference stuff on it.  This should
  /// produce a newly resolved nonterminal, which we make a record for and
  /// return.  To be extra fancy and efficient, this only makes one clone for
  /// each type it is instantiated with.
  Record *InstantiateNonterminal(Pattern *NT, MVT::ValueType ResultTy);

private:
  // ReadNodeTypes - Read in all of the node types in the current RecordKeeper,
  // turning them into the more accessible NodeTypes data structure.
  void ReadNodeTypes();

  // ReadNonTerminals - Read in all nonterminals and incorporate them into our
  // pattern database.
  void ReadNonterminals();

  // ReadInstructionPatterns - Read in all subclasses of Instruction, and
  // process those with a useful Pattern field.
  void ReadInstructionPatterns();

  // ReadExpanderPatterns - Read in all of the expanded patterns.
  void ReadExpanderPatterns();

  // InstantiateNonterminals - Instantiate any unresolved nonterminals with
  // information from the context that they are used in.
  void InstantiateNonterminals();
  
  // CalculateComputableValues - Fill in the ComputableValues map through
  // analysis of the patterns we are playing with.
  void CalculateComputableValues();

  // EmitMatchCosters - Given a list of patterns, which all have the same root
  // pattern operator, emit an efficient decision tree to decide which one to
  // pick.  This is structured this way to avoid reevaluations of non-obvious
  // subexpressions.
  void EmitMatchCosters(std::ostream &OS,
            const std::vector<std::pair<Pattern*, TreePatternNode*> > &Patterns,
                        const std::string &VarPrefix, unsigned Indent);
  
  /// PrintExpanderOperand - Print out Arg as part of the instruction emission
  /// process for the expander pattern P.  This argument may be referencing some
  /// values defined in P, or may just be physical register references or
  /// something like that.  If PrintArg is true, we are printing out arguments
  /// to the BuildMI call.  If it is false, we are printing the result register
  /// name.
  void PrintExpanderOperand(Init *Arg, const std::string &NameVar,
                            TreePatternNode *ArgDecl, Pattern *P,
                            bool PrintArg, std::ostream &OS);
};

} // End llvm namespace

#endif