aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/CodeGen/MachineCompilationStatus.h
blob: f88957429a2e6fe4c555377c22a875354b7c911f (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
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef RCC_CODEGEN_MACHINECOMPILATIONSTATUS_H
#define RCC_CODEGEN_MACHINECOMPILATIONSTATUS_H

#include "rcc/CodeGen/InstructionDescriptor.h"
#include "rcc/CodeGen/MachineIRTypes.h"
#include "rcc/CodeGen/StableID.h"
#include "rcc/Support/Error.h"

#include <cstdint>
#include <optional>
#include <string>
#include <string_view>

namespace rcc {

class MachineFunctionCloneContext;

enum class MachineCompilationState : std::uint8_t {
  Success,
  Unsupported,
  MIRParseFailed,
  LegalizationFailed,
  SelectionFailed,
  RegisterAllocationFailed,
  CallLoweringFailed,
  FrameLayoutFailed,
  FinalizationFailed,
  AssemblyLoweringFailed,
  InternalError,
  Count,
};

[[nodiscard]] bool isKnownMachineCompilationState(MachineCompilationState State) noexcept;
[[nodiscard]] std::string_view
getMachineCompilationStateName(MachineCompilationState State) noexcept;

enum class MachineCompilationDiagnosticSeverity : std::uint8_t {
  Error,
  Fatal,
  Count,
};

struct MachineCompilationDiagnostic final {
  MachineCompilationDiagnosticSeverity Severity = MachineCompilationDiagnosticSeverity::Error;
  ErrorCode Code = ErrorCode::InternalError;
  std::string Message;
  std::optional<SourceLocation> Location;

  friend bool operator==(const MachineCompilationDiagnostic &Left,
                         const MachineCompilationDiagnostic &Right) = default;
};

struct MachineCompilationFailure final {
  MachineCompilationDiagnostic Diagnostic;
  std::optional<std::string> FailurePass;
  std::optional<MachineInstrStableID> FailureInstruction;
  std::optional<PipelineStage> FailureStage;
  std::optional<std::string> FailureRule;
  std::optional<std::string> Target;
  std::optional<std::string> Subtarget;

  friend bool operator==(const MachineCompilationFailure &Left,
                         const MachineCompilationFailure &Right) = default;
};

class MachineCompilationStatus final {
public:
  MachineCompilationStatus() = default;
  MachineCompilationStatus(const MachineCompilationStatus &) = delete;
  MachineCompilationStatus &operator=(const MachineCompilationStatus &) = delete;
  MachineCompilationStatus(MachineCompilationStatus &&) noexcept = default;
  MachineCompilationStatus &operator=(MachineCompilationStatus &&) noexcept = default;
  ~MachineCompilationStatus() = default;

  [[nodiscard]] MachineCompilationState state() const noexcept {
    return State;
  }

  [[nodiscard]] bool succeeded() const noexcept {
    return State == MachineCompilationState::Success;
  }

  [[nodiscard]] const MachineCompilationFailure *failure() const noexcept {
    if (!Failure)
      return nullptr;
    return &*Failure;
  }

  [[nodiscard]] Expected<void> fail(MachineCompilationState NewState,
                                    MachineCompilationFailure NewFailure);
  [[nodiscard]] Expected<void> verify() const;
  [[nodiscard]] Expected<MachineCompilationStatus>
  clone(const MachineFunctionCloneContext &CloneContext) const;

  friend bool operator==(const MachineCompilationStatus &Left,
                         const MachineCompilationStatus &Right) = default;

private:
  MachineCompilationState State = MachineCompilationState::Success;
  std::optional<MachineCompilationFailure> Failure;
};

} // namespace rcc

#endif // RCC_CODEGEN_MACHINECOMPILATIONSTATUS_H