diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-30 16:33:32 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-30 16:33:32 +0000 |
commit | 51315c45ff5643a27f9c84b816db54ee870ba29b (patch) | |
tree | 1d87443fa0e53d3e6b315ce25787e64be0906bf7 /contrib/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp | |
parent | 6dfd050075216be8538ae375a22d30db72916f7e (diff) | |
parent | eb11fae6d08f479c0799db45860a98af528fa6e7 (diff) |
Merge llvm trunk r338150, and resolve conflicts.
Notes
Notes:
svn path=/projects/clang700-import/; revision=336916
Diffstat (limited to 'contrib/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp')
-rw-r--r-- | contrib/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp | 106 |
1 files changed, 69 insertions, 37 deletions
diff --git a/contrib/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/contrib/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp index 422cc2219aa8..c83c791327e4 100644 --- a/contrib/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp +++ b/contrib/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp @@ -12,7 +12,6 @@ #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" #include "llvm/ADT/PostOrderIterator.h" -#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/Twine.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" @@ -57,23 +56,17 @@ InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) { void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<TargetPassConfig>(); + getSelectionDAGFallbackAnalysisUsage(AU); MachineFunctionPass::getAnalysisUsage(AU); } bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { - const MachineRegisterInfo &MRI = MF.getRegInfo(); - - // No matter what happens, whether we successfully select the function or not, - // nothing is going to use the vreg types after us. Make sure they disappear. - auto ClearVRegTypesOnReturn = - make_scope_exit([&]() { MRI.getVRegToType().clear(); }); - // If the ISel pipeline failed, do not bother running that pass. if (MF.getProperties().hasProperty( MachineFunctionProperties::Property::FailedISel)) return false; - DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n'); + LLVM_DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n'); const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>(); const InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector(); @@ -85,23 +78,18 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { // FIXME: There are many other MF/MFI fields we need to initialize. + MachineRegisterInfo &MRI = MF.getRegInfo(); #ifndef NDEBUG // Check that our input is fully legal: we require the function to have the // Legalized property, so it should be. - // FIXME: This should be in the MachineVerifier, but it can't use the - // LegalizerInfo as it's currently in the separate GlobalISel library. - // The RegBankSelected property is already checked in the verifier. Note - // that it has the same layering problem, but we only use inline methods so - // end up not needing to link against the GlobalISel library. - if (const LegalizerInfo *MLI = MF.getSubtarget().getLegalizerInfo()) - for (MachineBasicBlock &MBB : MF) - for (MachineInstr &MI : MBB) - if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI, MRI)) { - reportGISelFailure(MF, TPC, MORE, "gisel-select", - "instruction is not legal", MI); - return false; - } - + // FIXME: This should be in the MachineVerifier, as the RegBankSelected + // property check already is. + if (!DisableGISelLegalityCheck) + if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) { + reportGISelFailure(MF, TPC, MORE, "gisel-select", + "instruction is not legal", *MI); + return false; + } #endif // FIXME: We could introduce new blocks and will need to fix the outer loop. // Until then, keep track of the number of blocks to assert that we don't. @@ -129,12 +117,12 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { else --MII; - DEBUG(dbgs() << "Selecting: \n " << MI); + LLVM_DEBUG(dbgs() << "Selecting: \n " << MI); // We could have folded this instruction away already, making it dead. // If so, erase it. if (isTriviallyDead(MI, MRI)) { - DEBUG(dbgs() << "Is dead; erasing.\n"); + LLVM_DEBUG(dbgs() << "Is dead; erasing.\n"); MI.eraseFromParentAndMarkDBGValuesForRemoval(); continue; } @@ -147,7 +135,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { } // Dump the range of instructions that MI expanded into. - DEBUG({ + LLVM_DEBUG({ auto InsertedBegin = ReachedBegin ? MBB->begin() : std::next(MII); dbgs() << "Into:\n"; for (auto &InsertedMI : make_range(InsertedBegin, AfterIt)) @@ -159,30 +147,63 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); + for (MachineBasicBlock &MBB : MF) { + if (MBB.empty()) + continue; + + // Try to find redundant copies b/w vregs of the same register class. + bool ReachedBegin = false; + for (auto MII = std::prev(MBB.end()), Begin = MBB.begin(); !ReachedBegin;) { + // Select this instruction. + MachineInstr &MI = *MII; + + // And have our iterator point to the next instruction, if there is one. + if (MII == Begin) + ReachedBegin = true; + else + --MII; + if (MI.getOpcode() != TargetOpcode::COPY) + continue; + unsigned SrcReg = MI.getOperand(1).getReg(); + unsigned DstReg = MI.getOperand(0).getReg(); + if (TargetRegisterInfo::isVirtualRegister(SrcReg) && + TargetRegisterInfo::isVirtualRegister(DstReg)) { + auto SrcRC = MRI.getRegClass(SrcReg); + auto DstRC = MRI.getRegClass(DstReg); + if (SrcRC == DstRC) { + MRI.replaceRegWith(DstReg, SrcReg); + MI.eraseFromParentAndMarkDBGValuesForRemoval(); + } + } + } + } + // Now that selection is complete, there are no more generic vregs. Verify // that the size of the now-constrained vreg is unchanged and that it has a // register class. - for (auto &VRegToType : MRI.getVRegToType()) { - unsigned VReg = VRegToType.first; - auto *RC = MRI.getRegClassOrNull(VReg); + for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { + unsigned VReg = TargetRegisterInfo::index2VirtReg(I); + MachineInstr *MI = nullptr; if (!MRI.def_empty(VReg)) MI = &*MRI.def_instr_begin(VReg); else if (!MRI.use_empty(VReg)) MI = &*MRI.use_instr_begin(VReg); + if (!MI) + continue; - if (MI && !RC) { + const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg); + if (!RC) { reportGISelFailure(MF, TPC, MORE, "gisel-select", "VReg has no regclass after selection", *MI); return false; - } else if (!RC) - continue; + } - if (VRegToType.second.isValid() && - VRegToType.second.getSizeInBits() > TRI.getRegSizeInBits(*RC)) { - reportGISelFailure(MF, TPC, MORE, "gisel-select", - "VReg has explicit size different from class size", - *MI); + const LLT Ty = MRI.getType(VReg); + if (Ty.isValid() && Ty.getSizeInBits() > TRI.getRegSizeInBits(*RC)) { + reportGISelFailure( + MF, TPC, MORE, "gisel-select", + "VReg's low-level type and register class have different sizes", *MI); return false; } } @@ -199,6 +220,12 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { auto &TLI = *MF.getSubtarget().getTargetLowering(); TLI.finalizeLowering(MF); + LLVM_DEBUG({ + dbgs() << "Rules covered by selecting function: " << MF.getName() << ":"; + for (auto RuleID : CoverageInfo.covered()) + dbgs() << " id" << RuleID; + dbgs() << "\n\n"; + }); CoverageInfo.emit(CoveragePrefix, MF.getSubtarget() .getTargetLowering() @@ -206,6 +233,11 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { .getTarget() .getBackendName()); + // If we successfully selected the function nothing is going to use the vreg + // types after us (otherwise MIRPrinter would need them). Make sure the types + // disappear. + MRI.clearVirtRegTypes(); + // FIXME: Should we accurately track changes? return true; } |