aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/CodeGen/RegisterPressure.h
diff options
context:
space:
mode:
Diffstat (limited to 'backend/include/rcc/CodeGen/RegisterPressure.h')
-rw-r--r--backend/include/rcc/CodeGen/RegisterPressure.h107
1 files changed, 107 insertions, 0 deletions
diff --git a/backend/include/rcc/CodeGen/RegisterPressure.h b/backend/include/rcc/CodeGen/RegisterPressure.h
new file mode 100644
index 0000000..fa1209a
--- /dev/null
+++ b/backend/include/rcc/CodeGen/RegisterPressure.h
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_REGISTERPRESSURE_H
+#define RCC_CODEGEN_REGISTERPRESSURE_H
+
+#include "rcc/CodeGen/MachineIRTypes.h"
+#include "rcc/CodeGen/ScheduleDAG.h"
+#include "rcc/Support/Error.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <span>
+#include <unordered_map>
+#include <vector>
+
+namespace rcc {
+
+class MachineFunction;
+class TargetDescription;
+class TargetSchedulingModel;
+struct MachineBlockLiveness;
+
+namespace detail {
+struct RegisterPressureBuilder;
+}
+
+struct RegisterPressureValue final {
+ RegisterPressureSetID Set;
+ std::uint32_t Current = 0;
+ std::uint32_t Maximum = 0;
+ std::uint32_t Limit = 0;
+
+ friend constexpr bool operator==(RegisterPressureValue, RegisterPressureValue) noexcept = default;
+};
+
+struct RegisterPressureCost final {
+ std::uint64_t CurrentPressure = 0;
+ std::uint64_t CurrentExcess = 0;
+ std::uint64_t PeakExcess = 0;
+ std::uint64_t PeakIncrease = 0;
+
+ friend constexpr bool operator==(RegisterPressureCost, RegisterPressureCost) noexcept = default;
+};
+
+enum class RegisterPressureDirection : std::uint8_t {
+ TopDown,
+ BottomUp,
+};
+
+class RegisterPressureTracker final {
+public:
+ [[nodiscard]] static Expected<RegisterPressureTracker>
+ create(const ScheduleDAG &DAG, const MachineFunction &Function, const TargetDescription &Target,
+ const TargetSchedulingModel &Model, ScheduleDAGMode Mode,
+ const MachineBlockLiveness &Liveness,
+ RegisterPressureDirection Direction = RegisterPressureDirection::TopDown);
+
+ [[nodiscard]] std::span<const RegisterPressureValue> pressure() const noexcept {
+ return Pressure;
+ }
+
+ [[nodiscard]] bool wasScheduled(std::size_t UnitID) const noexcept {
+ return UnitID < Scheduled.size() && Scheduled[UnitID];
+ }
+
+ [[nodiscard]] Expected<RegisterPressureCost> evaluate(std::size_t UnitID) const;
+ [[nodiscard]] Expected<void> schedule(std::size_t UnitID);
+ [[nodiscard]] RegisterPressureCost cost() const noexcept;
+
+private:
+ using EntityID = std::size_t;
+
+ struct Entity final {
+ std::vector<RegisterPressureSetID> Sets;
+ std::size_t RemainingUses = 0;
+ bool HasDefinition = false;
+ bool DefinitionPending = false;
+ bool LiveOut = false;
+ bool Live = false;
+ };
+
+ struct Event final {
+ std::vector<EntityID> Uses;
+ std::vector<EntityID> Definitions;
+ };
+
+ struct UnitEffects final {
+ std::vector<Event> Events;
+ };
+
+ [[nodiscard]] Expected<void> applyEvent(const Event &Value);
+ [[nodiscard]] Expected<void> makeLive(EntityID Entity);
+ [[nodiscard]] Expected<void> makeDead(EntityID Entity);
+
+ std::vector<RegisterPressureValue> Pressure;
+ std::unordered_map<RegisterPressureSetID, std::size_t> PressureIndexes;
+ std::vector<Entity> Entities;
+ std::vector<UnitEffects> Effects;
+ std::vector<bool> Scheduled;
+ RegisterPressureDirection Direction = RegisterPressureDirection::TopDown;
+
+ friend struct detail::RegisterPressureBuilder;
+};
+
+} // namespace rcc
+
+#endif // RCC_CODEGEN_REGISTERPRESSURE_H