diff --git a/llvm/include/llvm/CodeGen/MachineCSE.h b/llvm/include/llvm/CodeGen/MachineCSE.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/CodeGen/MachineCSE.h @@ -0,0 +1,29 @@ +//===- MachineCSE.h - Machine Common Subexpression Elimination Pass -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This pass performs global common subexpression elimination on machine +// instructions using a scoped hash table based value numbering scheme. It +// must be run while the machine function is still in SSA form. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MACHINE_CSE_H +#define LLVM_CODEGEN_MACHINE_CSE_H + +#include "llvm/CodeGen/PassManager.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { + +struct MachineCSEPass : PassInfoMixin { + PreservedAnalyses run(MachineFunction &MF, + MachineFunctionAnalysisManager &AM); +}; +} // namespace llvm + +#endif // LLVM_CODEGEN_MACHINE_CSE_H diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -255,7 +255,7 @@ void initializeMachineBlockPlacementPass(PassRegistry&); void initializeMachineBlockPlacementStatsPass(PassRegistry&); void initializeMachineBranchProbabilityInfoPass(PassRegistry&); -void initializeMachineCSEPass(PassRegistry&); +void initializeMachineCSELegacyPassPass(PassRegistry &); void initializeMachineCombinerPass(PassRegistry&); void initializeMachineCopyPropagationLegacyPassPass(PassRegistry &); void initializeMachineDominanceFrontierPass(PassRegistry&); diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp --- a/llvm/lib/CodeGen/CodeGen.cpp +++ b/llvm/lib/CodeGen/CodeGen.cpp @@ -56,7 +56,7 @@ initializeMachineBlockFrequencyInfoPass(Registry); initializeMachineBlockPlacementPass(Registry); initializeMachineBlockPlacementStatsPass(Registry); - initializeMachineCSEPass(Registry); + initializeMachineCSELegacyPassPass(Registry); initializeMachineCombinerPass(Registry); initializeMachineCopyPropagationLegacyPassPass(Registry); initializeMachineDominatorTreeWrapperPassPass(Registry); diff --git a/llvm/lib/CodeGen/MachineCSE.cpp b/llvm/lib/CodeGen/MachineCSE.cpp --- a/llvm/lib/CodeGen/MachineCSE.cpp +++ b/llvm/lib/CodeGen/MachineCSE.cpp @@ -12,6 +12,8 @@ // //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/MachineCSE.h" + #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/ScopedHashTable.h" #include "llvm/ADT/SmallPtrSet.h" @@ -27,6 +29,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PassManager.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetOpcodes.h" @@ -60,36 +63,29 @@ namespace { - class MachineCSE : public MachineFunctionPass { - const TargetInstrInfo *TII; - const TargetRegisterInfo *TRI; - AliasAnalysis *AA; - MachineDominatorTree *DT; - MachineRegisterInfo *MRI; - - public: - static char ID; // Pass identification - - MachineCSE() : MachineFunctionPass(ID) { - initializeMachineCSEPass(*PassRegistry::getPassRegistry()); - } - - bool runOnMachineFunction(MachineFunction &MF) override; +class MachineCSE { + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + AliasAnalysis *AA; + MachineDominatorTree *DT; + MachineRegisterInfo *MRI; + +public: + MachineCSE(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, + AliasAnalysis *AA, MachineDominatorTree *DT, + MachineRegisterInfo *MRI) + : TII(TII), TRI(TRI), AA(AA), DT(DT), MRI(MRI) { + LookAheadLimit = TII->getMachineCSELookAheadLimit(); + } - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - MachineFunctionPass::getAnalysisUsage(AU); - AU.addRequired(); - AU.addPreservedID(MachineLoopInfoID); - AU.addRequired(); - AU.addPreserved(); - } + ~MachineCSE() { + ScopeMap.clear(); + PREMap.clear(); + Exps.clear(); + } - void releaseMemory() override { - ScopeMap.clear(); - PREMap.clear(); - Exps.clear(); - } + bool PerformCSE(MachineDomTreeNode *Node); + bool PerformSimplePRE(MachineDominatorTree *DT); private: using AllocatorTy = RecyclingAllocator &OpenChildren); - bool PerformCSE(MachineDomTreeNode *Node); bool isPRECandidate(MachineInstr *MI); bool ProcessBlockPRE(MachineDominatorTree *MDT, MachineBasicBlock *MBB); - bool PerformSimplePRE(MachineDominatorTree *DT); }; +class MachineCSELegacyPass : public MachineFunctionPass { +public: + static char ID; // Pass identification + + MachineCSELegacyPass() : MachineFunctionPass(ID) { + initializeMachineCSELegacyPassPass(*PassRegistry::getPassRegistry()); + } + + bool runOnMachineFunction(MachineFunction &MF) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesCFG(); + MachineFunctionPass::getAnalysisUsage(AU); + AU.addRequired(); + AU.addPreservedID(MachineLoopInfoID); + AU.addRequired(); + AU.addPreserved(); + } +}; + } // end anonymous namespace -char MachineCSE::ID = 0; +char MachineCSELegacyPass::ID = 0; -char &llvm::MachineCSEID = MachineCSE::ID; +char &llvm::MachineCSEID = MachineCSELegacyPass::ID; -INITIALIZE_PASS_BEGIN(MachineCSE, DEBUG_TYPE, +INITIALIZE_PASS_BEGIN(MachineCSELegacyPass, DEBUG_TYPE, "Machine Common Subexpression Elimination", false, false) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) -INITIALIZE_PASS_END(MachineCSE, DEBUG_TYPE, +INITIALIZE_PASS_END(MachineCSELegacyPass, DEBUG_TYPE, "Machine Common Subexpression Elimination", false, false) /// The source register of a COPY machine instruction can be propagated to all @@ -854,18 +868,44 @@ return Changed; } -bool MachineCSE::runOnMachineFunction(MachineFunction &MF) { +bool MachineCSELegacyPass::runOnMachineFunction(MachineFunction &MF) { if (skipFunction(MF.getFunction())) return false; - TII = MF.getSubtarget().getInstrInfo(); - TRI = MF.getSubtarget().getRegisterInfo(); - MRI = &MF.getRegInfo(); - AA = &getAnalysis().getAAResults(); - DT = &getAnalysis(); - LookAheadLimit = TII->getMachineCSELookAheadLimit(); - bool ChangedPRE, ChangedCSE; - ChangedPRE = PerformSimplePRE(DT); - ChangedCSE = PerformCSE(DT->getRootNode()); + MachineDominatorTree *DT = + &getAnalysis().getMachineDominatorTree(); + + MachineCSE MCSE(MF.getSubtarget().getInstrInfo(), + MF.getSubtarget().getRegisterInfo(), + &getAnalysis().getAAResults(), DT, + &MF.getRegInfo()); + + bool ChangedPRE = MCSE.PerformSimplePRE(DT); + bool ChangedCSE = MCSE.PerformCSE(DT->getRootNode()); return ChangedPRE || ChangedCSE; } + +PreservedAnalyses MachineCSEPass::run(MachineFunction &MF, + MachineFunctionAnalysisManager &AM) { + MachineDominatorTree *DT = &AM.getResult(MF); + + MachineCSE MCSE(MF.getSubtarget().getInstrInfo(), + MF.getSubtarget().getRegisterInfo(), + AM.getResult(MF) + .getManager() + .getCachedResult( + *const_cast(&MF.getFunction())), + DT, &MF.getRegInfo()); + + bool ChangedPRE = MCSE.PerformSimplePRE(DT); + bool ChangedCSE = MCSE.PerformCSE(DT->getRootNode()); + + if (!ChangedPRE && !ChangedCSE) + return PreservedAnalyses::all(); + + PreservedAnalyses PA; + PA.preserveSet(); + PA.preserve(); + + return PA; +} diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -324,4 +324,5 @@ #endif MACHINE_FUNCTION_PASS("machine-cp", MachineCopyPropagationPass()) MACHINE_FUNCTION_PASS("finalize-isel", FinalizeISelPass()) +MACHINE_FUNCTION_PASS("machine-cse", MachineCSEPass()) #undef MACHINE_FUNCTION_PASS