summaryrefslogtreecommitdiff
path: root/lib/CodeGen/VirtRegMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/VirtRegMap.cpp')
-rw-r--r--lib/CodeGen/VirtRegMap.cpp73
1 files changed, 56 insertions, 17 deletions
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index 13f7e83f3dd0..0ead2b8340ab 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -35,6 +35,7 @@
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/Pass.h"
#include "llvm/Support/Compiler.h"
@@ -241,10 +242,9 @@ bool VirtRegRewriter::runOnMachineFunction(MachineFunction &fn) {
Indexes = &getAnalysis<SlotIndexes>();
LIS = &getAnalysis<LiveIntervals>();
VRM = &getAnalysis<VirtRegMap>();
- DEBUG(dbgs() << "********** REWRITE VIRTUAL REGISTERS **********\n"
- << "********** Function: "
- << MF->getName() << '\n');
- DEBUG(VRM->dump());
+ LLVM_DEBUG(dbgs() << "********** REWRITE VIRTUAL REGISTERS **********\n"
+ << "********** Function: " << MF->getName() << '\n');
+ LLVM_DEBUG(VRM->dump());
// Add kill flags while we still have virtual registers.
LIS->addKillFlags(VRM);
@@ -376,7 +376,7 @@ bool VirtRegRewriter::readsUndefSubreg(const MachineOperand &MO) const {
void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) const {
if (!MI.isIdentityCopy())
return;
- DEBUG(dbgs() << "Identity copy: " << MI);
+ LLVM_DEBUG(dbgs() << "Identity copy: " << MI);
++NumIdCopies;
// Copies like:
@@ -387,14 +387,14 @@ void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) const {
// instruction to maintain this information.
if (MI.getOperand(0).isUndef() || MI.getNumOperands() > 2) {
MI.setDesc(TII->get(TargetOpcode::KILL));
- DEBUG(dbgs() << " replace by: " << MI);
+ LLVM_DEBUG(dbgs() << " replace by: " << MI);
return;
}
if (Indexes)
Indexes->removeSingleMachineInstrFromMaps(MI);
MI.eraseFromBundle();
- DEBUG(dbgs() << " deleted.\n");
+ LLVM_DEBUG(dbgs() << " deleted.\n");
}
/// The liverange splitting logic sometimes produces bundles of copies when
@@ -406,6 +406,8 @@ void VirtRegRewriter::expandCopyBundle(MachineInstr &MI) const {
return;
if (MI.isBundledWithPred() && !MI.isBundledWithSucc()) {
+ SmallVector<MachineInstr *, 2> MIs({&MI});
+
// Only do this when the complete bundle is made out of COPYs.
MachineBasicBlock &MBB = *MI.getParent();
for (MachineBasicBlock::reverse_instr_iterator I =
@@ -413,16 +415,53 @@ void VirtRegRewriter::expandCopyBundle(MachineInstr &MI) const {
I != E && I->isBundledWithSucc(); ++I) {
if (!I->isCopy())
return;
+ MIs.push_back(&*I);
+ }
+ MachineInstr *FirstMI = MIs.back();
+
+ auto anyRegsAlias = [](const MachineInstr *Dst,
+ ArrayRef<MachineInstr *> Srcs,
+ const TargetRegisterInfo *TRI) {
+ for (const MachineInstr *Src : Srcs)
+ if (Src != Dst)
+ if (TRI->regsOverlap(Dst->getOperand(0).getReg(),
+ Src->getOperand(1).getReg()))
+ return true;
+ return false;
+ };
+
+ // If any of the destination registers in the bundle of copies alias any of
+ // the source registers, try to schedule the instructions to avoid any
+ // clobbering.
+ for (int E = MIs.size(), PrevE = E; E > 1; PrevE = E) {
+ for (int I = E; I--; )
+ if (!anyRegsAlias(MIs[I], makeArrayRef(MIs).take_front(E), TRI)) {
+ if (I + 1 != E)
+ std::swap(MIs[I], MIs[E - 1]);
+ --E;
+ }
+ if (PrevE == E) {
+ MF->getFunction().getContext().emitError(
+ "register rewriting failed: cycle in copy bundle");
+ break;
+ }
}
- for (MachineBasicBlock::reverse_instr_iterator I = MI.getReverseIterator();
- I->isBundledWithPred(); ) {
- MachineInstr &MI = *I;
- ++I;
+ MachineInstr *BundleStart = FirstMI;
+ for (MachineInstr *BundledMI : llvm::reverse(MIs)) {
+ // If instruction is in the middle of the bundle, move it before the
+ // bundle starts, otherwise, just unbundle it. When we get to the last
+ // instruction, the bundle will have been completely undone.
+ if (BundledMI != BundleStart) {
+ BundledMI->removeFromBundle();
+ MBB.insert(FirstMI, BundledMI);
+ } else if (BundledMI->isBundledWithSucc()) {
+ BundledMI->unbundleFromSucc();
+ BundleStart = &*std::next(BundledMI->getIterator());
+ }
- MI.unbundleFromPred();
- if (Indexes)
- Indexes->insertMachineInstrInMaps(MI);
+ if (Indexes && BundledMI != FirstMI)
+ Indexes->insertMachineInstrInMaps(*BundledMI);
}
}
}
@@ -461,7 +500,7 @@ void VirtRegRewriter::rewrite() {
for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end();
MBBI != MBBE; ++MBBI) {
- DEBUG(MBBI->print(dbgs(), Indexes));
+ LLVM_DEBUG(MBBI->print(dbgs(), Indexes));
for (MachineBasicBlock::instr_iterator
MII = MBBI->instr_begin(), MIE = MBBI->instr_end(); MII != MIE;) {
MachineInstr *MI = &*MII;
@@ -530,7 +569,7 @@ void VirtRegRewriter::rewrite() {
// Rewrite. Note we could have used MachineOperand::substPhysReg(), but
// we need the inlining here.
MO.setReg(PhysReg);
- MO.setIsRenamableIfNoExtraRegAllocReq();
+ MO.setIsRenamable(true);
}
// Add any missing super-register kills after rewriting the whole
@@ -544,7 +583,7 @@ void VirtRegRewriter::rewrite() {
while (!SuperDefs.empty())
MI->addRegisterDefined(SuperDefs.pop_back_val(), TRI);
- DEBUG(dbgs() << "> " << *MI);
+ LLVM_DEBUG(dbgs() << "> " << *MI);
expandCopyBundle(*MI);