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
|
// SPDX-License-Identifier: GPL-3.0-or-later
#include "RISCV.h"
#include "rcc/Target/RISCV/RISCVTarget.h"
#include <cstdint>
#include <cstdlib>
#include <string>
#include <utility>
#include <vector>
namespace rcc::riscv {
namespace {
[[nodiscard]] constexpr Opcode targetOpcode(InstructionOpcode Value) noexcept {
return Opcode::fromValue(static_cast<std::uint32_t>(Value));
}
[[nodiscard]] constexpr MachineCombinerStageMask allOptimizationStages() noexcept {
return machineCombinerStageMask(MachineCombinerStage::SelectedSSA) |
machineCombinerStageMask(MachineCombinerStage::PreRegisterAllocation) |
machineCombinerStageMask(MachineCombinerStage::PostRegisterAllocation) |
machineCombinerStageMask(MachineCombinerStage::PostFrame);
}
[[nodiscard]] MachineCombinerPattern immediateIdentity(InstructionOpcode OpcodeValue,
std::string Name, std::int64_t Immediate) {
return {
.Name = std::move(Name),
.RootOpcode = targetOpcode(OpcodeValue),
.Stages = allOptimizationStages(),
.Predicates = {{MachineCombinerPredicateKind::ImmediateEquals, 2, 0, Immediate}},
.Action = {MachineCombinerActionKind::ReplaceDefWithOperandAndErase, 0, 1},
};
}
[[nodiscard]] MachineCombinerPattern zeroRegisterIdentity(InstructionOpcode OpcodeValue,
std::string Name, std::size_t ZeroOperand,
std::size_t SourceOperand) {
return {
.Name = std::move(Name),
.RootOpcode = targetOpcode(OpcodeValue),
.Stages = allOptimizationStages(),
.Predicates = {{MachineCombinerPredicateKind::PhysicalRegisterEquals, ZeroOperand, 0,
static_cast<std::int64_t>(PhysicalRegisterID::X0)}},
.Action = {MachineCombinerActionKind::ReplaceDefWithOperandAndErase, 0, SourceOperand},
};
}
[[nodiscard]] MachineCombinerPattern equalSourceIdentity(InstructionOpcode OpcodeValue,
std::string Name) {
return {
.Name = std::move(Name),
.RootOpcode = targetOpcode(OpcodeValue),
.Stages = allOptimizationStages(),
.Predicates = {{MachineCombinerPredicateKind::RegisterEquals, 1, 2, 0}},
.Action = {MachineCombinerActionKind::ReplaceDefWithOperandAndErase, 0, 1},
};
}
[[nodiscard]] std::vector<MachineCombinerPattern> createPatterns() {
std::vector<MachineCombinerPattern> Patterns;
Patterns.push_back(immediateIdentity(InstructionOpcode::ADDI, "addi-zero", 0));
Patterns.push_back(immediateIdentity(InstructionOpcode::XORI, "xori-zero", 0));
Patterns.push_back(immediateIdentity(InstructionOpcode::ORI, "ori-zero", 0));
Patterns.push_back(immediateIdentity(InstructionOpcode::ANDI, "andi-all-ones", -1));
Patterns.push_back(immediateIdentity(InstructionOpcode::SLLI, "slli-zero", 0));
Patterns.push_back(immediateIdentity(InstructionOpcode::SRLI, "srli-zero", 0));
Patterns.push_back(immediateIdentity(InstructionOpcode::SRAI, "srai-zero", 0));
Patterns.push_back(zeroRegisterIdentity(InstructionOpcode::ADD, "add-zero-right", 2, 1));
Patterns.push_back(zeroRegisterIdentity(InstructionOpcode::ADD, "add-zero-left", 1, 2));
Patterns.push_back(zeroRegisterIdentity(InstructionOpcode::OR, "or-zero-right", 2, 1));
Patterns.push_back(zeroRegisterIdentity(InstructionOpcode::OR, "or-zero-left", 1, 2));
Patterns.push_back(zeroRegisterIdentity(InstructionOpcode::XOR, "xor-zero-right", 2, 1));
Patterns.push_back(zeroRegisterIdentity(InstructionOpcode::XOR, "xor-zero-left", 1, 2));
Patterns.push_back(zeroRegisterIdentity(InstructionOpcode::SUB, "sub-zero-right", 2, 1));
Patterns.push_back(equalSourceIdentity(InstructionOpcode::FSGNJ_S, "fsgnj-s-copy"));
Patterns.push_back(equalSourceIdentity(InstructionOpcode::FSGNJ_D, "fsgnj-d-copy"));
return Patterns;
}
} // namespace
const TargetMachineCombinerInfo &machineCombinerInfo() noexcept {
static const Expected<TargetMachineCombinerInfo> Info =
TargetMachineCombinerInfo::create(createPatterns());
if (!Info)
std::abort();
return *Info;
}
} // namespace rcc::riscv
|