From acb857b83180a70f0aa42a8e98f40c4b0537d629 Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Sat, 27 Aug 2016 02:38:27 +0000 Subject: [PATCH] [RegBankSelect] Do not abort when the target wants to fall back. llvm-svn: 279906 --- .../llvm/CodeGen/GlobalISel/RegBankSelect.h | 14 ++++- llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp | 65 ++++++++++++++++------ 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h b/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h index 9faed91..ffd3787 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h @@ -74,6 +74,7 @@ class BlockFrequency; class MachineBranchProbabilityInfo; class MachineBlockFrequencyInfo; class MachineRegisterInfo; +class TargetPassConfig; class TargetRegisterInfo; /// This pass implements the reg bank selector pass used in the GlobalISel @@ -476,8 +477,12 @@ private: /// Optimization mode of the pass. Mode OptMode; + /// Current target configuration. Controls how the pass handles errors. + const TargetPassConfig *TPC; + /// Assign the register bank of each operand of \p MI. - void assignInstr(MachineInstr &MI); + /// \return True on success, false otherwise. + bool assignInstr(MachineInstr &MI); /// Initialize the field members using \p MF. void init(MachineFunction &MF); @@ -520,7 +525,9 @@ private: /// /// \note The caller is supposed to do the rewriting of op if need be. /// I.e., Reg = op ... => = NewOp ... - void repairReg(MachineOperand &MO, + /// + /// \return True if the repairing worked, false otherwise. + bool repairReg(MachineOperand &MO, const RegisterBankInfo::ValueMapping &ValMapping, RegBankSelect::RepairingPlacement &RepairPt, const iterator_range::const_iterator> @@ -570,7 +577,8 @@ private: /// Apply \p Mapping to \p MI. \p RepairPts represents the different /// mapping action that need to happen for the mapping to be /// applied. - void applyMapping(MachineInstr &MI, + /// \return True if the mapping was applied sucessfully, false otherwise. + bool applyMapping(MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, SmallVectorImpl &RepairPts); diff --git a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp index 9efe48a..f20ff54 100644 --- a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp @@ -17,6 +17,7 @@ #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/Function.h" #include "llvm/Support/BlockFrequency.h" #include "llvm/Support/CommandLine.h" @@ -41,6 +42,7 @@ INITIALIZE_PASS_BEGIN(RegBankSelect, "regbankselect", false, false); INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo) INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) +INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) INITIALIZE_PASS_END(RegBankSelect, "regbankselect", "Assign register bank of generic virtual registers", false, false) @@ -61,6 +63,7 @@ void RegBankSelect::init(MachineFunction &MF) { assert(RBI && "Cannot work without RegisterBankInfo"); MRI = &MF.getRegInfo(); TRI = MF.getSubtarget().getRegisterInfo(); + TPC = &getAnalysis(); if (OptMode != Mode::Fast) { MBFI = &getAnalysis(); MBPI = &getAnalysis(); @@ -78,6 +81,7 @@ void RegBankSelect::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addRequired(); } + AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -104,10 +108,12 @@ bool RegBankSelect::assignmentMatch( return CurRegBank == DesiredRegBrank; } -void RegBankSelect::repairReg( +bool RegBankSelect::repairReg( MachineOperand &MO, const RegisterBankInfo::ValueMapping &ValMapping, RegBankSelect::RepairingPlacement &RepairPt, const iterator_range::const_iterator> &NewVRegs) { + if (ValMapping.BreakDown.size() != 1 && !TPC->isGlobalISelAbortEnabled()) + return false; assert(ValMapping.BreakDown.size() == 1 && "Not yet implemented"); // An empty range of new register means no repairing. assert(NewVRegs.begin() != NewVRegs.end() && "We should not have to repair"); @@ -150,6 +156,7 @@ void RegBankSelect::repairReg( } // TODO: // Legalize NewInstrs if need be. + return true; } uint64_t RegBankSelect::getRepairCost( @@ -196,16 +203,20 @@ uint64_t RegBankSelect::getRepairCost( // TODO: use a dedicated constant for ImpossibleCost. if (Cost != UINT_MAX) return Cost; - assert(false && "Legalization not available yet"); + assert(!TPC->isGlobalISelAbortEnabled() && + "Legalization not available yet"); // Return the legalization cost of that repairing. } - assert(false && "Complex repairing not implemented yet"); - return 1; + assert(!TPC->isGlobalISelAbortEnabled() && + "Complex repairing not implemented yet"); + return UINT_MAX; } RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping( MachineInstr &MI, RegisterBankInfo::InstructionMappings &PossibleMappings, SmallVectorImpl &RepairPts) { + assert(!PossibleMappings.empty() && + "Do not know how to map this instruction"); RegisterBankInfo::InstructionMapping *BestMapping = nullptr; MappingCost Cost = MappingCost::ImpossibleCost(); @@ -220,7 +231,15 @@ RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping( RepairPts.emplace_back(std::move(RepairPt)); } } - assert(BestMapping && "No suitable mapping for instruction"); + if (!BestMapping && !TPC->isGlobalISelAbortEnabled()) { + // If none of the mapping worked that means they are all impossible. + // Thus, pick the first one and set an impossible repairing point. + // It will trigger the failed isel mode. + BestMapping = &(*PossibleMappings.begin()); + RepairPts.emplace_back( + RepairingPlacement(MI, 0, *TRI, *this, RepairingPlacement::Impossible)); + } else + assert(BestMapping && "No suitable mapping for instruction"); return *BestMapping; } @@ -467,7 +486,7 @@ RegBankSelect::MappingCost RegBankSelect::computeMapping( return Cost; } -void RegBankSelect::applyMapping( +bool RegBankSelect::applyMapping( MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, SmallVectorImpl &RepairPts) { // OpdMapper will hold all the information needed for the rewritting. @@ -475,9 +494,9 @@ void RegBankSelect::applyMapping( // First, place the repairing code. for (RepairingPlacement &RepairPt : RepairPts) { - assert(RepairPt.canMaterialize() && - RepairPt.getKind() != RepairingPlacement::Impossible && - "This mapping is impossible"); + if (!RepairPt.canMaterialize() || + RepairPt.getKind() == RepairingPlacement::Impossible) + return false; assert(RepairPt.getKind() != RepairingPlacement::None && "This should not make its way in the list"); unsigned OpIdx = RepairPt.getOpIdx(); @@ -496,7 +515,8 @@ void RegBankSelect::applyMapping( break; case RepairingPlacement::Insert: OpdMapper.createVRegs(OpIdx); - repairReg(MO, ValMapping, RepairPt, OpdMapper.getVRegs(OpIdx)); + if (!repairReg(MO, ValMapping, RepairPt, OpdMapper.getVRegs(OpIdx))) + return false; break; default: llvm_unreachable("Other kind should not happen"); @@ -505,9 +525,10 @@ void RegBankSelect::applyMapping( // Second, rewrite the instruction. DEBUG(dbgs() << "Actual mapping of the operands: " << OpdMapper << '\n'); RBI->applyMapping(OpdMapper); + return true; } -void RegBankSelect::assignInstr(MachineInstr &MI) { +bool RegBankSelect::assignInstr(MachineInstr &MI) { DEBUG(dbgs() << "Assign: " << MI); // Remember the repairing placement for all the operands. SmallVector RepairPts; @@ -517,13 +538,13 @@ void RegBankSelect::assignInstr(MachineInstr &MI) { BestMapping = RBI->getInstrMapping(MI); MappingCost DefaultCost = computeMapping(MI, BestMapping, RepairPts); (void)DefaultCost; - assert(DefaultCost != MappingCost::ImpossibleCost() && - "Default mapping is not suited"); + if (DefaultCost == MappingCost::ImpossibleCost()) + return false; } else { RegisterBankInfo::InstructionMappings PossibleMappings = RBI->getInstrPossibleMappings(MI); - assert(!PossibleMappings.empty() && - "Do not know how to map this instruction"); + if (PossibleMappings.empty()) + return false; BestMapping = std::move(findBestMapping(MI, PossibleMappings, RepairPts)); } // Make sure the mapping is valid for MI. @@ -533,7 +554,7 @@ void RegBankSelect::assignInstr(MachineInstr &MI) { // After this call, MI may not be valid anymore. // Do not use it. - applyMapping(MI, BestMapping, RepairPts); + return applyMapping(MI, BestMapping, RepairPts); } bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) { @@ -558,6 +579,11 @@ bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) { for (const MachineBasicBlock &MBB : MF) { for (const MachineInstr &MI : MBB) { if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI)) { + if (!TPC->isGlobalISelAbortEnabled()) { + MF.getProperties().set( + MachineFunctionProperties::Property::FailedISel); + return false; + } std::string ErrStorage; raw_string_ostream Err(ErrStorage); Err << "Instruction is not legal: " << MI << '\n'; @@ -586,7 +612,12 @@ bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) { if (isTargetSpecificOpcode(MI.getOpcode())) continue; - assignInstr(MI); + if (!assignInstr(MI)) { + if (TPC->isGlobalISelAbortEnabled()) + report_fatal_error("Unable to map instruction"); + MF.getProperties().set(MachineFunctionProperties::Property::FailedISel); + return false; + } } } OptMode = SaveOptMode; -- 2.7.4