aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib/CodeGen')
-rw-r--r--backend/lib/CodeGen/CMakeLists.txt2
-rw-r--r--backend/lib/CodeGen/MachineOptimizationPipeline.cpp9
-rw-r--r--backend/lib/CodeGen/MachinePeepholeOptimizer.cpp94
3 files changed, 104 insertions, 1 deletions
diff --git a/backend/lib/CodeGen/CMakeLists.txt b/backend/lib/CodeGen/CMakeLists.txt
index b95fe42..8524f1b 100644
--- a/backend/lib/CodeGen/CMakeLists.txt
+++ b/backend/lib/CodeGen/CMakeLists.txt
@@ -43,6 +43,7 @@ set(
LivePhysRegs.cpp
LiveRegUnits.cpp
MachineMemoryFolding.cpp
+ MachinePeepholeOptimizer.cpp
MachineMemOperand.cpp
MachineMetadata.cpp
MachineOperand.cpp
@@ -132,6 +133,7 @@ set(
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/LivePhysRegs.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/LiveRegUnits.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineMemoryFolding.h"
+ "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachinePeepholeOptimizer.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineMemOperand.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineMetadata.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineOperand.h"
diff --git a/backend/lib/CodeGen/MachineOptimizationPipeline.cpp b/backend/lib/CodeGen/MachineOptimizationPipeline.cpp
index adec384..2badb78 100644
--- a/backend/lib/CodeGen/MachineOptimizationPipeline.cpp
+++ b/backend/lib/CodeGen/MachineOptimizationPipeline.cpp
@@ -14,6 +14,7 @@
#include "rcc/CodeGen/MachineFinalization.h"
#include "rcc/CodeGen/MachineLICM.h"
#include "rcc/CodeGen/MachineMemoryFolding.h"
+#include "rcc/CodeGen/MachinePeepholeOptimizer.h"
#include "rcc/CodeGen/MachinePseudoExpansion.h"
#include "rcc/CodeGen/MachineScheduler.h"
#include "rcc/CodeGen/MachineShrinkWrapping.h"
@@ -62,7 +63,13 @@ addSelectedSSAOptimizationPipeline(MachineFunctionPassManager &Pipeline,
Added = addPass<MachineLICMPass>(Pipeline, MachineCodeMotionStage::SelectedSSA);
if (!Added)
return std::unexpected(Added.error());
- return addPass<MachineSinkPass>(Pipeline, MachineCodeMotionStage::SelectedSSA);
+ Added = addPass<MachineSinkPass>(Pipeline, MachineCodeMotionStage::SelectedSSA);
+ if (!Added)
+ return std::unexpected(Added.error());
+ Added = addPass<MachinePeepholeOptimizerPass>(Pipeline, TargetInfo.InstrInfo);
+ if (!Added)
+ return std::unexpected(Added.error());
+ return addPass<MachineDCEPass>(Pipeline);
}
Expected<void> addPreRegisterAllocationOptimizationPipeline(
diff --git a/backend/lib/CodeGen/MachinePeepholeOptimizer.cpp b/backend/lib/CodeGen/MachinePeepholeOptimizer.cpp
new file mode 100644
index 0000000..f874699
--- /dev/null
+++ b/backend/lib/CodeGen/MachinePeepholeOptimizer.cpp
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "rcc/CodeGen/MachinePeepholeOptimizer.h"
+
+#include "rcc/CodeGen/MachineBasicBlock.h"
+#include "rcc/CodeGen/MachineFunction.h"
+#include "rcc/CodeGen/MachineFunctionCloner.h"
+#include "rcc/CodeGen/MachineInstr.h"
+#include "rcc/CodeGen/TargetDescription.h"
+#include "rcc/CodeGen/TargetInstrInfo.h"
+
+#include <optional>
+
+namespace rcc {
+namespace {
+
+[[nodiscard]] const MachinePassContract &peepholeOptimizerContract() {
+ static const MachinePassContract Contract = [] {
+ MachinePassContract Value{
+ .Name = "peephole-opt",
+ .Requires = {MachineFunctionProperty::IsSSA},
+ .Sets = {},
+ .Clears = {},
+ .RequiredAnalyses = {},
+ .VerificationStage = PipelineStage::Selected,
+ };
+ Value.ThreadSafety = PassThreadSafety::ThreadSafe;
+ Value.DeclaredChanges = {MachinePassChange::Instructions, MachinePassChange::Operands,
+ MachinePassChange::Registers};
+ return Value;
+ }();
+ return Contract;
+}
+
+} // namespace
+
+const MachinePassContract &MachinePeepholeOptimizerPass::contract() const noexcept {
+ return peepholeOptimizerContract();
+}
+
+Expected<MachinePassResult> MachinePeepholeOptimizerPass::run(MachineFunction &Function,
+ const TargetDescription &Target,
+ MachineFunctionAnalysisManager &) {
+ if (!Function.properties().containsAll(contract().Requires)) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "machine peephole optimizer requires SSA MachineIR");
+ }
+
+ auto Trial = cloneMachineFunction(
+ Function, Target,
+ MachineFunctionCloneOptions{.NewStableID = Function.stableID(), .NewName = std::nullopt});
+ if (!Trial) {
+ return std::unexpected(
+ withErrorContext(Trial.error(), "machine peephole transaction setup failed: "));
+ }
+ auto TrialResult = runImplementation(*Trial->ClonedFunction, Target);
+ if (!TrialResult)
+ return std::unexpected(TrialResult.error());
+
+ auto Result = runImplementation(Function, Target);
+ if (!Result) {
+ return std::unexpected(withErrorContext(
+ Result.error(), "machine peephole diverged after a successful transaction preflight: "));
+ }
+ return Result;
+}
+
+Expected<MachinePassResult>
+MachinePeepholeOptimizerPass::runImplementation(MachineFunction &Function,
+ const TargetDescription &Target) const {
+ MachinePassResult Result;
+ for (MachineBasicBlock *Block = Function.firstBlock(); Block != nullptr; Block = Block->next()) {
+ for (MachineInstr *Instruction = Block->firstInstruction(); Instruction != nullptr;) {
+ MachineInstr *Next = Instruction->next();
+ if (!Instruction->isDebugInstr()) {
+ auto Changed = Info->optimizeCondBranch(*Instruction, Function, Target);
+ if (!Changed)
+ return std::unexpected(Changed.error());
+ Result.Changed |= *Changed;
+ }
+ Instruction = Next;
+ }
+ }
+ if (Result.Changed) {
+ Result.Changes = {MachinePassChange::Instructions, MachinePassChange::Operands,
+ MachinePassChange::Registers};
+ Result.Preserved = PreservedAnalyses::none();
+ } else {
+ Result.Preserved = PreservedAnalyses::all();
+ }
+ return Result;
+}
+
+} // namespace rcc