aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen/MachineCombinerPattern.cpp
blob: b1c3c96e91001a7fe55bf737fac719006a04f7ee (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
// SPDX-License-Identifier: GPL-3.0-or-later

#include "rcc/CodeGen/MachineCombinerPattern.h"

#include <cstddef>
#include <ranges>
#include <string>
#include <unordered_set>
#include <utility>

namespace rcc {

Expected<TargetMachineCombinerInfo>
TargetMachineCombinerInfo::create(std::vector<MachineCombinerPattern> Patterns) {
  TargetMachineCombinerInfo Result(std::move(Patterns));
  std::unordered_set<std::string> Names;
  for (const MachineCombinerPattern &Pattern : Result.Patterns) {
    if (Pattern.Name.empty() || !Pattern.RootOpcode.isValid() || Pattern.Stages == 0 ||
        !Names.insert(Pattern.Name).second) {
      return makeUnexpected(ErrorCode::InvalidArgument,
                            "machine combiner pattern has an invalid identity or stage mask");
    }
    for (const MachineCombinerPredicate &Predicate : Pattern.Predicates) {
      switch (Predicate.Kind) {
      case MachineCombinerPredicateKind::ImmediateEquals:
      case MachineCombinerPredicateKind::PhysicalRegisterEquals:
      case MachineCombinerPredicateKind::RegisterIsVirtual:
      case MachineCombinerPredicateKind::RegisterIsPhysical:
        break;
      case MachineCombinerPredicateKind::RegisterEquals:
        if (Predicate.Operand == Predicate.OtherOperand) {
          return makeUnexpected(ErrorCode::InvalidArgument,
                                "register equality pattern compares an operand with itself");
        }
        break;
      }
    }
    Result.MatchTable[Pattern.RootOpcode].push_back(Pattern);
  }
  return Result;
}

std::span<const MachineCombinerPattern>
TargetMachineCombinerInfo::patterns(Opcode RootOpcode) const noexcept {
  const auto Position = MatchTable.find(RootOpcode);
  return Position == MatchTable.end() ? std::span<const MachineCombinerPattern>{}
                                      : std::span<const MachineCombinerPattern>(Position->second);
}

} // namespace rcc