summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/ReachingDefAnalysis.cpp2
-rw-r--r--llvm/lib/Target/ARM/MVEVPTBlockPass.cpp72
2 files changed, 41 insertions, 33 deletions
diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
index 61ae3b75ab5..3c1f9905afd 100644
--- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
+++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
@@ -133,8 +133,6 @@ void ReachingDefAnalysis::processBasicBlock(
}
bool ReachingDefAnalysis::runOnMachineFunction(MachineFunction &mf) {
- if (skipFunction(mf.getFunction()))
- return false;
MF = &mf;
TRI = MF->getSubtarget().getRegisterInfo();
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');
OpenPOWER on IntegriCloud