diff options
| author | Sjoerd Meijer <sjoerd.meijer@arm.com> | 2020-01-07 13:54:47 +0000 |
|---|---|---|
| committer | Sjoerd Meijer <sjoerd.meijer@arm.com> | 2020-01-07 13:54:47 +0000 |
| commit | e34801c8e6df11b802f58b202f2ce6598734f040 (patch) | |
| tree | 63aa5135a6177261ea6a1c3ecb4f5393dadaad60 /llvm/lib/Target/ARM/MVEVPTBlockPass.cpp | |
| parent | c0365aaaa4f20dd92d6f887c4539d1360dbb8c8e (diff) | |
| download | bcm5719-llvm-e34801c8e6df11b802f58b202f2ce6598734f040.tar.gz bcm5719-llvm-e34801c8e6df11b802f58b202f2ce6598734f040.zip | |
[ARM][MVE] VPT Blocks: findVCMPToFoldIntoVPS
This is a recommit of D71330, but with a few things fixed and changed:
1) ReachingDefAnalysis: this was not running with optnone as it was checking
skipFunction(), which other analysis passes don't do. I guess this is a
copy-paste from a codegen pass.
2) VPTBlockPass: here I've added skipFunction(), because like most/all
optimisations, we don't want to run this with optnone.
This fixes the issues with the initial/previous commit: the VPTBlockPass was
running with optnone, but ReachingDefAnalysis wasn't, and so VPTBlockPass was
crashing querying ReachingDefAnalysis.
I've added test case mve-vpt-block-optnone.mir to check that we don't run
VPTBlock with optnone.
Differential Revision: https://reviews.llvm.org/D71470
Diffstat (limited to 'llvm/lib/Target/ARM/MVEVPTBlockPass.cpp')
| -rw-r--r-- | llvm/lib/Target/ARM/MVEVPTBlockPass.cpp | 72 |
1 files changed, 41 insertions, 31 deletions
diff --git a/llvm/lib/Target/ARM/MVEVPTBlockPass.cpp b/llvm/lib/Target/ARM/MVEVPTBlockPass.cpp index c8b725f339e..19d34fd275d 100644 --- a/llvm/lib/Target/ARM/MVEVPTBlockPass.cpp +++ b/llvm/lib/Target/ARM/MVEVPTBlockPass.cpp @@ -22,9 +22,9 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/ReachingDefAnalysis.h" #include "llvm/IR/DebugLoc.h" #include "llvm/MC/MCInstrDesc.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/Debug.h" #include <cassert> #include <new> @@ -37,16 +37,21 @@ namespace { class MVEVPTBlock : public MachineFunctionPass { public: static char ID; - const Thumb2InstrInfo *TII; - const TargetRegisterInfo *TRI; MVEVPTBlock() : MachineFunctionPass(ID) {} bool runOnMachineFunction(MachineFunction &Fn) override; + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesCFG(); + AU.addRequired<ReachingDefAnalysis>(); + MachineFunctionPass::getAnalysisUsage(AU); + } + MachineFunctionProperties getRequiredProperties() const override { return MachineFunctionProperties().set( - MachineFunctionProperties::Property::NoVRegs); + MachineFunctionProperties::Property::NoVRegs).set( + MachineFunctionProperties::Property::TracksLiveness); } StringRef getPassName() const override { @@ -55,6 +60,9 @@ namespace { private: bool InsertVPTBlocks(MachineBasicBlock &MBB); + + const Thumb2InstrInfo *TII = nullptr; + ReachingDefAnalysis *RDA = nullptr; }; char MVEVPTBlock::ID = 0; @@ -63,41 +71,32 @@ namespace { INITIALIZE_PASS(MVEVPTBlock, DEBUG_TYPE, "ARM MVE VPT block pass", false, false) -static MachineInstr *findVCMPToFoldIntoVPST(MachineBasicBlock::iterator MI, - const TargetRegisterInfo *TRI, +static MachineInstr *findVCMPToFoldIntoVPST(MachineInstr *MI, + ReachingDefAnalysis *RDA, unsigned &NewOpcode) { - // Search backwards to the instruction that defines VPR. This may or not - // be a VCMP, we check that after this loop. If we find another instruction - // that reads cpsr, we return nullptr. - MachineBasicBlock::iterator CmpMI = MI; - while (CmpMI != MI->getParent()->begin()) { - --CmpMI; - if (CmpMI->modifiesRegister(ARM::VPR, TRI)) - break; - if (CmpMI->readsRegister(ARM::VPR, TRI)) - break; - } - - if (CmpMI == MI) - return nullptr; - NewOpcode = VCMPOpcodeToVPT(CmpMI->getOpcode()); - if (NewOpcode == 0) + // First, search backwards to the instruction that defines VPR + auto *Def = RDA->getReachingMIDef(MI, ARM::VPR); + if (!Def) return nullptr; - // Search forward from CmpMI to MI, checking if either register was def'd - if (registerDefinedBetween(CmpMI->getOperand(1).getReg(), std::next(CmpMI), - MI, TRI)) + // Now check that Def is a VCMP + if (!(NewOpcode = VCMPOpcodeToVPT(Def->getOpcode()))) return nullptr; - if (registerDefinedBetween(CmpMI->getOperand(2).getReg(), std::next(CmpMI), - MI, TRI)) + + // Check that Def's operands are not defined between the VCMP and MI, i.e. + // check that they have the same reaching def. + if (!RDA->hasSameReachingDef(Def, MI, Def->getOperand(1).getReg()) || + !RDA->hasSameReachingDef(Def, MI, Def->getOperand(2).getReg())) return nullptr; - return &*CmpMI; + + return Def; } bool MVEVPTBlock::InsertVPTBlocks(MachineBasicBlock &Block) { bool Modified = false; MachineBasicBlock::instr_iterator MBIter = Block.instr_begin(); MachineBasicBlock::instr_iterator EndIter = Block.instr_end(); + SmallVector<MachineInstr *, 4> RemovedVCMPs; while (MBIter != EndIter) { MachineInstr *MI = &*MBIter; @@ -143,7 +142,7 @@ bool MVEVPTBlock::InsertVPTBlocks(MachineBasicBlock &Block) { // a VPST directly MachineInstrBuilder MIBuilder; unsigned NewOpcode; - MachineInstr *VCMP = findVCMPToFoldIntoVPST(MI, TRI, NewOpcode); + MachineInstr *VCMP = findVCMPToFoldIntoVPST(MI, RDA, NewOpcode); if (VCMP) { LLVM_DEBUG(dbgs() << " folding VCMP into VPST: "; VCMP->dump()); MIBuilder = BuildMI(Block, MI, dl, TII->get(NewOpcode)); @@ -151,7 +150,11 @@ bool MVEVPTBlock::InsertVPTBlocks(MachineBasicBlock &Block) { MIBuilder.add(VCMP->getOperand(1)); MIBuilder.add(VCMP->getOperand(2)); MIBuilder.add(VCMP->getOperand(3)); - VCMP->eraseFromParent(); + // We delay removing the actual VCMP instruction by saving it to a list + // and deleting all instructions in this list in one go after we have + // created the VPT blocks. We do this in order not to invalidate the + // ReachingDefAnalysis that is queried by 'findVCMPToFoldIntoVPST'. + RemovedVCMPs.push_back(VCMP); } else { MIBuilder = BuildMI(Block, MI, dl, TII->get(ARM::MVE_VPST)); MIBuilder.addImm(BlockMask); @@ -162,10 +165,17 @@ bool MVEVPTBlock::InsertVPTBlocks(MachineBasicBlock &Block) { Modified = true; } + + for (auto *I : RemovedVCMPs) + I->eraseFromParent(); + return Modified; } bool MVEVPTBlock::runOnMachineFunction(MachineFunction &Fn) { + if (skipFunction(Fn.getFunction())) + return false; + const ARMSubtarget &STI = static_cast<const ARMSubtarget &>(Fn.getSubtarget()); @@ -173,7 +183,7 @@ bool MVEVPTBlock::runOnMachineFunction(MachineFunction &Fn) { return false; TII = static_cast<const Thumb2InstrInfo *>(STI.getInstrInfo()); - TRI = STI.getRegisterInfo(); + RDA = &getAnalysis<ReachingDefAnalysis>(); LLVM_DEBUG(dbgs() << "********** ARM MVE VPT BLOCKS **********\n" << "********** Function: " << Fn.getName() << '\n'); |

