summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/VirtRegMap.cpp
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2017-03-17 00:41:39 +0000
committerMatthias Braun <matze@braunis.de>2017-03-17 00:41:39 +0000
commitf0b68d3fbc1b0aa04f05fe8718749de4b1d8978f (patch)
treeb94ca5046379fe7883074662e852e565e37df39a /llvm/lib/CodeGen/VirtRegMap.cpp
parentfa289ec7f0bf5ee205ad9d607f16166a3762c06a (diff)
downloadbcm5719-llvm-f0b68d3fbc1b0aa04f05fe8718749de4b1d8978f.tar.gz
bcm5719-llvm-f0b68d3fbc1b0aa04f05fe8718749de4b1d8978f.zip
SplitKit: Correctly implement partial subregister copies
- This fixes a bug where subregister incompatible with the vregs register class where used. - Implement the case where multiple copies are necessary to cover a given lanemask. Differential Revision: https://reviews.llvm.org/D30438 llvm-svn: 298025
Diffstat (limited to 'llvm/lib/CodeGen/VirtRegMap.cpp')
-rw-r--r--llvm/lib/CodeGen/VirtRegMap.cpp31
1 files changed, 31 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/VirtRegMap.cpp b/llvm/lib/CodeGen/VirtRegMap.cpp
index b561c6aba18..06a97fd6d4d 100644
--- a/llvm/lib/CodeGen/VirtRegMap.cpp
+++ b/llvm/lib/CodeGen/VirtRegMap.cpp
@@ -167,6 +167,7 @@ class VirtRegRewriter : public MachineFunctionPass {
bool readsUndefSubreg(const MachineOperand &MO) const;
void addLiveInsForSubRanges(const LiveInterval &LI, unsigned PhysReg) const;
void handleIdentityCopy(MachineInstr &MI) const;
+ void expandCopyBundle(MachineInstr &MI) const;
public:
static char ID;
@@ -372,6 +373,34 @@ void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) const {
DEBUG(dbgs() << " deleted.\n");
}
+/// The liverange splitting logic sometimes produces bundles of copies when
+/// subregisters are involved. Expand these into a sequence of copy instructions
+/// after processing the last in the bundle. Does not update LiveIntervals
+/// which we shouldn't need for this instruction anymore.
+void VirtRegRewriter::expandCopyBundle(MachineInstr &MI) const {
+ if (!MI.isCopy())
+ return;
+
+ if (MI.isBundledWithPred() && !MI.isBundledWithSucc()) {
+ // Only do this when the complete bundle is made out of COPYs.
+ for (MachineBasicBlock::reverse_instr_iterator I =
+ std::next(MI.getReverseIterator()); I->isBundledWithSucc(); ++I) {
+ if (!I->isCopy())
+ return;
+ }
+
+ for (MachineBasicBlock::reverse_instr_iterator I = MI.getReverseIterator();
+ I->isBundledWithPred(); ) {
+ MachineInstr &MI = *I;
+ ++I;
+
+ MI.unbundleFromPred();
+ if (Indexes)
+ Indexes->insertMachineInstrInMaps(MI);
+ }
+ }
+}
+
void VirtRegRewriter::rewrite() {
bool NoSubRegLiveness = !MRI->subRegLivenessEnabled();
SmallVector<unsigned, 8> SuperDeads;
@@ -463,6 +492,8 @@ void VirtRegRewriter::rewrite() {
DEBUG(dbgs() << "> " << *MI);
+ expandCopyBundle(*MI);
+
// We can remove identity copies right now.
handleIdentityCopy(*MI);
}
OpenPOWER on IntegriCloud