summaryrefslogtreecommitdiffstats
path: root/support/tools/TableGen/InstrSelectorEmitter.h
blob: dc16fb20f4709d02cca6fa150f3a1176d214ba8a (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
//===- InstrInfoEmitter.h - Generate a Instruction Set Desc. ----*- C++ -*-===//
//
// 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 "llvm/CodeGen/ValueTypes.h"
#include <vector>
#include <map>
class DagInit;
class Init;

struct NodeType {
  enum ArgResultTypes {
    // Both argument and return types...
    Val,            // A non-void type
    Arg0,           // Value matches the type of Arg0
    Ptr,            // Tree node is the type of the target pointer

    // Return types
    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);
};

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<TreePatternNode*> Children;

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

  Record *getOperator() const { return Operator; }
  MVT::ValueType getType() const { return Type; }
  void setType(MVT::ValueType T) { Type = T; }

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

  const std::vector<TreePatternNode*> &getChildren() const {
    assert(Operator != 0 && "This is a leaf node!");
    return Children;
  }
  Init *getValue() const {
    assert(Operator == 0 && "This is not a leaf node!");
    return Value;
  }

  void dump() const;
};

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



class InstrSelectorEmitter : public TableGenBackend {
  RecordKeeper &Records;

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

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

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

  // ParseTreePattern - Parse the specified DagInit into a TreePattern which we
  // can use.
  //
  TreePatternNode *ParseTreePattern(DagInit *DI, const std::string &RecName);

  // InferTypes - Perform type inference on the tree, returning true if there
  // are any remaining untyped nodes and setting MadeChange if any changes were
  // made.
  bool InferTypes(TreePatternNode *N, const std::string &RecName,
                  bool &MadeChange);

  // ReadAndCheckPattern - Parse the specified DagInit into a pattern and then
  // perform full type inference.
  TreePatternNode *ReadAndCheckPattern(DagInit *DI, const std::string &RecName);
};

#endif