aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/CodeGen/TargetCodeGen.h
blob: 34a6de49c6ac751e07f93ee49504f243ab5b86be (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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef RCC_CODEGEN_TARGETCODEGEN_H
#define RCC_CODEGEN_TARGETCODEGEN_H

#include "rcc/CodeGen/MachineIRTypes.h"
#include "rcc/CodeGen/Register.h"
#include "rcc/Support/Error.h"

#include <cstddef>
#include <cstdint>
#include <optional>

namespace rcc {

class MachineFunction;
class MachineBasicBlock;
class MachineInstr;
class MachineRegisterInfo;
class TargetDescription;
struct VirtualRegisterInfo;

enum class LegalizationAction : std::uint8_t {
  Legal,
  Unsupported,
  Custom,
  Lower,
  Libcall,
  WidenScalar,
  NarrowScalar,
  MoreElements,
  FewerElements,
  Bitcast,
  ChangeElementType,
  ChangeAddressSpace,
};

class TargetLegalizerInfo {
public:
  virtual ~TargetLegalizerInfo() = default;

  [[nodiscard]] virtual Expected<LegalizationAction>
  classify(const MachineInstr &Instruction, const MachineFunction &Function,
           const TargetDescription &Target) const = 0;

  [[nodiscard]] virtual Expected<void> lower(MachineInstr &Instruction, MachineFunction &Function,
                                             const TargetDescription &Target,
                                             LegalizationAction Action) const = 0;

  // This hook performs read-only target checks before a lowering mutation is committed.
  [[nodiscard]] virtual Expected<void> validateLowering(const MachineInstr &,
                                                        const MachineFunction &,
                                                        const TargetDescription &,
                                                        LegalizationAction) const {
    return {};
  }
};

class TargetRegisterBankInfo {
public:
  virtual ~TargetRegisterBankInfo() = default;

  [[nodiscard]] virtual Expected<RegisterBankID>
  selectBank(const MachineFunction &Function, Register Reg, const VirtualRegisterInfo &Info,
             const MachineInstr *Context, const TargetDescription &Target) const = 0;

  [[nodiscard]] virtual Expected<void>
  constrainInstruction(MachineInstr &Instruction, MachineFunction &Function,
                       const TargetDescription &Target) const = 0;

  // This hook must not mutate MachineIR. It allows the pass to reject a bad mapping
  // before publishing any bank or class assignment.
  [[nodiscard]] virtual Expected<void> validateInstruction(const MachineInstr &,
                                                           const MachineFunction &,
                                                           const TargetDescription &) const {
    return {};
  }
};

class TargetInstructionSelector {
public:
  virtual ~TargetInstructionSelector() = default;

  [[nodiscard]] virtual Expected<void> select(MachineInstr &Instruction, MachineFunction &Function,
                                              const TargetDescription &Target) const = 0;

  // Selection matching is read-only and must complete before select() mutates MachineIR.
  [[nodiscard]] virtual Expected<void> canSelect(const MachineInstr &, const MachineFunction &,
                                                 const TargetDescription &) const {
    return {};
  }

  [[nodiscard]] virtual Expected<void>
  constrainSelectedInstruction(MachineInstr &, MachineFunction &, const TargetDescription &) const {
    return {};
  }
};

class TargetSSAInfo {
public:
  virtual ~TargetSSAInfo() = default;

  [[nodiscard]] virtual Expected<bool> isFallthroughEdge(const MachineBasicBlock &From,
                                                         const MachineBasicBlock &To,
                                                         const MachineFunction &Function,
                                                         const TargetDescription &Target) const = 0;

  [[nodiscard]] virtual Expected<bool>
  rewriteBranchTarget(MachineBasicBlock &Block, MachineBasicBlock &OldTarget,
                      MachineBasicBlock &NewTarget, MachineFunction &Function,
                      const TargetDescription &Target) const = 0;

  [[nodiscard]] virtual Expected<void>
  insertUnconditionalBranch(MachineBasicBlock &Block, MachineBasicBlock &Target,
                            MachineFunction &Function,
                            const TargetDescription &TargetDescription) const = 0;

  [[nodiscard]] virtual Expected<void> validateCopy(Register Destination,
                                                    SubRegIndex DestinationSubReg, Register Source,
                                                    SubRegIndex SourceSubReg,
                                                    const MachineFunction &Function,
                                                    const TargetDescription &Target) const = 0;

  [[nodiscard]] virtual Expected<bool> tryConvertToThreeAddress(MachineInstr &, std::size_t,
                                                                std::size_t, MachineFunction &,
                                                                const TargetDescription &) const {
    return false;
  }
};

} // namespace rcc

#endif // RCC_CODEGEN_TARGETCODEGEN_H