diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/OptimizePHIs.cpp')
| -rw-r--r-- | contrib/llvm/lib/CodeGen/OptimizePHIs.cpp | 210 |
1 files changed, 0 insertions, 210 deletions
diff --git a/contrib/llvm/lib/CodeGen/OptimizePHIs.cpp b/contrib/llvm/lib/CodeGen/OptimizePHIs.cpp deleted file mode 100644 index c70b62252139..000000000000 --- a/contrib/llvm/lib/CodeGen/OptimizePHIs.cpp +++ /dev/null @@ -1,210 +0,0 @@ -//===- OptimizePHIs.cpp - Optimize machine instruction PHIs ---------------===// -// -// 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 optimizes machine instruction PHIs to take advantage of -// opportunities created during DAG legalization. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineOperand.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/TargetRegisterInfo.h" -#include "llvm/CodeGen/TargetSubtargetInfo.h" -#include "llvm/Pass.h" -#include <cassert> - -using namespace llvm; - -#define DEBUG_TYPE "opt-phis" - -STATISTIC(NumPHICycles, "Number of PHI cycles replaced"); -STATISTIC(NumDeadPHICycles, "Number of dead PHI cycles"); - -namespace { - - class OptimizePHIs : public MachineFunctionPass { - MachineRegisterInfo *MRI; - const TargetInstrInfo *TII; - - public: - static char ID; // Pass identification - - OptimizePHIs() : MachineFunctionPass(ID) { - initializeOptimizePHIsPass(*PassRegistry::getPassRegistry()); - } - - bool runOnMachineFunction(MachineFunction &Fn) override; - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - MachineFunctionPass::getAnalysisUsage(AU); - } - - private: - using InstrSet = SmallPtrSet<MachineInstr *, 16>; - using InstrSetIterator = SmallPtrSetIterator<MachineInstr *>; - - bool IsSingleValuePHICycle(MachineInstr *MI, unsigned &SingleValReg, - InstrSet &PHIsInCycle); - bool IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle); - bool OptimizeBB(MachineBasicBlock &MBB); - }; - -} // end anonymous namespace - -char OptimizePHIs::ID = 0; - -char &llvm::OptimizePHIsID = OptimizePHIs::ID; - -INITIALIZE_PASS(OptimizePHIs, DEBUG_TYPE, - "Optimize machine instruction PHIs", false, false) - -bool OptimizePHIs::runOnMachineFunction(MachineFunction &Fn) { - if (skipFunction(Fn.getFunction())) - return false; - - MRI = &Fn.getRegInfo(); - TII = Fn.getSubtarget().getInstrInfo(); - - // Find dead PHI cycles and PHI cycles that can be replaced by a single - // value. InstCombine does these optimizations, but DAG legalization may - // introduce new opportunities, e.g., when i64 values are split up for - // 32-bit targets. - bool Changed = false; - for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) - Changed |= OptimizeBB(*I); - - return Changed; -} - -/// IsSingleValuePHICycle - Check if MI is a PHI where all the source operands -/// are copies of SingleValReg, possibly via copies through other PHIs. If -/// SingleValReg is zero on entry, it is set to the register with the single -/// non-copy value. PHIsInCycle is a set used to keep track of the PHIs that -/// have been scanned. PHIs may be grouped by cycle, several cycles or chains. -bool OptimizePHIs::IsSingleValuePHICycle(MachineInstr *MI, - unsigned &SingleValReg, - InstrSet &PHIsInCycle) { - assert(MI->isPHI() && "IsSingleValuePHICycle expects a PHI instruction"); - unsigned DstReg = MI->getOperand(0).getReg(); - - // See if we already saw this register. - if (!PHIsInCycle.insert(MI).second) - return true; - - // Don't scan crazily complex things. - if (PHIsInCycle.size() == 16) - return false; - - // Scan the PHI operands. - for (unsigned i = 1; i != MI->getNumOperands(); i += 2) { - unsigned SrcReg = MI->getOperand(i).getReg(); - if (SrcReg == DstReg) - continue; - MachineInstr *SrcMI = MRI->getVRegDef(SrcReg); - - // Skip over register-to-register moves. - if (SrcMI && SrcMI->isCopy() && - !SrcMI->getOperand(0).getSubReg() && - !SrcMI->getOperand(1).getSubReg() && - TargetRegisterInfo::isVirtualRegister(SrcMI->getOperand(1).getReg())) { - SrcReg = SrcMI->getOperand(1).getReg(); - SrcMI = MRI->getVRegDef(SrcReg); - } - if (!SrcMI) - return false; - - if (SrcMI->isPHI()) { - if (!IsSingleValuePHICycle(SrcMI, SingleValReg, PHIsInCycle)) - return false; - } else { - // Fail if there is more than one non-phi/non-move register. - if (SingleValReg != 0 && SingleValReg != SrcReg) - return false; - SingleValReg = SrcReg; - } - } - return true; -} - -/// IsDeadPHICycle - Check if the register defined by a PHI is only used by -/// other PHIs in a cycle. -bool OptimizePHIs::IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle) { - assert(MI->isPHI() && "IsDeadPHICycle expects a PHI instruction"); - unsigned DstReg = MI->getOperand(0).getReg(); - assert(TargetRegisterInfo::isVirtualRegister(DstReg) && - "PHI destination is not a virtual register"); - - // See if we already saw this register. - if (!PHIsInCycle.insert(MI).second) - return true; - - // Don't scan crazily complex things. - if (PHIsInCycle.size() == 16) - return false; - - for (MachineInstr &UseMI : MRI->use_nodbg_instructions(DstReg)) { - if (!UseMI.isPHI() || !IsDeadPHICycle(&UseMI, PHIsInCycle)) - return false; - } - - return true; -} - -/// OptimizeBB - Remove dead PHI cycles and PHI cycles that can be replaced by -/// a single value. -bool OptimizePHIs::OptimizeBB(MachineBasicBlock &MBB) { - bool Changed = false; - for (MachineBasicBlock::iterator - MII = MBB.begin(), E = MBB.end(); MII != E; ) { - MachineInstr *MI = &*MII++; - if (!MI->isPHI()) - break; - - // Check for single-value PHI cycles. - unsigned SingleValReg = 0; - InstrSet PHIsInCycle; - if (IsSingleValuePHICycle(MI, SingleValReg, PHIsInCycle) && - SingleValReg != 0) { - unsigned OldReg = MI->getOperand(0).getReg(); - if (!MRI->constrainRegClass(SingleValReg, MRI->getRegClass(OldReg))) - continue; - - MRI->replaceRegWith(OldReg, SingleValReg); - MI->eraseFromParent(); - - // The kill flags on OldReg and SingleValReg may no longer be correct. - MRI->clearKillFlags(SingleValReg); - - ++NumPHICycles; - Changed = true; - continue; - } - - // Check for dead PHI cycles. - PHIsInCycle.clear(); - if (IsDeadPHICycle(MI, PHIsInCycle)) { - for (InstrSetIterator PI = PHIsInCycle.begin(), PE = PHIsInCycle.end(); - PI != PE; ++PI) { - MachineInstr *PhiMI = *PI; - if (MII == PhiMI) - ++MII; - PhiMI->eraseFromParent(); - } - ++NumDeadPHICycles; - Changed = true; - } - } - return Changed; -} |
