SetTheory.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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) Generate a sequence of defs with printf.
  47. // For instance, (sequence "R%u", 0, 3) -> [ R0, R1, R2, R3 ]
  48. //
  49. //===----------------------------------------------------------------------===//
  50. #ifndef LLVM_TABLEGEN_SETTHEORY_H
  51. #define LLVM_TABLEGEN_SETTHEORY_H
  52. #include "llvm/ADT/ArrayRef.h"
  53. #include "llvm/ADT/SetVector.h"
  54. #include "llvm/ADT/StringMap.h"
  55. #include "llvm/ADT/StringRef.h"
  56. #include "llvm/Support/SMLoc.h"
  57. #include <map>
  58. #include <memory>
  59. #include <vector>
  60. namespace llvm {
  61. class DagInit;
  62. class Init;
  63. class Record;
  64. class SetTheory {
  65. public:
  66. using RecVec = std::vector<Record *>;
  67. using RecSet = SmallSetVector<Record *, 16>;
  68. /// Operator - A callback representing a DAG operator.
  69. class Operator {
  70. virtual void anchor();
  71. public:
  72. virtual ~Operator() = default;
  73. /// apply - Apply this operator to Expr's arguments and insert the result
  74. /// in Elts.
  75. virtual void apply(SetTheory&, DagInit *Expr, RecSet &Elts,
  76. ArrayRef<SMLoc> Loc) = 0;
  77. };
  78. /// Expander - A callback function that can transform a Record representing a
  79. /// set into a fully expanded list of elements. Expanders provide a way for
  80. /// users to define named sets that can be used in DAG expressions.
  81. class Expander {
  82. virtual void anchor();
  83. public:
  84. virtual ~Expander() = default;
  85. virtual void expand(SetTheory&, Record*, RecSet &Elts) = 0;
  86. };
  87. private:
  88. // Map set defs to their fully expanded contents. This serves as a memoization
  89. // cache and it makes it possible to return const references on queries.
  90. using ExpandMap = std::map<Record *, RecVec>;
  91. ExpandMap Expansions;
  92. // Known DAG operators by name.
  93. StringMap<std::unique_ptr<Operator>> Operators;
  94. // Typed expanders by class name.
  95. StringMap<std::unique_ptr<Expander>> Expanders;
  96. public:
  97. /// Create a SetTheory instance with only the standard operators.
  98. SetTheory();
  99. /// addExpander - Add an expander for Records with the named super class.
  100. void addExpander(StringRef ClassName, std::unique_ptr<Expander>);
  101. /// addFieldExpander - Add an expander for ClassName that simply evaluates
  102. /// FieldName in the Record to get the set elements. That is all that is
  103. /// needed for a class like:
  104. ///
  105. /// class Set<dag d> {
  106. /// dag Elts = d;
  107. /// }
  108. ///
  109. void addFieldExpander(StringRef ClassName, StringRef FieldName);
  110. /// addOperator - Add a DAG operator.
  111. void addOperator(StringRef Name, std::unique_ptr<Operator>);
  112. /// evaluate - Evaluate Expr and append the resulting set to Elts.
  113. void evaluate(Init *Expr, RecSet &Elts, ArrayRef<SMLoc> Loc);
  114. /// evaluate - Evaluate a sequence of Inits and append to Elts.
  115. template<typename Iter>
  116. void evaluate(Iter begin, Iter end, RecSet &Elts, ArrayRef<SMLoc> Loc) {
  117. while (begin != end)
  118. evaluate(*begin++, Elts, Loc);
  119. }
  120. /// expand - Expand a record into a set of elements if possible. Return a
  121. /// pointer to the expanded elements, or NULL if Set cannot be expanded
  122. /// further.
  123. const RecVec *expand(Record *Set);
  124. };
  125. } // end namespace llvm
  126. #endif // LLVM_TABLEGEN_SETTHEORY_H
  127. #ifdef __GNUC__
  128. #pragma GCC diagnostic pop
  129. #endif