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

#include "rcc/CodeGen/MachineFunctionProperties.h"

#include <array>
#include <string>

namespace rcc {
namespace {

constexpr std::array PropertyNames{
    std::string_view{"IsSSA"},
    std::string_view{"NoPHIs"},
    std::string_view{"TracksLiveness"},
    std::string_view{"Legalized"},
    std::string_view{"RegBankSelected"},
    std::string_view{"Selected"},
    std::string_view{"TiedOpsRewritten"},
    std::string_view{"NoVRegs"},
    std::string_view{"FrameFinalized"},
    std::string_view{"NoFrameIndices"},
    std::string_view{"NoExecutablePseudos"},
};

static_assert(PropertyNames.size() == static_cast<std::size_t>(MachineFunctionProperty::Count));

} // namespace

bool isKnownMachineFunctionProperty(MachineFunctionProperty Property) noexcept {
  return static_cast<std::size_t>(Property) < PropertyNames.size();
}

std::string_view getMachineFunctionPropertyName(MachineFunctionProperty Property) noexcept {
  const auto Index = static_cast<std::size_t>(Property);
  if (Index >= PropertyNames.size())
    return "Unknown";
  return PropertyNames[Index];
}

MachineFunctionProperties::MachineFunctionProperties(
    std::initializer_list<MachineFunctionProperty> Properties) noexcept {
  for (const MachineFunctionProperty Property : Properties)
    set(Property);
}

Expected<MachineFunctionProperties> MachineFunctionProperties::fromRaw(std::uint64_t RawValue) {
  if ((RawValue & ~ValidMask) != 0) {
    return makeUnexpected(ErrorCode::InvalidArgument,
                          "machine function property mask contains unknown bits");
  }
  return MachineFunctionProperties(RawValue);
}

Expected<void> MachineFunctionProperties::applyTransition(MachineFunctionProperties Required,
                                                          MachineFunctionProperties Sets,
                                                          MachineFunctionProperties Clears) {
  if (Sets.intersects(Clears)) {
    return makeUnexpected(ErrorCode::InvalidArgument,
                          "a machine function property transition cannot set and clear the "
                          "same property");
  }

  const MachineFunctionProperties Missing = Required.missingFrom(*this);
  if (!Missing.empty()) {
    return makeUnexpected(ErrorCode::VerificationError,
                          "missing required machine function properties: " + Missing.toString());
  }

  Mask = (Mask | Sets.Mask) & ~Clears.Mask;
  return {};
}

std::string MachineFunctionProperties::toString() const {
  if (empty())
    return "none";

  std::string Result;
  for (std::size_t Index = 0; Index < PropertyNames.size(); ++Index) {
    if ((Mask & (std::uint64_t{1} << Index)) == 0)
      continue;
    if (!Result.empty())
      Result += ", ";
    Result += PropertyNames[Index];
  }
  return Result;
}

} // namespace rcc