SetTheory.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- SetTheory.h - Generate ordered sets from DAG expressions -*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file implements the SetTheory class that computes ordered sets of
  15. // Records from DAG expressions. Operators for standard set operations are
  16. // predefined, and it is possible to add special purpose set operators as well.
  17. //
  18. // The user may define named sets as Records of predefined classes. Set
  19. // expanders can be added to a SetTheory instance to teach it how to find the
  20. // elements of such a named set.
  21. //
  22. // These are the predefined operators. The argument lists can be individual
  23. // elements (defs), other sets (defs of expandable classes), lists, or DAG
  24. // expressions that are evaluated recursively.
  25. //
  26. // - (add S1, S2 ...) Union sets. This is also how sets are created from element
  27. // lists.
  28. //
  29. // - (sub S1, S2, ...) Set difference. Every element in S1 except for the
  30. // elements in S2, ...
  31. //
  32. // - (and S1, S2) Set intersection. Every element in S1 that is also in S2.
  33. //
  34. // - (shl S, N) Shift left. Remove the first N elements from S.
  35. //
  36. // - (trunc S, N) Truncate. The first N elements of S.
  37. //
  38. // - (rotl S, N) Rotate left. Same as (add (shl S, N), (trunc S, N)).
  39. //
  40. // - (rotr S, N) Rotate right.
  41. //
  42. // - (decimate S, N) Decimate S by picking every N'th element, starting with
  43. // the first one. For instance, (decimate S, 2) returns the even elements of
  44. // S.
  45. //
  46. // - (sequence "Format", From, To, [Stride]) Generate a sequence of defs with
  47. // printf. For instance, (sequence "R%u", 0, 3) -> [ R0, R1, R2, R3 ] and
  48. // (sequence "R%u", 20, 30, 5) -> [ R20, R25, R30 ].
  49. //
  50. //===----------------------------------------------------------------------===//
  51. #ifndef LLVM_TABLEGEN_SETTHEORY_H
  52. #define LLVM_TABLEGEN_SETTHEORY_H
  53. #include "llvm/ADT/ArrayRef.h"
  54. #include "llvm/ADT/SetVector.h"
  55. #include "llvm/ADT/StringMap.h"
  56. #include "llvm/ADT/StringRef.h"
  57. #include "llvm/Support/SMLoc.h"
  58. #include <map>
  59. #include <memory>
  60. #include <vector>
  61. namespace llvm {
  62. class DagInit;
  63. class Init;
  64. class Record;
  65. class SetTheory {
  66. public:
  67. using RecVec = std::vector<Record *>;
  68. using RecSet = SmallSetVector<Record *, 16>;
  69. /// Operator - A callback representing a DAG operator.
  70. class Operator {
  71. virtual void anchor();
  72. public:
  73. virtual ~Operator() = default;
  74. /// apply - Apply this operator to Expr's arguments and insert the result
  75. /// in Elts.
  76. virtual void apply(SetTheory&, DagInit *Expr, RecSet &Elts,
  77. ArrayRef<SMLoc> Loc) = 0;
  78. };
  79. /// Expander - A callback function that can transform a Record representing a
  80. /// set into a fully expanded list of elements. Expanders provide a way for
  81. /// users to define named sets that can be used in DAG expressions.
  82. class Expander {
  83. virtual void anchor();
  84. public:
  85. virtual ~Expander() = default;
  86. virtual void expand(SetTheory&, Record*, RecSet &Elts) = 0;
  87. };
  88. private:
  89. // Map set defs to their fully expanded contents. This serves as a memoization
  90. // cache and it makes it possible to return const references on queries.
  91. using ExpandMap = std::map<Record *, RecVec>;
  92. ExpandMap Expansions;
  93. // Known DAG operators by name.
  94. StringMap<std::unique_ptr<Operator>> Operators;
  95. // Typed expanders by class name.
  96. StringMap<std::unique_ptr<Expander>> Expanders;
  97. public:
  98. /// Create a SetTheory instance with only the standard operators.
  99. SetTheory();
  100. /// addExpander - Add an expander for Records with the named super class.
  101. void addExpander(StringRef ClassName, std::unique_ptr<Expander>);
  102. /// addFieldExpander - Add an expander for ClassName that simply evaluates
  103. /// FieldName in the Record to get the set elements. That is all that is
  104. /// needed for a class like:
  105. ///
  106. /// class Set<dag d> {
  107. /// dag Elts = d;
  108. /// }
  109. ///
  110. void addFieldExpander(StringRef ClassName, StringRef FieldName);
  111. /// addOperator - Add a DAG operator.
  112. void addOperator(StringRef Name, std::unique_ptr<Operator>);
  113. /// evaluate - Evaluate Expr and append the resulting set to Elts.
  114. void evaluate(Init *Expr, RecSet &Elts, ArrayRef<SMLoc> Loc);
  115. /// evaluate - Evaluate a sequence of Inits and append to Elts.
  116. template<typename Iter>
  117. void evaluate(Iter begin, Iter end, RecSet &Elts, ArrayRef<SMLoc> Loc) {
  118. while (begin != end)
  119. evaluate(*begin++, Elts, Loc);
  120. }
  121. /// expand - Expand a record into a set of elements if possible. Return a
  122. /// pointer to the expanded elements, or NULL if Set cannot be expanded
  123. /// further.
  124. const RecVec *expand(Record *Set);
  125. };
  126. } // end namespace llvm
  127. #endif // LLVM_TABLEGEN_SETTHEORY_H
  128. #ifdef __GNUC__
  129. #pragma GCC diagnostic pop
  130. #endif