1*0b57cec5SDimitry Andric //==- llvm/CodeGen/GlobalISel/RegBankSelect.cpp - RegBankSelect --*- C++ -*-==// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric /// \file 9*0b57cec5SDimitry Andric /// This file implements the RegBankSelect class. 10*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11*0b57cec5SDimitry Andric 12*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" 13*0b57cec5SDimitry Andric #include "llvm/ADT/PostOrderIterator.h" 14*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 15*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 16*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 17*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 18*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 19*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/Utils.h" 20*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 21*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 22*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" 23*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 24*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 25*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 26*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" 27*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 28*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h" 29*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 30*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 31*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 32*0b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h" 33*0b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 34*0b57cec5SDimitry Andric #include "llvm/IR/Function.h" 35*0b57cec5SDimitry Andric #include "llvm/Pass.h" 36*0b57cec5SDimitry Andric #include "llvm/Support/BlockFrequency.h" 37*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 38*0b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 39*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 40*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 41*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 42*0b57cec5SDimitry Andric #include <algorithm> 43*0b57cec5SDimitry Andric #include <cassert> 44*0b57cec5SDimitry Andric #include <cstdint> 45*0b57cec5SDimitry Andric #include <limits> 46*0b57cec5SDimitry Andric #include <memory> 47*0b57cec5SDimitry Andric #include <utility> 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric #define DEBUG_TYPE "regbankselect" 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric using namespace llvm; 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric static cl::opt<RegBankSelect::Mode> RegBankSelectMode( 54*0b57cec5SDimitry Andric cl::desc("Mode of the RegBankSelect pass"), cl::Hidden, cl::Optional, 55*0b57cec5SDimitry Andric cl::values(clEnumValN(RegBankSelect::Mode::Fast, "regbankselect-fast", 56*0b57cec5SDimitry Andric "Run the Fast mode (default mapping)"), 57*0b57cec5SDimitry Andric clEnumValN(RegBankSelect::Mode::Greedy, "regbankselect-greedy", 58*0b57cec5SDimitry Andric "Use the Greedy mode (best local mapping)"))); 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric char RegBankSelect::ID = 0; 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(RegBankSelect, DEBUG_TYPE, 63*0b57cec5SDimitry Andric "Assign register bank of generic virtual registers", 64*0b57cec5SDimitry Andric false, false); 65*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo) 66*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) 67*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 68*0b57cec5SDimitry Andric INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, 69*0b57cec5SDimitry Andric "Assign register bank of generic virtual registers", false, 70*0b57cec5SDimitry Andric false) 71*0b57cec5SDimitry Andric 72*0b57cec5SDimitry Andric RegBankSelect::RegBankSelect(Mode RunningMode) 73*0b57cec5SDimitry Andric : MachineFunctionPass(ID), OptMode(RunningMode) { 74*0b57cec5SDimitry Andric if (RegBankSelectMode.getNumOccurrences() != 0) { 75*0b57cec5SDimitry Andric OptMode = RegBankSelectMode; 76*0b57cec5SDimitry Andric if (RegBankSelectMode != RunningMode) 77*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "RegBankSelect mode overrided by command line\n"); 78*0b57cec5SDimitry Andric } 79*0b57cec5SDimitry Andric } 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric void RegBankSelect::init(MachineFunction &MF) { 82*0b57cec5SDimitry Andric RBI = MF.getSubtarget().getRegBankInfo(); 83*0b57cec5SDimitry Andric assert(RBI && "Cannot work without RegisterBankInfo"); 84*0b57cec5SDimitry Andric MRI = &MF.getRegInfo(); 85*0b57cec5SDimitry Andric TRI = MF.getSubtarget().getRegisterInfo(); 86*0b57cec5SDimitry Andric TPC = &getAnalysis<TargetPassConfig>(); 87*0b57cec5SDimitry Andric if (OptMode != Mode::Fast) { 88*0b57cec5SDimitry Andric MBFI = &getAnalysis<MachineBlockFrequencyInfo>(); 89*0b57cec5SDimitry Andric MBPI = &getAnalysis<MachineBranchProbabilityInfo>(); 90*0b57cec5SDimitry Andric } else { 91*0b57cec5SDimitry Andric MBFI = nullptr; 92*0b57cec5SDimitry Andric MBPI = nullptr; 93*0b57cec5SDimitry Andric } 94*0b57cec5SDimitry Andric MIRBuilder.setMF(MF); 95*0b57cec5SDimitry Andric MORE = llvm::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI); 96*0b57cec5SDimitry Andric } 97*0b57cec5SDimitry Andric 98*0b57cec5SDimitry Andric void RegBankSelect::getAnalysisUsage(AnalysisUsage &AU) const { 99*0b57cec5SDimitry Andric if (OptMode != Mode::Fast) { 100*0b57cec5SDimitry Andric // We could preserve the information from these two analysis but 101*0b57cec5SDimitry Andric // the APIs do not allow to do so yet. 102*0b57cec5SDimitry Andric AU.addRequired<MachineBlockFrequencyInfo>(); 103*0b57cec5SDimitry Andric AU.addRequired<MachineBranchProbabilityInfo>(); 104*0b57cec5SDimitry Andric } 105*0b57cec5SDimitry Andric AU.addRequired<TargetPassConfig>(); 106*0b57cec5SDimitry Andric getSelectionDAGFallbackAnalysisUsage(AU); 107*0b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 108*0b57cec5SDimitry Andric } 109*0b57cec5SDimitry Andric 110*0b57cec5SDimitry Andric bool RegBankSelect::assignmentMatch( 111*0b57cec5SDimitry Andric Register Reg, const RegisterBankInfo::ValueMapping &ValMapping, 112*0b57cec5SDimitry Andric bool &OnlyAssign) const { 113*0b57cec5SDimitry Andric // By default we assume we will have to repair something. 114*0b57cec5SDimitry Andric OnlyAssign = false; 115*0b57cec5SDimitry Andric // Each part of a break down needs to end up in a different register. 116*0b57cec5SDimitry Andric // In other word, Reg assignment does not match. 117*0b57cec5SDimitry Andric if (ValMapping.NumBreakDowns != 1) 118*0b57cec5SDimitry Andric return false; 119*0b57cec5SDimitry Andric 120*0b57cec5SDimitry Andric const RegisterBank *CurRegBank = RBI->getRegBank(Reg, *MRI, *TRI); 121*0b57cec5SDimitry Andric const RegisterBank *DesiredRegBrank = ValMapping.BreakDown[0].RegBank; 122*0b57cec5SDimitry Andric // Reg is free of assignment, a simple assignment will make the 123*0b57cec5SDimitry Andric // register bank to match. 124*0b57cec5SDimitry Andric OnlyAssign = CurRegBank == nullptr; 125*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Does assignment already match: "; 126*0b57cec5SDimitry Andric if (CurRegBank) dbgs() << *CurRegBank; else dbgs() << "none"; 127*0b57cec5SDimitry Andric dbgs() << " against "; 128*0b57cec5SDimitry Andric assert(DesiredRegBrank && "The mapping must be valid"); 129*0b57cec5SDimitry Andric dbgs() << *DesiredRegBrank << '\n';); 130*0b57cec5SDimitry Andric return CurRegBank == DesiredRegBrank; 131*0b57cec5SDimitry Andric } 132*0b57cec5SDimitry Andric 133*0b57cec5SDimitry Andric bool RegBankSelect::repairReg( 134*0b57cec5SDimitry Andric MachineOperand &MO, const RegisterBankInfo::ValueMapping &ValMapping, 135*0b57cec5SDimitry Andric RegBankSelect::RepairingPlacement &RepairPt, 136*0b57cec5SDimitry Andric const iterator_range<SmallVectorImpl<Register>::const_iterator> &NewVRegs) { 137*0b57cec5SDimitry Andric 138*0b57cec5SDimitry Andric assert(ValMapping.NumBreakDowns == (unsigned)size(NewVRegs) && 139*0b57cec5SDimitry Andric "need new vreg for each breakdown"); 140*0b57cec5SDimitry Andric 141*0b57cec5SDimitry Andric // An empty range of new register means no repairing. 142*0b57cec5SDimitry Andric assert(!empty(NewVRegs) && "We should not have to repair"); 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andric MachineInstr *MI; 145*0b57cec5SDimitry Andric if (ValMapping.NumBreakDowns == 1) { 146*0b57cec5SDimitry Andric // Assume we are repairing a use and thus, the original reg will be 147*0b57cec5SDimitry Andric // the source of the repairing. 148*0b57cec5SDimitry Andric Register Src = MO.getReg(); 149*0b57cec5SDimitry Andric Register Dst = *NewVRegs.begin(); 150*0b57cec5SDimitry Andric 151*0b57cec5SDimitry Andric // If we repair a definition, swap the source and destination for 152*0b57cec5SDimitry Andric // the repairing. 153*0b57cec5SDimitry Andric if (MO.isDef()) 154*0b57cec5SDimitry Andric std::swap(Src, Dst); 155*0b57cec5SDimitry Andric 156*0b57cec5SDimitry Andric assert((RepairPt.getNumInsertPoints() == 1 || 157*0b57cec5SDimitry Andric TargetRegisterInfo::isPhysicalRegister(Dst)) && 158*0b57cec5SDimitry Andric "We are about to create several defs for Dst"); 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric // Build the instruction used to repair, then clone it at the right 161*0b57cec5SDimitry Andric // places. Avoiding buildCopy bypasses the check that Src and Dst have the 162*0b57cec5SDimitry Andric // same types because the type is a placeholder when this function is called. 163*0b57cec5SDimitry Andric MI = MIRBuilder.buildInstrNoInsert(TargetOpcode::COPY) 164*0b57cec5SDimitry Andric .addDef(Dst) 165*0b57cec5SDimitry Andric .addUse(Src); 166*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Copy: " << printReg(Src) << " to: " << printReg(Dst) 167*0b57cec5SDimitry Andric << '\n'); 168*0b57cec5SDimitry Andric } else { 169*0b57cec5SDimitry Andric // TODO: Support with G_IMPLICIT_DEF + G_INSERT sequence or G_EXTRACT 170*0b57cec5SDimitry Andric // sequence. 171*0b57cec5SDimitry Andric assert(ValMapping.partsAllUniform() && "irregular breakdowns not supported"); 172*0b57cec5SDimitry Andric 173*0b57cec5SDimitry Andric LLT RegTy = MRI->getType(MO.getReg()); 174*0b57cec5SDimitry Andric if (MO.isDef()) { 175*0b57cec5SDimitry Andric unsigned MergeOp; 176*0b57cec5SDimitry Andric if (RegTy.isVector()) { 177*0b57cec5SDimitry Andric if (ValMapping.NumBreakDowns == RegTy.getNumElements()) 178*0b57cec5SDimitry Andric MergeOp = TargetOpcode::G_BUILD_VECTOR; 179*0b57cec5SDimitry Andric else { 180*0b57cec5SDimitry Andric assert( 181*0b57cec5SDimitry Andric (ValMapping.BreakDown[0].Length * ValMapping.NumBreakDowns == 182*0b57cec5SDimitry Andric RegTy.getSizeInBits()) && 183*0b57cec5SDimitry Andric (ValMapping.BreakDown[0].Length % RegTy.getScalarSizeInBits() == 184*0b57cec5SDimitry Andric 0) && 185*0b57cec5SDimitry Andric "don't understand this value breakdown"); 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andric MergeOp = TargetOpcode::G_CONCAT_VECTORS; 188*0b57cec5SDimitry Andric } 189*0b57cec5SDimitry Andric } else 190*0b57cec5SDimitry Andric MergeOp = TargetOpcode::G_MERGE_VALUES; 191*0b57cec5SDimitry Andric 192*0b57cec5SDimitry Andric auto MergeBuilder = 193*0b57cec5SDimitry Andric MIRBuilder.buildInstrNoInsert(MergeOp) 194*0b57cec5SDimitry Andric .addDef(MO.getReg()); 195*0b57cec5SDimitry Andric 196*0b57cec5SDimitry Andric for (Register SrcReg : NewVRegs) 197*0b57cec5SDimitry Andric MergeBuilder.addUse(SrcReg); 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric MI = MergeBuilder; 200*0b57cec5SDimitry Andric } else { 201*0b57cec5SDimitry Andric MachineInstrBuilder UnMergeBuilder = 202*0b57cec5SDimitry Andric MIRBuilder.buildInstrNoInsert(TargetOpcode::G_UNMERGE_VALUES); 203*0b57cec5SDimitry Andric for (Register DefReg : NewVRegs) 204*0b57cec5SDimitry Andric UnMergeBuilder.addDef(DefReg); 205*0b57cec5SDimitry Andric 206*0b57cec5SDimitry Andric UnMergeBuilder.addUse(MO.getReg()); 207*0b57cec5SDimitry Andric MI = UnMergeBuilder; 208*0b57cec5SDimitry Andric } 209*0b57cec5SDimitry Andric } 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric if (RepairPt.getNumInsertPoints() != 1) 212*0b57cec5SDimitry Andric report_fatal_error("need testcase to support multiple insertion points"); 213*0b57cec5SDimitry Andric 214*0b57cec5SDimitry Andric // TODO: 215*0b57cec5SDimitry Andric // Check if MI is legal. if not, we need to legalize all the 216*0b57cec5SDimitry Andric // instructions we are going to insert. 217*0b57cec5SDimitry Andric std::unique_ptr<MachineInstr *[]> NewInstrs( 218*0b57cec5SDimitry Andric new MachineInstr *[RepairPt.getNumInsertPoints()]); 219*0b57cec5SDimitry Andric bool IsFirst = true; 220*0b57cec5SDimitry Andric unsigned Idx = 0; 221*0b57cec5SDimitry Andric for (const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) { 222*0b57cec5SDimitry Andric MachineInstr *CurMI; 223*0b57cec5SDimitry Andric if (IsFirst) 224*0b57cec5SDimitry Andric CurMI = MI; 225*0b57cec5SDimitry Andric else 226*0b57cec5SDimitry Andric CurMI = MIRBuilder.getMF().CloneMachineInstr(MI); 227*0b57cec5SDimitry Andric InsertPt->insert(*CurMI); 228*0b57cec5SDimitry Andric NewInstrs[Idx++] = CurMI; 229*0b57cec5SDimitry Andric IsFirst = false; 230*0b57cec5SDimitry Andric } 231*0b57cec5SDimitry Andric // TODO: 232*0b57cec5SDimitry Andric // Legalize NewInstrs if need be. 233*0b57cec5SDimitry Andric return true; 234*0b57cec5SDimitry Andric } 235*0b57cec5SDimitry Andric 236*0b57cec5SDimitry Andric uint64_t RegBankSelect::getRepairCost( 237*0b57cec5SDimitry Andric const MachineOperand &MO, 238*0b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping) const { 239*0b57cec5SDimitry Andric assert(MO.isReg() && "We should only repair register operand"); 240*0b57cec5SDimitry Andric assert(ValMapping.NumBreakDowns && "Nothing to map??"); 241*0b57cec5SDimitry Andric 242*0b57cec5SDimitry Andric bool IsSameNumOfValues = ValMapping.NumBreakDowns == 1; 243*0b57cec5SDimitry Andric const RegisterBank *CurRegBank = RBI->getRegBank(MO.getReg(), *MRI, *TRI); 244*0b57cec5SDimitry Andric // If MO does not have a register bank, we should have just been 245*0b57cec5SDimitry Andric // able to set one unless we have to break the value down. 246*0b57cec5SDimitry Andric assert(CurRegBank || MO.isDef()); 247*0b57cec5SDimitry Andric 248*0b57cec5SDimitry Andric // Def: Val <- NewDefs 249*0b57cec5SDimitry Andric // Same number of values: copy 250*0b57cec5SDimitry Andric // Different number: Val = build_sequence Defs1, Defs2, ... 251*0b57cec5SDimitry Andric // Use: NewSources <- Val. 252*0b57cec5SDimitry Andric // Same number of values: copy. 253*0b57cec5SDimitry Andric // Different number: Src1, Src2, ... = 254*0b57cec5SDimitry Andric // extract_value Val, Src1Begin, Src1Len, Src2Begin, Src2Len, ... 255*0b57cec5SDimitry Andric // We should remember that this value is available somewhere else to 256*0b57cec5SDimitry Andric // coalesce the value. 257*0b57cec5SDimitry Andric 258*0b57cec5SDimitry Andric if (ValMapping.NumBreakDowns != 1) 259*0b57cec5SDimitry Andric return RBI->getBreakDownCost(ValMapping, CurRegBank); 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric if (IsSameNumOfValues) { 262*0b57cec5SDimitry Andric const RegisterBank *DesiredRegBrank = ValMapping.BreakDown[0].RegBank; 263*0b57cec5SDimitry Andric // If we repair a definition, swap the source and destination for 264*0b57cec5SDimitry Andric // the repairing. 265*0b57cec5SDimitry Andric if (MO.isDef()) 266*0b57cec5SDimitry Andric std::swap(CurRegBank, DesiredRegBrank); 267*0b57cec5SDimitry Andric // TODO: It may be possible to actually avoid the copy. 268*0b57cec5SDimitry Andric // If we repair something where the source is defined by a copy 269*0b57cec5SDimitry Andric // and the source of that copy is on the right bank, we can reuse 270*0b57cec5SDimitry Andric // it for free. 271*0b57cec5SDimitry Andric // E.g., 272*0b57cec5SDimitry Andric // RegToRepair<BankA> = copy AlternativeSrc<BankB> 273*0b57cec5SDimitry Andric // = op RegToRepair<BankA> 274*0b57cec5SDimitry Andric // We can simply propagate AlternativeSrc instead of copying RegToRepair 275*0b57cec5SDimitry Andric // into a new virtual register. 276*0b57cec5SDimitry Andric // We would also need to propagate this information in the 277*0b57cec5SDimitry Andric // repairing placement. 278*0b57cec5SDimitry Andric unsigned Cost = RBI->copyCost(*DesiredRegBrank, *CurRegBank, 279*0b57cec5SDimitry Andric RBI->getSizeInBits(MO.getReg(), *MRI, *TRI)); 280*0b57cec5SDimitry Andric // TODO: use a dedicated constant for ImpossibleCost. 281*0b57cec5SDimitry Andric if (Cost != std::numeric_limits<unsigned>::max()) 282*0b57cec5SDimitry Andric return Cost; 283*0b57cec5SDimitry Andric // Return the legalization cost of that repairing. 284*0b57cec5SDimitry Andric } 285*0b57cec5SDimitry Andric return std::numeric_limits<unsigned>::max(); 286*0b57cec5SDimitry Andric } 287*0b57cec5SDimitry Andric 288*0b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping( 289*0b57cec5SDimitry Andric MachineInstr &MI, RegisterBankInfo::InstructionMappings &PossibleMappings, 290*0b57cec5SDimitry Andric SmallVectorImpl<RepairingPlacement> &RepairPts) { 291*0b57cec5SDimitry Andric assert(!PossibleMappings.empty() && 292*0b57cec5SDimitry Andric "Do not know how to map this instruction"); 293*0b57cec5SDimitry Andric 294*0b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping *BestMapping = nullptr; 295*0b57cec5SDimitry Andric MappingCost Cost = MappingCost::ImpossibleCost(); 296*0b57cec5SDimitry Andric SmallVector<RepairingPlacement, 4> LocalRepairPts; 297*0b57cec5SDimitry Andric for (const RegisterBankInfo::InstructionMapping *CurMapping : 298*0b57cec5SDimitry Andric PossibleMappings) { 299*0b57cec5SDimitry Andric MappingCost CurCost = 300*0b57cec5SDimitry Andric computeMapping(MI, *CurMapping, LocalRepairPts, &Cost); 301*0b57cec5SDimitry Andric if (CurCost < Cost) { 302*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "New best: " << CurCost << '\n'); 303*0b57cec5SDimitry Andric Cost = CurCost; 304*0b57cec5SDimitry Andric BestMapping = CurMapping; 305*0b57cec5SDimitry Andric RepairPts.clear(); 306*0b57cec5SDimitry Andric for (RepairingPlacement &RepairPt : LocalRepairPts) 307*0b57cec5SDimitry Andric RepairPts.emplace_back(std::move(RepairPt)); 308*0b57cec5SDimitry Andric } 309*0b57cec5SDimitry Andric } 310*0b57cec5SDimitry Andric if (!BestMapping && !TPC->isGlobalISelAbortEnabled()) { 311*0b57cec5SDimitry Andric // If none of the mapping worked that means they are all impossible. 312*0b57cec5SDimitry Andric // Thus, pick the first one and set an impossible repairing point. 313*0b57cec5SDimitry Andric // It will trigger the failed isel mode. 314*0b57cec5SDimitry Andric BestMapping = *PossibleMappings.begin(); 315*0b57cec5SDimitry Andric RepairPts.emplace_back( 316*0b57cec5SDimitry Andric RepairingPlacement(MI, 0, *TRI, *this, RepairingPlacement::Impossible)); 317*0b57cec5SDimitry Andric } else 318*0b57cec5SDimitry Andric assert(BestMapping && "No suitable mapping for instruction"); 319*0b57cec5SDimitry Andric return *BestMapping; 320*0b57cec5SDimitry Andric } 321*0b57cec5SDimitry Andric 322*0b57cec5SDimitry Andric void RegBankSelect::tryAvoidingSplit( 323*0b57cec5SDimitry Andric RegBankSelect::RepairingPlacement &RepairPt, const MachineOperand &MO, 324*0b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping) const { 325*0b57cec5SDimitry Andric const MachineInstr &MI = *MO.getParent(); 326*0b57cec5SDimitry Andric assert(RepairPt.hasSplit() && "We should not have to adjust for split"); 327*0b57cec5SDimitry Andric // Splitting should only occur for PHIs or between terminators, 328*0b57cec5SDimitry Andric // because we only do local repairing. 329*0b57cec5SDimitry Andric assert((MI.isPHI() || MI.isTerminator()) && "Why do we split?"); 330*0b57cec5SDimitry Andric 331*0b57cec5SDimitry Andric assert(&MI.getOperand(RepairPt.getOpIdx()) == &MO && 332*0b57cec5SDimitry Andric "Repairing placement does not match operand"); 333*0b57cec5SDimitry Andric 334*0b57cec5SDimitry Andric // If we need splitting for phis, that means it is because we 335*0b57cec5SDimitry Andric // could not find an insertion point before the terminators of 336*0b57cec5SDimitry Andric // the predecessor block for this argument. In other words, 337*0b57cec5SDimitry Andric // the input value is defined by one of the terminators. 338*0b57cec5SDimitry Andric assert((!MI.isPHI() || !MO.isDef()) && "Need split for phi def?"); 339*0b57cec5SDimitry Andric 340*0b57cec5SDimitry Andric // We split to repair the use of a phi or a terminator. 341*0b57cec5SDimitry Andric if (!MO.isDef()) { 342*0b57cec5SDimitry Andric if (MI.isTerminator()) { 343*0b57cec5SDimitry Andric assert(&MI != &(*MI.getParent()->getFirstTerminator()) && 344*0b57cec5SDimitry Andric "Need to split for the first terminator?!"); 345*0b57cec5SDimitry Andric } else { 346*0b57cec5SDimitry Andric // For the PHI case, the split may not be actually required. 347*0b57cec5SDimitry Andric // In the copy case, a phi is already a copy on the incoming edge, 348*0b57cec5SDimitry Andric // therefore there is no need to split. 349*0b57cec5SDimitry Andric if (ValMapping.NumBreakDowns == 1) 350*0b57cec5SDimitry Andric // This is a already a copy, there is nothing to do. 351*0b57cec5SDimitry Andric RepairPt.switchTo(RepairingPlacement::RepairingKind::Reassign); 352*0b57cec5SDimitry Andric } 353*0b57cec5SDimitry Andric return; 354*0b57cec5SDimitry Andric } 355*0b57cec5SDimitry Andric 356*0b57cec5SDimitry Andric // At this point, we need to repair a defintion of a terminator. 357*0b57cec5SDimitry Andric 358*0b57cec5SDimitry Andric // Technically we need to fix the def of MI on all outgoing 359*0b57cec5SDimitry Andric // edges of MI to keep the repairing local. In other words, we 360*0b57cec5SDimitry Andric // will create several definitions of the same register. This 361*0b57cec5SDimitry Andric // does not work for SSA unless that definition is a physical 362*0b57cec5SDimitry Andric // register. 363*0b57cec5SDimitry Andric // However, there are other cases where we can get away with 364*0b57cec5SDimitry Andric // that while still keeping the repairing local. 365*0b57cec5SDimitry Andric assert(MI.isTerminator() && MO.isDef() && 366*0b57cec5SDimitry Andric "This code is for the def of a terminator"); 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric // Since we use RPO traversal, if we need to repair a definition 369*0b57cec5SDimitry Andric // this means this definition could be: 370*0b57cec5SDimitry Andric // 1. Used by PHIs (i.e., this VReg has been visited as part of the 371*0b57cec5SDimitry Andric // uses of a phi.), or 372*0b57cec5SDimitry Andric // 2. Part of a target specific instruction (i.e., the target applied 373*0b57cec5SDimitry Andric // some register class constraints when creating the instruction.) 374*0b57cec5SDimitry Andric // If the constraints come for #2, the target said that another mapping 375*0b57cec5SDimitry Andric // is supported so we may just drop them. Indeed, if we do not change 376*0b57cec5SDimitry Andric // the number of registers holding that value, the uses will get fixed 377*0b57cec5SDimitry Andric // when we get to them. 378*0b57cec5SDimitry Andric // Uses in PHIs may have already been proceeded though. 379*0b57cec5SDimitry Andric // If the constraints come for #1, then, those are weak constraints and 380*0b57cec5SDimitry Andric // no actual uses may rely on them. However, the problem remains mainly 381*0b57cec5SDimitry Andric // the same as for #2. If the value stays in one register, we could 382*0b57cec5SDimitry Andric // just switch the register bank of the definition, but we would need to 383*0b57cec5SDimitry Andric // account for a repairing cost for each phi we silently change. 384*0b57cec5SDimitry Andric // 385*0b57cec5SDimitry Andric // In any case, if the value needs to be broken down into several 386*0b57cec5SDimitry Andric // registers, the repairing is not local anymore as we need to patch 387*0b57cec5SDimitry Andric // every uses to rebuild the value in just one register. 388*0b57cec5SDimitry Andric // 389*0b57cec5SDimitry Andric // To summarize: 390*0b57cec5SDimitry Andric // - If the value is in a physical register, we can do the split and 391*0b57cec5SDimitry Andric // fix locally. 392*0b57cec5SDimitry Andric // Otherwise if the value is in a virtual register: 393*0b57cec5SDimitry Andric // - If the value remains in one register, we do not have to split 394*0b57cec5SDimitry Andric // just switching the register bank would do, but we need to account 395*0b57cec5SDimitry Andric // in the repairing cost all the phi we changed. 396*0b57cec5SDimitry Andric // - If the value spans several registers, then we cannot do a local 397*0b57cec5SDimitry Andric // repairing. 398*0b57cec5SDimitry Andric 399*0b57cec5SDimitry Andric // Check if this is a physical or virtual register. 400*0b57cec5SDimitry Andric Register Reg = MO.getReg(); 401*0b57cec5SDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 402*0b57cec5SDimitry Andric // We are going to split every outgoing edges. 403*0b57cec5SDimitry Andric // Check that this is possible. 404*0b57cec5SDimitry Andric // FIXME: The machine representation is currently broken 405*0b57cec5SDimitry Andric // since it also several terminators in one basic block. 406*0b57cec5SDimitry Andric // Because of that we would technically need a way to get 407*0b57cec5SDimitry Andric // the targets of just one terminator to know which edges 408*0b57cec5SDimitry Andric // we have to split. 409*0b57cec5SDimitry Andric // Assert that we do not hit the ill-formed representation. 410*0b57cec5SDimitry Andric 411*0b57cec5SDimitry Andric // If there are other terminators before that one, some of 412*0b57cec5SDimitry Andric // the outgoing edges may not be dominated by this definition. 413*0b57cec5SDimitry Andric assert(&MI == &(*MI.getParent()->getFirstTerminator()) && 414*0b57cec5SDimitry Andric "Do not know which outgoing edges are relevant"); 415*0b57cec5SDimitry Andric const MachineInstr *Next = MI.getNextNode(); 416*0b57cec5SDimitry Andric assert((!Next || Next->isUnconditionalBranch()) && 417*0b57cec5SDimitry Andric "Do not know where each terminator ends up"); 418*0b57cec5SDimitry Andric if (Next) 419*0b57cec5SDimitry Andric // If the next terminator uses Reg, this means we have 420*0b57cec5SDimitry Andric // to split right after MI and thus we need a way to ask 421*0b57cec5SDimitry Andric // which outgoing edges are affected. 422*0b57cec5SDimitry Andric assert(!Next->readsRegister(Reg) && "Need to split between terminators"); 423*0b57cec5SDimitry Andric // We will split all the edges and repair there. 424*0b57cec5SDimitry Andric } else { 425*0b57cec5SDimitry Andric // This is a virtual register defined by a terminator. 426*0b57cec5SDimitry Andric if (ValMapping.NumBreakDowns == 1) { 427*0b57cec5SDimitry Andric // There is nothing to repair, but we may actually lie on 428*0b57cec5SDimitry Andric // the repairing cost because of the PHIs already proceeded 429*0b57cec5SDimitry Andric // as already stated. 430*0b57cec5SDimitry Andric // Though the code will be correct. 431*0b57cec5SDimitry Andric assert(false && "Repairing cost may not be accurate"); 432*0b57cec5SDimitry Andric } else { 433*0b57cec5SDimitry Andric // We need to do non-local repairing. Basically, patch all 434*0b57cec5SDimitry Andric // the uses (i.e., phis) that we already proceeded. 435*0b57cec5SDimitry Andric // For now, just say this mapping is not possible. 436*0b57cec5SDimitry Andric RepairPt.switchTo(RepairingPlacement::RepairingKind::Impossible); 437*0b57cec5SDimitry Andric } 438*0b57cec5SDimitry Andric } 439*0b57cec5SDimitry Andric } 440*0b57cec5SDimitry Andric 441*0b57cec5SDimitry Andric RegBankSelect::MappingCost RegBankSelect::computeMapping( 442*0b57cec5SDimitry Andric MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, 443*0b57cec5SDimitry Andric SmallVectorImpl<RepairingPlacement> &RepairPts, 444*0b57cec5SDimitry Andric const RegBankSelect::MappingCost *BestCost) { 445*0b57cec5SDimitry Andric assert((MBFI || !BestCost) && "Costs comparison require MBFI"); 446*0b57cec5SDimitry Andric 447*0b57cec5SDimitry Andric if (!InstrMapping.isValid()) 448*0b57cec5SDimitry Andric return MappingCost::ImpossibleCost(); 449*0b57cec5SDimitry Andric 450*0b57cec5SDimitry Andric // If mapped with InstrMapping, MI will have the recorded cost. 451*0b57cec5SDimitry Andric MappingCost Cost(MBFI ? MBFI->getBlockFreq(MI.getParent()) : 1); 452*0b57cec5SDimitry Andric bool Saturated = Cost.addLocalCost(InstrMapping.getCost()); 453*0b57cec5SDimitry Andric assert(!Saturated && "Possible mapping saturated the cost"); 454*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Evaluating mapping cost for: " << MI); 455*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "With: " << InstrMapping << '\n'); 456*0b57cec5SDimitry Andric RepairPts.clear(); 457*0b57cec5SDimitry Andric if (BestCost && Cost > *BestCost) { 458*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Mapping is too expensive from the start\n"); 459*0b57cec5SDimitry Andric return Cost; 460*0b57cec5SDimitry Andric } 461*0b57cec5SDimitry Andric 462*0b57cec5SDimitry Andric // Moreover, to realize this mapping, the register bank of each operand must 463*0b57cec5SDimitry Andric // match this mapping. In other words, we may need to locally reassign the 464*0b57cec5SDimitry Andric // register banks. Account for that repairing cost as well. 465*0b57cec5SDimitry Andric // In this context, local means in the surrounding of MI. 466*0b57cec5SDimitry Andric for (unsigned OpIdx = 0, EndOpIdx = InstrMapping.getNumOperands(); 467*0b57cec5SDimitry Andric OpIdx != EndOpIdx; ++OpIdx) { 468*0b57cec5SDimitry Andric const MachineOperand &MO = MI.getOperand(OpIdx); 469*0b57cec5SDimitry Andric if (!MO.isReg()) 470*0b57cec5SDimitry Andric continue; 471*0b57cec5SDimitry Andric Register Reg = MO.getReg(); 472*0b57cec5SDimitry Andric if (!Reg) 473*0b57cec5SDimitry Andric continue; 474*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Opd" << OpIdx << '\n'); 475*0b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping = 476*0b57cec5SDimitry Andric InstrMapping.getOperandMapping(OpIdx); 477*0b57cec5SDimitry Andric // If Reg is already properly mapped, this is free. 478*0b57cec5SDimitry Andric bool Assign; 479*0b57cec5SDimitry Andric if (assignmentMatch(Reg, ValMapping, Assign)) { 480*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "=> is free (match).\n"); 481*0b57cec5SDimitry Andric continue; 482*0b57cec5SDimitry Andric } 483*0b57cec5SDimitry Andric if (Assign) { 484*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "=> is free (simple assignment).\n"); 485*0b57cec5SDimitry Andric RepairPts.emplace_back(RepairingPlacement(MI, OpIdx, *TRI, *this, 486*0b57cec5SDimitry Andric RepairingPlacement::Reassign)); 487*0b57cec5SDimitry Andric continue; 488*0b57cec5SDimitry Andric } 489*0b57cec5SDimitry Andric 490*0b57cec5SDimitry Andric // Find the insertion point for the repairing code. 491*0b57cec5SDimitry Andric RepairPts.emplace_back( 492*0b57cec5SDimitry Andric RepairingPlacement(MI, OpIdx, *TRI, *this, RepairingPlacement::Insert)); 493*0b57cec5SDimitry Andric RepairingPlacement &RepairPt = RepairPts.back(); 494*0b57cec5SDimitry Andric 495*0b57cec5SDimitry Andric // If we need to split a basic block to materialize this insertion point, 496*0b57cec5SDimitry Andric // we may give a higher cost to this mapping. 497*0b57cec5SDimitry Andric // Nevertheless, we may get away with the split, so try that first. 498*0b57cec5SDimitry Andric if (RepairPt.hasSplit()) 499*0b57cec5SDimitry Andric tryAvoidingSplit(RepairPt, MO, ValMapping); 500*0b57cec5SDimitry Andric 501*0b57cec5SDimitry Andric // Check that the materialization of the repairing is possible. 502*0b57cec5SDimitry Andric if (!RepairPt.canMaterialize()) { 503*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Mapping involves impossible repairing\n"); 504*0b57cec5SDimitry Andric return MappingCost::ImpossibleCost(); 505*0b57cec5SDimitry Andric } 506*0b57cec5SDimitry Andric 507*0b57cec5SDimitry Andric // Account for the split cost and repair cost. 508*0b57cec5SDimitry Andric // Unless the cost is already saturated or we do not care about the cost. 509*0b57cec5SDimitry Andric if (!BestCost || Saturated) 510*0b57cec5SDimitry Andric continue; 511*0b57cec5SDimitry Andric 512*0b57cec5SDimitry Andric // To get accurate information we need MBFI and MBPI. 513*0b57cec5SDimitry Andric // Thus, if we end up here this information should be here. 514*0b57cec5SDimitry Andric assert(MBFI && MBPI && "Cost computation requires MBFI and MBPI"); 515*0b57cec5SDimitry Andric 516*0b57cec5SDimitry Andric // FIXME: We will have to rework the repairing cost model. 517*0b57cec5SDimitry Andric // The repairing cost depends on the register bank that MO has. 518*0b57cec5SDimitry Andric // However, when we break down the value into different values, 519*0b57cec5SDimitry Andric // MO may not have a register bank while still needing repairing. 520*0b57cec5SDimitry Andric // For the fast mode, we don't compute the cost so that is fine, 521*0b57cec5SDimitry Andric // but still for the repairing code, we will have to make a choice. 522*0b57cec5SDimitry Andric // For the greedy mode, we should choose greedily what is the best 523*0b57cec5SDimitry Andric // choice based on the next use of MO. 524*0b57cec5SDimitry Andric 525*0b57cec5SDimitry Andric // Sums up the repairing cost of MO at each insertion point. 526*0b57cec5SDimitry Andric uint64_t RepairCost = getRepairCost(MO, ValMapping); 527*0b57cec5SDimitry Andric 528*0b57cec5SDimitry Andric // This is an impossible to repair cost. 529*0b57cec5SDimitry Andric if (RepairCost == std::numeric_limits<unsigned>::max()) 530*0b57cec5SDimitry Andric return MappingCost::ImpossibleCost(); 531*0b57cec5SDimitry Andric 532*0b57cec5SDimitry Andric // Bias used for splitting: 5%. 533*0b57cec5SDimitry Andric const uint64_t PercentageForBias = 5; 534*0b57cec5SDimitry Andric uint64_t Bias = (RepairCost * PercentageForBias + 99) / 100; 535*0b57cec5SDimitry Andric // We should not need more than a couple of instructions to repair 536*0b57cec5SDimitry Andric // an assignment. In other words, the computation should not 537*0b57cec5SDimitry Andric // overflow because the repairing cost is free of basic block 538*0b57cec5SDimitry Andric // frequency. 539*0b57cec5SDimitry Andric assert(((RepairCost < RepairCost * PercentageForBias) && 540*0b57cec5SDimitry Andric (RepairCost * PercentageForBias < 541*0b57cec5SDimitry Andric RepairCost * PercentageForBias + 99)) && 542*0b57cec5SDimitry Andric "Repairing involves more than a billion of instructions?!"); 543*0b57cec5SDimitry Andric for (const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) { 544*0b57cec5SDimitry Andric assert(InsertPt->canMaterialize() && "We should not have made it here"); 545*0b57cec5SDimitry Andric // We will applied some basic block frequency and those uses uint64_t. 546*0b57cec5SDimitry Andric if (!InsertPt->isSplit()) 547*0b57cec5SDimitry Andric Saturated = Cost.addLocalCost(RepairCost); 548*0b57cec5SDimitry Andric else { 549*0b57cec5SDimitry Andric uint64_t CostForInsertPt = RepairCost; 550*0b57cec5SDimitry Andric // Again we shouldn't overflow here givent that 551*0b57cec5SDimitry Andric // CostForInsertPt is frequency free at this point. 552*0b57cec5SDimitry Andric assert(CostForInsertPt + Bias > CostForInsertPt && 553*0b57cec5SDimitry Andric "Repairing + split bias overflows"); 554*0b57cec5SDimitry Andric CostForInsertPt += Bias; 555*0b57cec5SDimitry Andric uint64_t PtCost = InsertPt->frequency(*this) * CostForInsertPt; 556*0b57cec5SDimitry Andric // Check if we just overflowed. 557*0b57cec5SDimitry Andric if ((Saturated = PtCost < CostForInsertPt)) 558*0b57cec5SDimitry Andric Cost.saturate(); 559*0b57cec5SDimitry Andric else 560*0b57cec5SDimitry Andric Saturated = Cost.addNonLocalCost(PtCost); 561*0b57cec5SDimitry Andric } 562*0b57cec5SDimitry Andric 563*0b57cec5SDimitry Andric // Stop looking into what it takes to repair, this is already 564*0b57cec5SDimitry Andric // too expensive. 565*0b57cec5SDimitry Andric if (BestCost && Cost > *BestCost) { 566*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Mapping is too expensive, stop processing\n"); 567*0b57cec5SDimitry Andric return Cost; 568*0b57cec5SDimitry Andric } 569*0b57cec5SDimitry Andric 570*0b57cec5SDimitry Andric // No need to accumulate more cost information. 571*0b57cec5SDimitry Andric // We need to still gather the repairing information though. 572*0b57cec5SDimitry Andric if (Saturated) 573*0b57cec5SDimitry Andric break; 574*0b57cec5SDimitry Andric } 575*0b57cec5SDimitry Andric } 576*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Total cost is: " << Cost << "\n"); 577*0b57cec5SDimitry Andric return Cost; 578*0b57cec5SDimitry Andric } 579*0b57cec5SDimitry Andric 580*0b57cec5SDimitry Andric bool RegBankSelect::applyMapping( 581*0b57cec5SDimitry Andric MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, 582*0b57cec5SDimitry Andric SmallVectorImpl<RegBankSelect::RepairingPlacement> &RepairPts) { 583*0b57cec5SDimitry Andric // OpdMapper will hold all the information needed for the rewriting. 584*0b57cec5SDimitry Andric RegisterBankInfo::OperandsMapper OpdMapper(MI, InstrMapping, *MRI); 585*0b57cec5SDimitry Andric 586*0b57cec5SDimitry Andric // First, place the repairing code. 587*0b57cec5SDimitry Andric for (RepairingPlacement &RepairPt : RepairPts) { 588*0b57cec5SDimitry Andric if (!RepairPt.canMaterialize() || 589*0b57cec5SDimitry Andric RepairPt.getKind() == RepairingPlacement::Impossible) 590*0b57cec5SDimitry Andric return false; 591*0b57cec5SDimitry Andric assert(RepairPt.getKind() != RepairingPlacement::None && 592*0b57cec5SDimitry Andric "This should not make its way in the list"); 593*0b57cec5SDimitry Andric unsigned OpIdx = RepairPt.getOpIdx(); 594*0b57cec5SDimitry Andric MachineOperand &MO = MI.getOperand(OpIdx); 595*0b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping = 596*0b57cec5SDimitry Andric InstrMapping.getOperandMapping(OpIdx); 597*0b57cec5SDimitry Andric Register Reg = MO.getReg(); 598*0b57cec5SDimitry Andric 599*0b57cec5SDimitry Andric switch (RepairPt.getKind()) { 600*0b57cec5SDimitry Andric case RepairingPlacement::Reassign: 601*0b57cec5SDimitry Andric assert(ValMapping.NumBreakDowns == 1 && 602*0b57cec5SDimitry Andric "Reassignment should only be for simple mapping"); 603*0b57cec5SDimitry Andric MRI->setRegBank(Reg, *ValMapping.BreakDown[0].RegBank); 604*0b57cec5SDimitry Andric break; 605*0b57cec5SDimitry Andric case RepairingPlacement::Insert: 606*0b57cec5SDimitry Andric OpdMapper.createVRegs(OpIdx); 607*0b57cec5SDimitry Andric if (!repairReg(MO, ValMapping, RepairPt, OpdMapper.getVRegs(OpIdx))) 608*0b57cec5SDimitry Andric return false; 609*0b57cec5SDimitry Andric break; 610*0b57cec5SDimitry Andric default: 611*0b57cec5SDimitry Andric llvm_unreachable("Other kind should not happen"); 612*0b57cec5SDimitry Andric } 613*0b57cec5SDimitry Andric } 614*0b57cec5SDimitry Andric 615*0b57cec5SDimitry Andric // Second, rewrite the instruction. 616*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Actual mapping of the operands: " << OpdMapper << '\n'); 617*0b57cec5SDimitry Andric RBI->applyMapping(OpdMapper); 618*0b57cec5SDimitry Andric 619*0b57cec5SDimitry Andric return true; 620*0b57cec5SDimitry Andric } 621*0b57cec5SDimitry Andric 622*0b57cec5SDimitry Andric bool RegBankSelect::assignInstr(MachineInstr &MI) { 623*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Assign: " << MI); 624*0b57cec5SDimitry Andric // Remember the repairing placement for all the operands. 625*0b57cec5SDimitry Andric SmallVector<RepairingPlacement, 4> RepairPts; 626*0b57cec5SDimitry Andric 627*0b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping *BestMapping; 628*0b57cec5SDimitry Andric if (OptMode == RegBankSelect::Mode::Fast) { 629*0b57cec5SDimitry Andric BestMapping = &RBI->getInstrMapping(MI); 630*0b57cec5SDimitry Andric MappingCost DefaultCost = computeMapping(MI, *BestMapping, RepairPts); 631*0b57cec5SDimitry Andric (void)DefaultCost; 632*0b57cec5SDimitry Andric if (DefaultCost == MappingCost::ImpossibleCost()) 633*0b57cec5SDimitry Andric return false; 634*0b57cec5SDimitry Andric } else { 635*0b57cec5SDimitry Andric RegisterBankInfo::InstructionMappings PossibleMappings = 636*0b57cec5SDimitry Andric RBI->getInstrPossibleMappings(MI); 637*0b57cec5SDimitry Andric if (PossibleMappings.empty()) 638*0b57cec5SDimitry Andric return false; 639*0b57cec5SDimitry Andric BestMapping = &findBestMapping(MI, PossibleMappings, RepairPts); 640*0b57cec5SDimitry Andric } 641*0b57cec5SDimitry Andric // Make sure the mapping is valid for MI. 642*0b57cec5SDimitry Andric assert(BestMapping->verify(MI) && "Invalid instruction mapping"); 643*0b57cec5SDimitry Andric 644*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Best Mapping: " << *BestMapping << '\n'); 645*0b57cec5SDimitry Andric 646*0b57cec5SDimitry Andric // After this call, MI may not be valid anymore. 647*0b57cec5SDimitry Andric // Do not use it. 648*0b57cec5SDimitry Andric return applyMapping(MI, *BestMapping, RepairPts); 649*0b57cec5SDimitry Andric } 650*0b57cec5SDimitry Andric 651*0b57cec5SDimitry Andric bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) { 652*0b57cec5SDimitry Andric // If the ISel pipeline failed, do not bother running that pass. 653*0b57cec5SDimitry Andric if (MF.getProperties().hasProperty( 654*0b57cec5SDimitry Andric MachineFunctionProperties::Property::FailedISel)) 655*0b57cec5SDimitry Andric return false; 656*0b57cec5SDimitry Andric 657*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Assign register banks for: " << MF.getName() << '\n'); 658*0b57cec5SDimitry Andric const Function &F = MF.getFunction(); 659*0b57cec5SDimitry Andric Mode SaveOptMode = OptMode; 660*0b57cec5SDimitry Andric if (F.hasOptNone()) 661*0b57cec5SDimitry Andric OptMode = Mode::Fast; 662*0b57cec5SDimitry Andric init(MF); 663*0b57cec5SDimitry Andric 664*0b57cec5SDimitry Andric #ifndef NDEBUG 665*0b57cec5SDimitry Andric // Check that our input is fully legal: we require the function to have the 666*0b57cec5SDimitry Andric // Legalized property, so it should be. 667*0b57cec5SDimitry Andric // FIXME: This should be in the MachineVerifier. 668*0b57cec5SDimitry Andric if (!DisableGISelLegalityCheck) 669*0b57cec5SDimitry Andric if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) { 670*0b57cec5SDimitry Andric reportGISelFailure(MF, *TPC, *MORE, "gisel-regbankselect", 671*0b57cec5SDimitry Andric "instruction is not legal", *MI); 672*0b57cec5SDimitry Andric return false; 673*0b57cec5SDimitry Andric } 674*0b57cec5SDimitry Andric #endif 675*0b57cec5SDimitry Andric 676*0b57cec5SDimitry Andric // Walk the function and assign register banks to all operands. 677*0b57cec5SDimitry Andric // Use a RPOT to make sure all registers are assigned before we choose 678*0b57cec5SDimitry Andric // the best mapping of the current instruction. 679*0b57cec5SDimitry Andric ReversePostOrderTraversal<MachineFunction*> RPOT(&MF); 680*0b57cec5SDimitry Andric for (MachineBasicBlock *MBB : RPOT) { 681*0b57cec5SDimitry Andric // Set a sensible insertion point so that subsequent calls to 682*0b57cec5SDimitry Andric // MIRBuilder. 683*0b57cec5SDimitry Andric MIRBuilder.setMBB(*MBB); 684*0b57cec5SDimitry Andric for (MachineBasicBlock::iterator MII = MBB->begin(), End = MBB->end(); 685*0b57cec5SDimitry Andric MII != End;) { 686*0b57cec5SDimitry Andric // MI might be invalidated by the assignment, so move the 687*0b57cec5SDimitry Andric // iterator before hand. 688*0b57cec5SDimitry Andric MachineInstr &MI = *MII++; 689*0b57cec5SDimitry Andric 690*0b57cec5SDimitry Andric // Ignore target-specific instructions: they should use proper regclasses. 691*0b57cec5SDimitry Andric if (isTargetSpecificOpcode(MI.getOpcode())) 692*0b57cec5SDimitry Andric continue; 693*0b57cec5SDimitry Andric 694*0b57cec5SDimitry Andric if (!assignInstr(MI)) { 695*0b57cec5SDimitry Andric reportGISelFailure(MF, *TPC, *MORE, "gisel-regbankselect", 696*0b57cec5SDimitry Andric "unable to map instruction", MI); 697*0b57cec5SDimitry Andric return false; 698*0b57cec5SDimitry Andric } 699*0b57cec5SDimitry Andric 700*0b57cec5SDimitry Andric // It's possible the mapping changed control flow, and moved the following 701*0b57cec5SDimitry Andric // instruction to a new block, so figure out the new parent. 702*0b57cec5SDimitry Andric if (MII != End) { 703*0b57cec5SDimitry Andric MachineBasicBlock *NextInstBB = MII->getParent(); 704*0b57cec5SDimitry Andric if (NextInstBB != MBB) { 705*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Instruction mapping changed control flow\n"); 706*0b57cec5SDimitry Andric MBB = NextInstBB; 707*0b57cec5SDimitry Andric MIRBuilder.setMBB(*MBB); 708*0b57cec5SDimitry Andric End = MBB->end(); 709*0b57cec5SDimitry Andric } 710*0b57cec5SDimitry Andric } 711*0b57cec5SDimitry Andric } 712*0b57cec5SDimitry Andric } 713*0b57cec5SDimitry Andric 714*0b57cec5SDimitry Andric OptMode = SaveOptMode; 715*0b57cec5SDimitry Andric return false; 716*0b57cec5SDimitry Andric } 717*0b57cec5SDimitry Andric 718*0b57cec5SDimitry Andric //------------------------------------------------------------------------------ 719*0b57cec5SDimitry Andric // Helper Classes Implementation 720*0b57cec5SDimitry Andric //------------------------------------------------------------------------------ 721*0b57cec5SDimitry Andric RegBankSelect::RepairingPlacement::RepairingPlacement( 722*0b57cec5SDimitry Andric MachineInstr &MI, unsigned OpIdx, const TargetRegisterInfo &TRI, Pass &P, 723*0b57cec5SDimitry Andric RepairingPlacement::RepairingKind Kind) 724*0b57cec5SDimitry Andric // Default is, we are going to insert code to repair OpIdx. 725*0b57cec5SDimitry Andric : Kind(Kind), OpIdx(OpIdx), 726*0b57cec5SDimitry Andric CanMaterialize(Kind != RepairingKind::Impossible), P(P) { 727*0b57cec5SDimitry Andric const MachineOperand &MO = MI.getOperand(OpIdx); 728*0b57cec5SDimitry Andric assert(MO.isReg() && "Trying to repair a non-reg operand"); 729*0b57cec5SDimitry Andric 730*0b57cec5SDimitry Andric if (Kind != RepairingKind::Insert) 731*0b57cec5SDimitry Andric return; 732*0b57cec5SDimitry Andric 733*0b57cec5SDimitry Andric // Repairings for definitions happen after MI, uses happen before. 734*0b57cec5SDimitry Andric bool Before = !MO.isDef(); 735*0b57cec5SDimitry Andric 736*0b57cec5SDimitry Andric // Check if we are done with MI. 737*0b57cec5SDimitry Andric if (!MI.isPHI() && !MI.isTerminator()) { 738*0b57cec5SDimitry Andric addInsertPoint(MI, Before); 739*0b57cec5SDimitry Andric // We are done with the initialization. 740*0b57cec5SDimitry Andric return; 741*0b57cec5SDimitry Andric } 742*0b57cec5SDimitry Andric 743*0b57cec5SDimitry Andric // Now, look for the special cases. 744*0b57cec5SDimitry Andric if (MI.isPHI()) { 745*0b57cec5SDimitry Andric // - PHI must be the first instructions: 746*0b57cec5SDimitry Andric // * Before, we have to split the related incoming edge. 747*0b57cec5SDimitry Andric // * After, move the insertion point past the last phi. 748*0b57cec5SDimitry Andric if (!Before) { 749*0b57cec5SDimitry Andric MachineBasicBlock::iterator It = MI.getParent()->getFirstNonPHI(); 750*0b57cec5SDimitry Andric if (It != MI.getParent()->end()) 751*0b57cec5SDimitry Andric addInsertPoint(*It, /*Before*/ true); 752*0b57cec5SDimitry Andric else 753*0b57cec5SDimitry Andric addInsertPoint(*(--It), /*Before*/ false); 754*0b57cec5SDimitry Andric return; 755*0b57cec5SDimitry Andric } 756*0b57cec5SDimitry Andric // We repair a use of a phi, we may need to split the related edge. 757*0b57cec5SDimitry Andric MachineBasicBlock &Pred = *MI.getOperand(OpIdx + 1).getMBB(); 758*0b57cec5SDimitry Andric // Check if we can move the insertion point prior to the 759*0b57cec5SDimitry Andric // terminators of the predecessor. 760*0b57cec5SDimitry Andric Register Reg = MO.getReg(); 761*0b57cec5SDimitry Andric MachineBasicBlock::iterator It = Pred.getLastNonDebugInstr(); 762*0b57cec5SDimitry Andric for (auto Begin = Pred.begin(); It != Begin && It->isTerminator(); --It) 763*0b57cec5SDimitry Andric if (It->modifiesRegister(Reg, &TRI)) { 764*0b57cec5SDimitry Andric // We cannot hoist the repairing code in the predecessor. 765*0b57cec5SDimitry Andric // Split the edge. 766*0b57cec5SDimitry Andric addInsertPoint(Pred, *MI.getParent()); 767*0b57cec5SDimitry Andric return; 768*0b57cec5SDimitry Andric } 769*0b57cec5SDimitry Andric // At this point, we can insert in Pred. 770*0b57cec5SDimitry Andric 771*0b57cec5SDimitry Andric // - If It is invalid, Pred is empty and we can insert in Pred 772*0b57cec5SDimitry Andric // wherever we want. 773*0b57cec5SDimitry Andric // - If It is valid, It is the first non-terminator, insert after It. 774*0b57cec5SDimitry Andric if (It == Pred.end()) 775*0b57cec5SDimitry Andric addInsertPoint(Pred, /*Beginning*/ false); 776*0b57cec5SDimitry Andric else 777*0b57cec5SDimitry Andric addInsertPoint(*It, /*Before*/ false); 778*0b57cec5SDimitry Andric } else { 779*0b57cec5SDimitry Andric // - Terminators must be the last instructions: 780*0b57cec5SDimitry Andric // * Before, move the insert point before the first terminator. 781*0b57cec5SDimitry Andric // * After, we have to split the outcoming edges. 782*0b57cec5SDimitry Andric if (Before) { 783*0b57cec5SDimitry Andric // Check whether Reg is defined by any terminator. 784*0b57cec5SDimitry Andric MachineBasicBlock::reverse_iterator It = MI; 785*0b57cec5SDimitry Andric auto REnd = MI.getParent()->rend(); 786*0b57cec5SDimitry Andric 787*0b57cec5SDimitry Andric for (; It != REnd && It->isTerminator(); ++It) { 788*0b57cec5SDimitry Andric assert(!It->modifiesRegister(MO.getReg(), &TRI) && 789*0b57cec5SDimitry Andric "copy insertion in middle of terminators not handled"); 790*0b57cec5SDimitry Andric } 791*0b57cec5SDimitry Andric 792*0b57cec5SDimitry Andric if (It == REnd) { 793*0b57cec5SDimitry Andric addInsertPoint(*MI.getParent()->begin(), true); 794*0b57cec5SDimitry Andric return; 795*0b57cec5SDimitry Andric } 796*0b57cec5SDimitry Andric 797*0b57cec5SDimitry Andric // We are sure to be right before the first terminator. 798*0b57cec5SDimitry Andric addInsertPoint(*It, /*Before*/ false); 799*0b57cec5SDimitry Andric return; 800*0b57cec5SDimitry Andric } 801*0b57cec5SDimitry Andric // Make sure Reg is not redefined by other terminators, otherwise 802*0b57cec5SDimitry Andric // we do not know how to split. 803*0b57cec5SDimitry Andric for (MachineBasicBlock::iterator It = MI, End = MI.getParent()->end(); 804*0b57cec5SDimitry Andric ++It != End;) 805*0b57cec5SDimitry Andric // The machine verifier should reject this kind of code. 806*0b57cec5SDimitry Andric assert(It->modifiesRegister(MO.getReg(), &TRI) && 807*0b57cec5SDimitry Andric "Do not know where to split"); 808*0b57cec5SDimitry Andric // Split each outcoming edges. 809*0b57cec5SDimitry Andric MachineBasicBlock &Src = *MI.getParent(); 810*0b57cec5SDimitry Andric for (auto &Succ : Src.successors()) 811*0b57cec5SDimitry Andric addInsertPoint(Src, Succ); 812*0b57cec5SDimitry Andric } 813*0b57cec5SDimitry Andric } 814*0b57cec5SDimitry Andric 815*0b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint(MachineInstr &MI, 816*0b57cec5SDimitry Andric bool Before) { 817*0b57cec5SDimitry Andric addInsertPoint(*new InstrInsertPoint(MI, Before)); 818*0b57cec5SDimitry Andric } 819*0b57cec5SDimitry Andric 820*0b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint(MachineBasicBlock &MBB, 821*0b57cec5SDimitry Andric bool Beginning) { 822*0b57cec5SDimitry Andric addInsertPoint(*new MBBInsertPoint(MBB, Beginning)); 823*0b57cec5SDimitry Andric } 824*0b57cec5SDimitry Andric 825*0b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint(MachineBasicBlock &Src, 826*0b57cec5SDimitry Andric MachineBasicBlock &Dst) { 827*0b57cec5SDimitry Andric addInsertPoint(*new EdgeInsertPoint(Src, Dst, P)); 828*0b57cec5SDimitry Andric } 829*0b57cec5SDimitry Andric 830*0b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint( 831*0b57cec5SDimitry Andric RegBankSelect::InsertPoint &Point) { 832*0b57cec5SDimitry Andric CanMaterialize &= Point.canMaterialize(); 833*0b57cec5SDimitry Andric HasSplit |= Point.isSplit(); 834*0b57cec5SDimitry Andric InsertPoints.emplace_back(&Point); 835*0b57cec5SDimitry Andric } 836*0b57cec5SDimitry Andric 837*0b57cec5SDimitry Andric RegBankSelect::InstrInsertPoint::InstrInsertPoint(MachineInstr &Instr, 838*0b57cec5SDimitry Andric bool Before) 839*0b57cec5SDimitry Andric : InsertPoint(), Instr(Instr), Before(Before) { 840*0b57cec5SDimitry Andric // Since we do not support splitting, we do not need to update 841*0b57cec5SDimitry Andric // liveness and such, so do not do anything with P. 842*0b57cec5SDimitry Andric assert((!Before || !Instr.isPHI()) && 843*0b57cec5SDimitry Andric "Splitting before phis requires more points"); 844*0b57cec5SDimitry Andric assert((!Before || !Instr.getNextNode() || !Instr.getNextNode()->isPHI()) && 845*0b57cec5SDimitry Andric "Splitting between phis does not make sense"); 846*0b57cec5SDimitry Andric } 847*0b57cec5SDimitry Andric 848*0b57cec5SDimitry Andric void RegBankSelect::InstrInsertPoint::materialize() { 849*0b57cec5SDimitry Andric if (isSplit()) { 850*0b57cec5SDimitry Andric // Slice and return the beginning of the new block. 851*0b57cec5SDimitry Andric // If we need to split between the terminators, we theoritically 852*0b57cec5SDimitry Andric // need to know where the first and second set of terminators end 853*0b57cec5SDimitry Andric // to update the successors properly. 854*0b57cec5SDimitry Andric // Now, in pratice, we should have a maximum of 2 branch 855*0b57cec5SDimitry Andric // instructions; one conditional and one unconditional. Therefore 856*0b57cec5SDimitry Andric // we know how to update the successor by looking at the target of 857*0b57cec5SDimitry Andric // the unconditional branch. 858*0b57cec5SDimitry Andric // If we end up splitting at some point, then, we should update 859*0b57cec5SDimitry Andric // the liveness information and such. I.e., we would need to 860*0b57cec5SDimitry Andric // access P here. 861*0b57cec5SDimitry Andric // The machine verifier should actually make sure such cases 862*0b57cec5SDimitry Andric // cannot happen. 863*0b57cec5SDimitry Andric llvm_unreachable("Not yet implemented"); 864*0b57cec5SDimitry Andric } 865*0b57cec5SDimitry Andric // Otherwise the insertion point is just the current or next 866*0b57cec5SDimitry Andric // instruction depending on Before. I.e., there is nothing to do 867*0b57cec5SDimitry Andric // here. 868*0b57cec5SDimitry Andric } 869*0b57cec5SDimitry Andric 870*0b57cec5SDimitry Andric bool RegBankSelect::InstrInsertPoint::isSplit() const { 871*0b57cec5SDimitry Andric // If the insertion point is after a terminator, we need to split. 872*0b57cec5SDimitry Andric if (!Before) 873*0b57cec5SDimitry Andric return Instr.isTerminator(); 874*0b57cec5SDimitry Andric // If we insert before an instruction that is after a terminator, 875*0b57cec5SDimitry Andric // we are still after a terminator. 876*0b57cec5SDimitry Andric return Instr.getPrevNode() && Instr.getPrevNode()->isTerminator(); 877*0b57cec5SDimitry Andric } 878*0b57cec5SDimitry Andric 879*0b57cec5SDimitry Andric uint64_t RegBankSelect::InstrInsertPoint::frequency(const Pass &P) const { 880*0b57cec5SDimitry Andric // Even if we need to split, because we insert between terminators, 881*0b57cec5SDimitry Andric // this split has actually the same frequency as the instruction. 882*0b57cec5SDimitry Andric const MachineBlockFrequencyInfo *MBFI = 883*0b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBlockFrequencyInfo>(); 884*0b57cec5SDimitry Andric if (!MBFI) 885*0b57cec5SDimitry Andric return 1; 886*0b57cec5SDimitry Andric return MBFI->getBlockFreq(Instr.getParent()).getFrequency(); 887*0b57cec5SDimitry Andric } 888*0b57cec5SDimitry Andric 889*0b57cec5SDimitry Andric uint64_t RegBankSelect::MBBInsertPoint::frequency(const Pass &P) const { 890*0b57cec5SDimitry Andric const MachineBlockFrequencyInfo *MBFI = 891*0b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBlockFrequencyInfo>(); 892*0b57cec5SDimitry Andric if (!MBFI) 893*0b57cec5SDimitry Andric return 1; 894*0b57cec5SDimitry Andric return MBFI->getBlockFreq(&MBB).getFrequency(); 895*0b57cec5SDimitry Andric } 896*0b57cec5SDimitry Andric 897*0b57cec5SDimitry Andric void RegBankSelect::EdgeInsertPoint::materialize() { 898*0b57cec5SDimitry Andric // If we end up repairing twice at the same place before materializing the 899*0b57cec5SDimitry Andric // insertion point, we may think we have to split an edge twice. 900*0b57cec5SDimitry Andric // We should have a factory for the insert point such that identical points 901*0b57cec5SDimitry Andric // are the same instance. 902*0b57cec5SDimitry Andric assert(Src.isSuccessor(DstOrSplit) && DstOrSplit->isPredecessor(&Src) && 903*0b57cec5SDimitry Andric "This point has already been split"); 904*0b57cec5SDimitry Andric MachineBasicBlock *NewBB = Src.SplitCriticalEdge(DstOrSplit, P); 905*0b57cec5SDimitry Andric assert(NewBB && "Invalid call to materialize"); 906*0b57cec5SDimitry Andric // We reuse the destination block to hold the information of the new block. 907*0b57cec5SDimitry Andric DstOrSplit = NewBB; 908*0b57cec5SDimitry Andric } 909*0b57cec5SDimitry Andric 910*0b57cec5SDimitry Andric uint64_t RegBankSelect::EdgeInsertPoint::frequency(const Pass &P) const { 911*0b57cec5SDimitry Andric const MachineBlockFrequencyInfo *MBFI = 912*0b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBlockFrequencyInfo>(); 913*0b57cec5SDimitry Andric if (!MBFI) 914*0b57cec5SDimitry Andric return 1; 915*0b57cec5SDimitry Andric if (WasMaterialized) 916*0b57cec5SDimitry Andric return MBFI->getBlockFreq(DstOrSplit).getFrequency(); 917*0b57cec5SDimitry Andric 918*0b57cec5SDimitry Andric const MachineBranchProbabilityInfo *MBPI = 919*0b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBranchProbabilityInfo>(); 920*0b57cec5SDimitry Andric if (!MBPI) 921*0b57cec5SDimitry Andric return 1; 922*0b57cec5SDimitry Andric // The basic block will be on the edge. 923*0b57cec5SDimitry Andric return (MBFI->getBlockFreq(&Src) * MBPI->getEdgeProbability(&Src, DstOrSplit)) 924*0b57cec5SDimitry Andric .getFrequency(); 925*0b57cec5SDimitry Andric } 926*0b57cec5SDimitry Andric 927*0b57cec5SDimitry Andric bool RegBankSelect::EdgeInsertPoint::canMaterialize() const { 928*0b57cec5SDimitry Andric // If this is not a critical edge, we should not have used this insert 929*0b57cec5SDimitry Andric // point. Indeed, either the successor or the predecessor should 930*0b57cec5SDimitry Andric // have do. 931*0b57cec5SDimitry Andric assert(Src.succ_size() > 1 && DstOrSplit->pred_size() > 1 && 932*0b57cec5SDimitry Andric "Edge is not critical"); 933*0b57cec5SDimitry Andric return Src.canSplitCriticalEdge(DstOrSplit); 934*0b57cec5SDimitry Andric } 935*0b57cec5SDimitry Andric 936*0b57cec5SDimitry Andric RegBankSelect::MappingCost::MappingCost(const BlockFrequency &LocalFreq) 937*0b57cec5SDimitry Andric : LocalFreq(LocalFreq.getFrequency()) {} 938*0b57cec5SDimitry Andric 939*0b57cec5SDimitry Andric bool RegBankSelect::MappingCost::addLocalCost(uint64_t Cost) { 940*0b57cec5SDimitry Andric // Check if this overflows. 941*0b57cec5SDimitry Andric if (LocalCost + Cost < LocalCost) { 942*0b57cec5SDimitry Andric saturate(); 943*0b57cec5SDimitry Andric return true; 944*0b57cec5SDimitry Andric } 945*0b57cec5SDimitry Andric LocalCost += Cost; 946*0b57cec5SDimitry Andric return isSaturated(); 947*0b57cec5SDimitry Andric } 948*0b57cec5SDimitry Andric 949*0b57cec5SDimitry Andric bool RegBankSelect::MappingCost::addNonLocalCost(uint64_t Cost) { 950*0b57cec5SDimitry Andric // Check if this overflows. 951*0b57cec5SDimitry Andric if (NonLocalCost + Cost < NonLocalCost) { 952*0b57cec5SDimitry Andric saturate(); 953*0b57cec5SDimitry Andric return true; 954*0b57cec5SDimitry Andric } 955*0b57cec5SDimitry Andric NonLocalCost += Cost; 956*0b57cec5SDimitry Andric return isSaturated(); 957*0b57cec5SDimitry Andric } 958*0b57cec5SDimitry Andric 959*0b57cec5SDimitry Andric bool RegBankSelect::MappingCost::isSaturated() const { 960*0b57cec5SDimitry Andric return LocalCost == UINT64_MAX - 1 && NonLocalCost == UINT64_MAX && 961*0b57cec5SDimitry Andric LocalFreq == UINT64_MAX; 962*0b57cec5SDimitry Andric } 963*0b57cec5SDimitry Andric 964*0b57cec5SDimitry Andric void RegBankSelect::MappingCost::saturate() { 965*0b57cec5SDimitry Andric *this = ImpossibleCost(); 966*0b57cec5SDimitry Andric --LocalCost; 967*0b57cec5SDimitry Andric } 968*0b57cec5SDimitry Andric 969*0b57cec5SDimitry Andric RegBankSelect::MappingCost RegBankSelect::MappingCost::ImpossibleCost() { 970*0b57cec5SDimitry Andric return MappingCost(UINT64_MAX, UINT64_MAX, UINT64_MAX); 971*0b57cec5SDimitry Andric } 972*0b57cec5SDimitry Andric 973*0b57cec5SDimitry Andric bool RegBankSelect::MappingCost::operator<(const MappingCost &Cost) const { 974*0b57cec5SDimitry Andric // Sort out the easy cases. 975*0b57cec5SDimitry Andric if (*this == Cost) 976*0b57cec5SDimitry Andric return false; 977*0b57cec5SDimitry Andric // If one is impossible to realize the other is cheaper unless it is 978*0b57cec5SDimitry Andric // impossible as well. 979*0b57cec5SDimitry Andric if ((*this == ImpossibleCost()) || (Cost == ImpossibleCost())) 980*0b57cec5SDimitry Andric return (*this == ImpossibleCost()) < (Cost == ImpossibleCost()); 981*0b57cec5SDimitry Andric // If one is saturated the other is cheaper, unless it is saturated 982*0b57cec5SDimitry Andric // as well. 983*0b57cec5SDimitry Andric if (isSaturated() || Cost.isSaturated()) 984*0b57cec5SDimitry Andric return isSaturated() < Cost.isSaturated(); 985*0b57cec5SDimitry Andric // At this point we know both costs hold sensible values. 986*0b57cec5SDimitry Andric 987*0b57cec5SDimitry Andric // If both values have a different base frequency, there is no much 988*0b57cec5SDimitry Andric // we can do but to scale everything. 989*0b57cec5SDimitry Andric // However, if they have the same base frequency we can avoid making 990*0b57cec5SDimitry Andric // complicated computation. 991*0b57cec5SDimitry Andric uint64_t ThisLocalAdjust; 992*0b57cec5SDimitry Andric uint64_t OtherLocalAdjust; 993*0b57cec5SDimitry Andric if (LLVM_LIKELY(LocalFreq == Cost.LocalFreq)) { 994*0b57cec5SDimitry Andric 995*0b57cec5SDimitry Andric // At this point, we know the local costs are comparable. 996*0b57cec5SDimitry Andric // Do the case that do not involve potential overflow first. 997*0b57cec5SDimitry Andric if (NonLocalCost == Cost.NonLocalCost) 998*0b57cec5SDimitry Andric // Since the non-local costs do not discriminate on the result, 999*0b57cec5SDimitry Andric // just compare the local costs. 1000*0b57cec5SDimitry Andric return LocalCost < Cost.LocalCost; 1001*0b57cec5SDimitry Andric 1002*0b57cec5SDimitry Andric // The base costs are comparable so we may only keep the relative 1003*0b57cec5SDimitry Andric // value to increase our chances of avoiding overflows. 1004*0b57cec5SDimitry Andric ThisLocalAdjust = 0; 1005*0b57cec5SDimitry Andric OtherLocalAdjust = 0; 1006*0b57cec5SDimitry Andric if (LocalCost < Cost.LocalCost) 1007*0b57cec5SDimitry Andric OtherLocalAdjust = Cost.LocalCost - LocalCost; 1008*0b57cec5SDimitry Andric else 1009*0b57cec5SDimitry Andric ThisLocalAdjust = LocalCost - Cost.LocalCost; 1010*0b57cec5SDimitry Andric } else { 1011*0b57cec5SDimitry Andric ThisLocalAdjust = LocalCost; 1012*0b57cec5SDimitry Andric OtherLocalAdjust = Cost.LocalCost; 1013*0b57cec5SDimitry Andric } 1014*0b57cec5SDimitry Andric 1015*0b57cec5SDimitry Andric // The non-local costs are comparable, just keep the relative value. 1016*0b57cec5SDimitry Andric uint64_t ThisNonLocalAdjust = 0; 1017*0b57cec5SDimitry Andric uint64_t OtherNonLocalAdjust = 0; 1018*0b57cec5SDimitry Andric if (NonLocalCost < Cost.NonLocalCost) 1019*0b57cec5SDimitry Andric OtherNonLocalAdjust = Cost.NonLocalCost - NonLocalCost; 1020*0b57cec5SDimitry Andric else 1021*0b57cec5SDimitry Andric ThisNonLocalAdjust = NonLocalCost - Cost.NonLocalCost; 1022*0b57cec5SDimitry Andric // Scale everything to make them comparable. 1023*0b57cec5SDimitry Andric uint64_t ThisScaledCost = ThisLocalAdjust * LocalFreq; 1024*0b57cec5SDimitry Andric // Check for overflow on that operation. 1025*0b57cec5SDimitry Andric bool ThisOverflows = ThisLocalAdjust && (ThisScaledCost < ThisLocalAdjust || 1026*0b57cec5SDimitry Andric ThisScaledCost < LocalFreq); 1027*0b57cec5SDimitry Andric uint64_t OtherScaledCost = OtherLocalAdjust * Cost.LocalFreq; 1028*0b57cec5SDimitry Andric // Check for overflow on the last operation. 1029*0b57cec5SDimitry Andric bool OtherOverflows = 1030*0b57cec5SDimitry Andric OtherLocalAdjust && 1031*0b57cec5SDimitry Andric (OtherScaledCost < OtherLocalAdjust || OtherScaledCost < Cost.LocalFreq); 1032*0b57cec5SDimitry Andric // Add the non-local costs. 1033*0b57cec5SDimitry Andric ThisOverflows |= ThisNonLocalAdjust && 1034*0b57cec5SDimitry Andric ThisScaledCost + ThisNonLocalAdjust < ThisNonLocalAdjust; 1035*0b57cec5SDimitry Andric ThisScaledCost += ThisNonLocalAdjust; 1036*0b57cec5SDimitry Andric OtherOverflows |= OtherNonLocalAdjust && 1037*0b57cec5SDimitry Andric OtherScaledCost + OtherNonLocalAdjust < OtherNonLocalAdjust; 1038*0b57cec5SDimitry Andric OtherScaledCost += OtherNonLocalAdjust; 1039*0b57cec5SDimitry Andric // If both overflows, we cannot compare without additional 1040*0b57cec5SDimitry Andric // precision, e.g., APInt. Just give up on that case. 1041*0b57cec5SDimitry Andric if (ThisOverflows && OtherOverflows) 1042*0b57cec5SDimitry Andric return false; 1043*0b57cec5SDimitry Andric // If one overflows but not the other, we can still compare. 1044*0b57cec5SDimitry Andric if (ThisOverflows || OtherOverflows) 1045*0b57cec5SDimitry Andric return ThisOverflows < OtherOverflows; 1046*0b57cec5SDimitry Andric // Otherwise, just compare the values. 1047*0b57cec5SDimitry Andric return ThisScaledCost < OtherScaledCost; 1048*0b57cec5SDimitry Andric } 1049*0b57cec5SDimitry Andric 1050*0b57cec5SDimitry Andric bool RegBankSelect::MappingCost::operator==(const MappingCost &Cost) const { 1051*0b57cec5SDimitry Andric return LocalCost == Cost.LocalCost && NonLocalCost == Cost.NonLocalCost && 1052*0b57cec5SDimitry Andric LocalFreq == Cost.LocalFreq; 1053*0b57cec5SDimitry Andric } 1054*0b57cec5SDimitry Andric 1055*0b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1056*0b57cec5SDimitry Andric LLVM_DUMP_METHOD void RegBankSelect::MappingCost::dump() const { 1057*0b57cec5SDimitry Andric print(dbgs()); 1058*0b57cec5SDimitry Andric dbgs() << '\n'; 1059*0b57cec5SDimitry Andric } 1060*0b57cec5SDimitry Andric #endif 1061*0b57cec5SDimitry Andric 1062*0b57cec5SDimitry Andric void RegBankSelect::MappingCost::print(raw_ostream &OS) const { 1063*0b57cec5SDimitry Andric if (*this == ImpossibleCost()) { 1064*0b57cec5SDimitry Andric OS << "impossible"; 1065*0b57cec5SDimitry Andric return; 1066*0b57cec5SDimitry Andric } 1067*0b57cec5SDimitry Andric if (isSaturated()) { 1068*0b57cec5SDimitry Andric OS << "saturated"; 1069*0b57cec5SDimitry Andric return; 1070*0b57cec5SDimitry Andric } 1071*0b57cec5SDimitry Andric OS << LocalFreq << " * " << LocalCost << " + " << NonLocalCost; 1072*0b57cec5SDimitry Andric } 1073