10b57cec5SDimitry Andric //==- llvm/CodeGen/GlobalISel/RegBankSelect.cpp - RegBankSelect --*- C++ -*-==// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// \file 90b57cec5SDimitry Andric /// This file implements the RegBankSelect class. 100b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" 130b57cec5SDimitry Andric #include "llvm/ADT/PostOrderIterator.h" 140b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 150b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 160b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/Utils.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 2681ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBank.h" 2781ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBankInfo.h" 280b57cec5SDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h" 290b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 300b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 310b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 320b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h" 330b57cec5SDimitry Andric #include "llvm/IR/Function.h" 34480093f4SDimitry Andric #include "llvm/InitializePasses.h" 350b57cec5SDimitry Andric #include "llvm/Pass.h" 360b57cec5SDimitry Andric #include "llvm/Support/BlockFrequency.h" 370b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 380b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 390b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 400b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 410b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 420b57cec5SDimitry Andric #include <algorithm> 430b57cec5SDimitry Andric #include <cassert> 440b57cec5SDimitry Andric #include <cstdint> 450b57cec5SDimitry Andric #include <limits> 460b57cec5SDimitry Andric #include <memory> 470b57cec5SDimitry Andric #include <utility> 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric #define DEBUG_TYPE "regbankselect" 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric using namespace llvm; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric static cl::opt<RegBankSelect::Mode> RegBankSelectMode( 540b57cec5SDimitry Andric cl::desc("Mode of the RegBankSelect pass"), cl::Hidden, cl::Optional, 550b57cec5SDimitry Andric cl::values(clEnumValN(RegBankSelect::Mode::Fast, "regbankselect-fast", 560b57cec5SDimitry Andric "Run the Fast mode (default mapping)"), 570b57cec5SDimitry Andric clEnumValN(RegBankSelect::Mode::Greedy, "regbankselect-greedy", 580b57cec5SDimitry Andric "Use the Greedy mode (best local mapping)"))); 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric char RegBankSelect::ID = 0; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(RegBankSelect, DEBUG_TYPE, 630b57cec5SDimitry Andric "Assign register bank of generic virtual registers", 640b57cec5SDimitry Andric false, false); 650b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo) 660b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) 670b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 680b57cec5SDimitry Andric INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, 690b57cec5SDimitry Andric "Assign register bank of generic virtual registers", false, 700b57cec5SDimitry Andric false) 710b57cec5SDimitry Andric 7206c3fb27SDimitry Andric RegBankSelect::RegBankSelect(char &PassID, Mode RunningMode) 7306c3fb27SDimitry Andric : MachineFunctionPass(PassID), OptMode(RunningMode) { 740b57cec5SDimitry Andric if (RegBankSelectMode.getNumOccurrences() != 0) { 750b57cec5SDimitry Andric OptMode = RegBankSelectMode; 760b57cec5SDimitry Andric if (RegBankSelectMode != RunningMode) 770b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "RegBankSelect mode overrided by command line\n"); 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric void RegBankSelect::init(MachineFunction &MF) { 820b57cec5SDimitry Andric RBI = MF.getSubtarget().getRegBankInfo(); 830b57cec5SDimitry Andric assert(RBI && "Cannot work without RegisterBankInfo"); 840b57cec5SDimitry Andric MRI = &MF.getRegInfo(); 850b57cec5SDimitry Andric TRI = MF.getSubtarget().getRegisterInfo(); 860b57cec5SDimitry Andric TPC = &getAnalysis<TargetPassConfig>(); 870b57cec5SDimitry Andric if (OptMode != Mode::Fast) { 880b57cec5SDimitry Andric MBFI = &getAnalysis<MachineBlockFrequencyInfo>(); 890b57cec5SDimitry Andric MBPI = &getAnalysis<MachineBranchProbabilityInfo>(); 900b57cec5SDimitry Andric } else { 910b57cec5SDimitry Andric MBFI = nullptr; 920b57cec5SDimitry Andric MBPI = nullptr; 930b57cec5SDimitry Andric } 940b57cec5SDimitry Andric MIRBuilder.setMF(MF); 958bcb0991SDimitry Andric MORE = std::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI); 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric void RegBankSelect::getAnalysisUsage(AnalysisUsage &AU) const { 990b57cec5SDimitry Andric if (OptMode != Mode::Fast) { 1000b57cec5SDimitry Andric // We could preserve the information from these two analysis but 1010b57cec5SDimitry Andric // the APIs do not allow to do so yet. 1020b57cec5SDimitry Andric AU.addRequired<MachineBlockFrequencyInfo>(); 1030b57cec5SDimitry Andric AU.addRequired<MachineBranchProbabilityInfo>(); 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric AU.addRequired<TargetPassConfig>(); 1060b57cec5SDimitry Andric getSelectionDAGFallbackAnalysisUsage(AU); 1070b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric bool RegBankSelect::assignmentMatch( 1110b57cec5SDimitry Andric Register Reg, const RegisterBankInfo::ValueMapping &ValMapping, 1120b57cec5SDimitry Andric bool &OnlyAssign) const { 1130b57cec5SDimitry Andric // By default we assume we will have to repair something. 1140b57cec5SDimitry Andric OnlyAssign = false; 1150b57cec5SDimitry Andric // Each part of a break down needs to end up in a different register. 1160b57cec5SDimitry Andric // In other word, Reg assignment does not match. 1170b57cec5SDimitry Andric if (ValMapping.NumBreakDowns != 1) 1180b57cec5SDimitry Andric return false; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric const RegisterBank *CurRegBank = RBI->getRegBank(Reg, *MRI, *TRI); 121480093f4SDimitry Andric const RegisterBank *DesiredRegBank = ValMapping.BreakDown[0].RegBank; 1220b57cec5SDimitry Andric // Reg is free of assignment, a simple assignment will make the 1230b57cec5SDimitry Andric // register bank to match. 1240b57cec5SDimitry Andric OnlyAssign = CurRegBank == nullptr; 1250b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Does assignment already match: "; 1260b57cec5SDimitry Andric if (CurRegBank) dbgs() << *CurRegBank; else dbgs() << "none"; 1270b57cec5SDimitry Andric dbgs() << " against "; 128480093f4SDimitry Andric assert(DesiredRegBank && "The mapping must be valid"); 129480093f4SDimitry Andric dbgs() << *DesiredRegBank << '\n';); 130480093f4SDimitry Andric return CurRegBank == DesiredRegBank; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric bool RegBankSelect::repairReg( 1340b57cec5SDimitry Andric MachineOperand &MO, const RegisterBankInfo::ValueMapping &ValMapping, 1350b57cec5SDimitry Andric RegBankSelect::RepairingPlacement &RepairPt, 1360b57cec5SDimitry Andric const iterator_range<SmallVectorImpl<Register>::const_iterator> &NewVRegs) { 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric assert(ValMapping.NumBreakDowns == (unsigned)size(NewVRegs) && 1390b57cec5SDimitry Andric "need new vreg for each breakdown"); 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric // An empty range of new register means no repairing. 1428bcb0991SDimitry Andric assert(!NewVRegs.empty() && "We should not have to repair"); 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric MachineInstr *MI; 1450b57cec5SDimitry Andric if (ValMapping.NumBreakDowns == 1) { 1460b57cec5SDimitry Andric // Assume we are repairing a use and thus, the original reg will be 1470b57cec5SDimitry Andric // the source of the repairing. 1480b57cec5SDimitry Andric Register Src = MO.getReg(); 1490b57cec5SDimitry Andric Register Dst = *NewVRegs.begin(); 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric // If we repair a definition, swap the source and destination for 1520b57cec5SDimitry Andric // the repairing. 1530b57cec5SDimitry Andric if (MO.isDef()) 1540b57cec5SDimitry Andric std::swap(Src, Dst); 1550b57cec5SDimitry Andric 156bdd1243dSDimitry Andric assert((RepairPt.getNumInsertPoints() == 1 || Dst.isPhysical()) && 1570b57cec5SDimitry Andric "We are about to create several defs for Dst"); 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric // Build the instruction used to repair, then clone it at the right 1600b57cec5SDimitry Andric // places. Avoiding buildCopy bypasses the check that Src and Dst have the 1610b57cec5SDimitry Andric // same types because the type is a placeholder when this function is called. 1620b57cec5SDimitry Andric MI = MIRBuilder.buildInstrNoInsert(TargetOpcode::COPY) 1630b57cec5SDimitry Andric .addDef(Dst) 1640b57cec5SDimitry Andric .addUse(Src); 16506c3fb27SDimitry Andric LLVM_DEBUG(dbgs() << "Copy: " << printReg(Src) << ':' 16606c3fb27SDimitry Andric << printRegClassOrBank(Src, *MRI, TRI) 16706c3fb27SDimitry Andric << " to: " << printReg(Dst) << ':' 16806c3fb27SDimitry Andric << printRegClassOrBank(Dst, *MRI, TRI) << '\n'); 1690b57cec5SDimitry Andric } else { 1700b57cec5SDimitry Andric // TODO: Support with G_IMPLICIT_DEF + G_INSERT sequence or G_EXTRACT 1710b57cec5SDimitry Andric // sequence. 1720b57cec5SDimitry Andric assert(ValMapping.partsAllUniform() && "irregular breakdowns not supported"); 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric LLT RegTy = MRI->getType(MO.getReg()); 1750b57cec5SDimitry Andric if (MO.isDef()) { 1760b57cec5SDimitry Andric unsigned MergeOp; 1770b57cec5SDimitry Andric if (RegTy.isVector()) { 1780b57cec5SDimitry Andric if (ValMapping.NumBreakDowns == RegTy.getNumElements()) 1790b57cec5SDimitry Andric MergeOp = TargetOpcode::G_BUILD_VECTOR; 1800b57cec5SDimitry Andric else { 1810b57cec5SDimitry Andric assert( 1820b57cec5SDimitry Andric (ValMapping.BreakDown[0].Length * ValMapping.NumBreakDowns == 1830b57cec5SDimitry Andric RegTy.getSizeInBits()) && 1840b57cec5SDimitry Andric (ValMapping.BreakDown[0].Length % RegTy.getScalarSizeInBits() == 1850b57cec5SDimitry Andric 0) && 1860b57cec5SDimitry Andric "don't understand this value breakdown"); 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric MergeOp = TargetOpcode::G_CONCAT_VECTORS; 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric } else 1910b57cec5SDimitry Andric MergeOp = TargetOpcode::G_MERGE_VALUES; 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric auto MergeBuilder = 1940b57cec5SDimitry Andric MIRBuilder.buildInstrNoInsert(MergeOp) 1950b57cec5SDimitry Andric .addDef(MO.getReg()); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric for (Register SrcReg : NewVRegs) 1980b57cec5SDimitry Andric MergeBuilder.addUse(SrcReg); 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric MI = MergeBuilder; 2010b57cec5SDimitry Andric } else { 2020b57cec5SDimitry Andric MachineInstrBuilder UnMergeBuilder = 2030b57cec5SDimitry Andric MIRBuilder.buildInstrNoInsert(TargetOpcode::G_UNMERGE_VALUES); 2040b57cec5SDimitry Andric for (Register DefReg : NewVRegs) 2050b57cec5SDimitry Andric UnMergeBuilder.addDef(DefReg); 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric UnMergeBuilder.addUse(MO.getReg()); 2080b57cec5SDimitry Andric MI = UnMergeBuilder; 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric } 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric if (RepairPt.getNumInsertPoints() != 1) 2130b57cec5SDimitry Andric report_fatal_error("need testcase to support multiple insertion points"); 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric // TODO: 2160b57cec5SDimitry Andric // Check if MI is legal. if not, we need to legalize all the 2170b57cec5SDimitry Andric // instructions we are going to insert. 2180b57cec5SDimitry Andric std::unique_ptr<MachineInstr *[]> NewInstrs( 2190b57cec5SDimitry Andric new MachineInstr *[RepairPt.getNumInsertPoints()]); 2200b57cec5SDimitry Andric bool IsFirst = true; 2210b57cec5SDimitry Andric unsigned Idx = 0; 2220b57cec5SDimitry Andric for (const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) { 2230b57cec5SDimitry Andric MachineInstr *CurMI; 2240b57cec5SDimitry Andric if (IsFirst) 2250b57cec5SDimitry Andric CurMI = MI; 2260b57cec5SDimitry Andric else 2270b57cec5SDimitry Andric CurMI = MIRBuilder.getMF().CloneMachineInstr(MI); 2280b57cec5SDimitry Andric InsertPt->insert(*CurMI); 2290b57cec5SDimitry Andric NewInstrs[Idx++] = CurMI; 2300b57cec5SDimitry Andric IsFirst = false; 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric // TODO: 2330b57cec5SDimitry Andric // Legalize NewInstrs if need be. 2340b57cec5SDimitry Andric return true; 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric uint64_t RegBankSelect::getRepairCost( 2380b57cec5SDimitry Andric const MachineOperand &MO, 2390b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping) const { 2400b57cec5SDimitry Andric assert(MO.isReg() && "We should only repair register operand"); 2410b57cec5SDimitry Andric assert(ValMapping.NumBreakDowns && "Nothing to map??"); 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric bool IsSameNumOfValues = ValMapping.NumBreakDowns == 1; 2440b57cec5SDimitry Andric const RegisterBank *CurRegBank = RBI->getRegBank(MO.getReg(), *MRI, *TRI); 2450b57cec5SDimitry Andric // If MO does not have a register bank, we should have just been 2460b57cec5SDimitry Andric // able to set one unless we have to break the value down. 2470b57cec5SDimitry Andric assert(CurRegBank || MO.isDef()); 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric // Def: Val <- NewDefs 2500b57cec5SDimitry Andric // Same number of values: copy 2510b57cec5SDimitry Andric // Different number: Val = build_sequence Defs1, Defs2, ... 2520b57cec5SDimitry Andric // Use: NewSources <- Val. 2530b57cec5SDimitry Andric // Same number of values: copy. 2540b57cec5SDimitry Andric // Different number: Src1, Src2, ... = 2550b57cec5SDimitry Andric // extract_value Val, Src1Begin, Src1Len, Src2Begin, Src2Len, ... 2560b57cec5SDimitry Andric // We should remember that this value is available somewhere else to 2570b57cec5SDimitry Andric // coalesce the value. 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric if (ValMapping.NumBreakDowns != 1) 2600b57cec5SDimitry Andric return RBI->getBreakDownCost(ValMapping, CurRegBank); 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric if (IsSameNumOfValues) { 263480093f4SDimitry Andric const RegisterBank *DesiredRegBank = ValMapping.BreakDown[0].RegBank; 2640b57cec5SDimitry Andric // If we repair a definition, swap the source and destination for 2650b57cec5SDimitry Andric // the repairing. 2660b57cec5SDimitry Andric if (MO.isDef()) 267480093f4SDimitry Andric std::swap(CurRegBank, DesiredRegBank); 2680b57cec5SDimitry Andric // TODO: It may be possible to actually avoid the copy. 2690b57cec5SDimitry Andric // If we repair something where the source is defined by a copy 2700b57cec5SDimitry Andric // and the source of that copy is on the right bank, we can reuse 2710b57cec5SDimitry Andric // it for free. 2720b57cec5SDimitry Andric // E.g., 2730b57cec5SDimitry Andric // RegToRepair<BankA> = copy AlternativeSrc<BankB> 2740b57cec5SDimitry Andric // = op RegToRepair<BankA> 2750b57cec5SDimitry Andric // We can simply propagate AlternativeSrc instead of copying RegToRepair 2760b57cec5SDimitry Andric // into a new virtual register. 2770b57cec5SDimitry Andric // We would also need to propagate this information in the 2780b57cec5SDimitry Andric // repairing placement. 279480093f4SDimitry Andric unsigned Cost = RBI->copyCost(*DesiredRegBank, *CurRegBank, 2800b57cec5SDimitry Andric RBI->getSizeInBits(MO.getReg(), *MRI, *TRI)); 2810b57cec5SDimitry Andric // TODO: use a dedicated constant for ImpossibleCost. 2820b57cec5SDimitry Andric if (Cost != std::numeric_limits<unsigned>::max()) 2830b57cec5SDimitry Andric return Cost; 2840b57cec5SDimitry Andric // Return the legalization cost of that repairing. 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric return std::numeric_limits<unsigned>::max(); 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping( 2900b57cec5SDimitry Andric MachineInstr &MI, RegisterBankInfo::InstructionMappings &PossibleMappings, 2910b57cec5SDimitry Andric SmallVectorImpl<RepairingPlacement> &RepairPts) { 2920b57cec5SDimitry Andric assert(!PossibleMappings.empty() && 2930b57cec5SDimitry Andric "Do not know how to map this instruction"); 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping *BestMapping = nullptr; 2960b57cec5SDimitry Andric MappingCost Cost = MappingCost::ImpossibleCost(); 2970b57cec5SDimitry Andric SmallVector<RepairingPlacement, 4> LocalRepairPts; 2980b57cec5SDimitry Andric for (const RegisterBankInfo::InstructionMapping *CurMapping : 2990b57cec5SDimitry Andric PossibleMappings) { 3000b57cec5SDimitry Andric MappingCost CurCost = 3010b57cec5SDimitry Andric computeMapping(MI, *CurMapping, LocalRepairPts, &Cost); 3020b57cec5SDimitry Andric if (CurCost < Cost) { 3030b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "New best: " << CurCost << '\n'); 3040b57cec5SDimitry Andric Cost = CurCost; 3050b57cec5SDimitry Andric BestMapping = CurMapping; 3060b57cec5SDimitry Andric RepairPts.clear(); 3070b57cec5SDimitry Andric for (RepairingPlacement &RepairPt : LocalRepairPts) 3080b57cec5SDimitry Andric RepairPts.emplace_back(std::move(RepairPt)); 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric if (!BestMapping && !TPC->isGlobalISelAbortEnabled()) { 3120b57cec5SDimitry Andric // If none of the mapping worked that means they are all impossible. 3130b57cec5SDimitry Andric // Thus, pick the first one and set an impossible repairing point. 3140b57cec5SDimitry Andric // It will trigger the failed isel mode. 3150b57cec5SDimitry Andric BestMapping = *PossibleMappings.begin(); 3160b57cec5SDimitry Andric RepairPts.emplace_back( 3170b57cec5SDimitry Andric RepairingPlacement(MI, 0, *TRI, *this, RepairingPlacement::Impossible)); 3180b57cec5SDimitry Andric } else 3190b57cec5SDimitry Andric assert(BestMapping && "No suitable mapping for instruction"); 3200b57cec5SDimitry Andric return *BestMapping; 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric void RegBankSelect::tryAvoidingSplit( 3240b57cec5SDimitry Andric RegBankSelect::RepairingPlacement &RepairPt, const MachineOperand &MO, 3250b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping) const { 3260b57cec5SDimitry Andric const MachineInstr &MI = *MO.getParent(); 3270b57cec5SDimitry Andric assert(RepairPt.hasSplit() && "We should not have to adjust for split"); 3280b57cec5SDimitry Andric // Splitting should only occur for PHIs or between terminators, 3290b57cec5SDimitry Andric // because we only do local repairing. 3300b57cec5SDimitry Andric assert((MI.isPHI() || MI.isTerminator()) && "Why do we split?"); 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric assert(&MI.getOperand(RepairPt.getOpIdx()) == &MO && 3330b57cec5SDimitry Andric "Repairing placement does not match operand"); 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric // If we need splitting for phis, that means it is because we 3360b57cec5SDimitry Andric // could not find an insertion point before the terminators of 3370b57cec5SDimitry Andric // the predecessor block for this argument. In other words, 3380b57cec5SDimitry Andric // the input value is defined by one of the terminators. 3390b57cec5SDimitry Andric assert((!MI.isPHI() || !MO.isDef()) && "Need split for phi def?"); 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric // We split to repair the use of a phi or a terminator. 3420b57cec5SDimitry Andric if (!MO.isDef()) { 3430b57cec5SDimitry Andric if (MI.isTerminator()) { 3440b57cec5SDimitry Andric assert(&MI != &(*MI.getParent()->getFirstTerminator()) && 3450b57cec5SDimitry Andric "Need to split for the first terminator?!"); 3460b57cec5SDimitry Andric } else { 3470b57cec5SDimitry Andric // For the PHI case, the split may not be actually required. 3480b57cec5SDimitry Andric // In the copy case, a phi is already a copy on the incoming edge, 3490b57cec5SDimitry Andric // therefore there is no need to split. 3500b57cec5SDimitry Andric if (ValMapping.NumBreakDowns == 1) 3510b57cec5SDimitry Andric // This is a already a copy, there is nothing to do. 3520b57cec5SDimitry Andric RepairPt.switchTo(RepairingPlacement::RepairingKind::Reassign); 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric return; 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric // At this point, we need to repair a defintion of a terminator. 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric // Technically we need to fix the def of MI on all outgoing 3600b57cec5SDimitry Andric // edges of MI to keep the repairing local. In other words, we 3610b57cec5SDimitry Andric // will create several definitions of the same register. This 3620b57cec5SDimitry Andric // does not work for SSA unless that definition is a physical 3630b57cec5SDimitry Andric // register. 3640b57cec5SDimitry Andric // However, there are other cases where we can get away with 3650b57cec5SDimitry Andric // that while still keeping the repairing local. 3660b57cec5SDimitry Andric assert(MI.isTerminator() && MO.isDef() && 3670b57cec5SDimitry Andric "This code is for the def of a terminator"); 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric // Since we use RPO traversal, if we need to repair a definition 3700b57cec5SDimitry Andric // this means this definition could be: 3710b57cec5SDimitry Andric // 1. Used by PHIs (i.e., this VReg has been visited as part of the 3720b57cec5SDimitry Andric // uses of a phi.), or 3730b57cec5SDimitry Andric // 2. Part of a target specific instruction (i.e., the target applied 3740b57cec5SDimitry Andric // some register class constraints when creating the instruction.) 3750b57cec5SDimitry Andric // If the constraints come for #2, the target said that another mapping 3760b57cec5SDimitry Andric // is supported so we may just drop them. Indeed, if we do not change 3770b57cec5SDimitry Andric // the number of registers holding that value, the uses will get fixed 3780b57cec5SDimitry Andric // when we get to them. 3790b57cec5SDimitry Andric // Uses in PHIs may have already been proceeded though. 3800b57cec5SDimitry Andric // If the constraints come for #1, then, those are weak constraints and 3810b57cec5SDimitry Andric // no actual uses may rely on them. However, the problem remains mainly 3820b57cec5SDimitry Andric // the same as for #2. If the value stays in one register, we could 3830b57cec5SDimitry Andric // just switch the register bank of the definition, but we would need to 3840b57cec5SDimitry Andric // account for a repairing cost for each phi we silently change. 3850b57cec5SDimitry Andric // 3860b57cec5SDimitry Andric // In any case, if the value needs to be broken down into several 3870b57cec5SDimitry Andric // registers, the repairing is not local anymore as we need to patch 3880b57cec5SDimitry Andric // every uses to rebuild the value in just one register. 3890b57cec5SDimitry Andric // 3900b57cec5SDimitry Andric // To summarize: 3910b57cec5SDimitry Andric // - If the value is in a physical register, we can do the split and 3920b57cec5SDimitry Andric // fix locally. 3930b57cec5SDimitry Andric // Otherwise if the value is in a virtual register: 3940b57cec5SDimitry Andric // - If the value remains in one register, we do not have to split 3950b57cec5SDimitry Andric // just switching the register bank would do, but we need to account 3960b57cec5SDimitry Andric // in the repairing cost all the phi we changed. 3970b57cec5SDimitry Andric // - If the value spans several registers, then we cannot do a local 3980b57cec5SDimitry Andric // repairing. 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric // Check if this is a physical or virtual register. 4010b57cec5SDimitry Andric Register Reg = MO.getReg(); 402bdd1243dSDimitry Andric if (Reg.isPhysical()) { 4030b57cec5SDimitry Andric // We are going to split every outgoing edges. 4040b57cec5SDimitry Andric // Check that this is possible. 4050b57cec5SDimitry Andric // FIXME: The machine representation is currently broken 4060b57cec5SDimitry Andric // since it also several terminators in one basic block. 4070b57cec5SDimitry Andric // Because of that we would technically need a way to get 4080b57cec5SDimitry Andric // the targets of just one terminator to know which edges 4090b57cec5SDimitry Andric // we have to split. 4100b57cec5SDimitry Andric // Assert that we do not hit the ill-formed representation. 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric // If there are other terminators before that one, some of 4130b57cec5SDimitry Andric // the outgoing edges may not be dominated by this definition. 4140b57cec5SDimitry Andric assert(&MI == &(*MI.getParent()->getFirstTerminator()) && 4150b57cec5SDimitry Andric "Do not know which outgoing edges are relevant"); 4160b57cec5SDimitry Andric const MachineInstr *Next = MI.getNextNode(); 4170b57cec5SDimitry Andric assert((!Next || Next->isUnconditionalBranch()) && 4180b57cec5SDimitry Andric "Do not know where each terminator ends up"); 4190b57cec5SDimitry Andric if (Next) 4200b57cec5SDimitry Andric // If the next terminator uses Reg, this means we have 4210b57cec5SDimitry Andric // to split right after MI and thus we need a way to ask 4220b57cec5SDimitry Andric // which outgoing edges are affected. 4230b57cec5SDimitry Andric assert(!Next->readsRegister(Reg) && "Need to split between terminators"); 4240b57cec5SDimitry Andric // We will split all the edges and repair there. 4250b57cec5SDimitry Andric } else { 4260b57cec5SDimitry Andric // This is a virtual register defined by a terminator. 4270b57cec5SDimitry Andric if (ValMapping.NumBreakDowns == 1) { 4280b57cec5SDimitry Andric // There is nothing to repair, but we may actually lie on 4290b57cec5SDimitry Andric // the repairing cost because of the PHIs already proceeded 4300b57cec5SDimitry Andric // as already stated. 4310b57cec5SDimitry Andric // Though the code will be correct. 4320b57cec5SDimitry Andric assert(false && "Repairing cost may not be accurate"); 4330b57cec5SDimitry Andric } else { 4340b57cec5SDimitry Andric // We need to do non-local repairing. Basically, patch all 4350b57cec5SDimitry Andric // the uses (i.e., phis) that we already proceeded. 4360b57cec5SDimitry Andric // For now, just say this mapping is not possible. 4370b57cec5SDimitry Andric RepairPt.switchTo(RepairingPlacement::RepairingKind::Impossible); 4380b57cec5SDimitry Andric } 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric RegBankSelect::MappingCost RegBankSelect::computeMapping( 4430b57cec5SDimitry Andric MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, 4440b57cec5SDimitry Andric SmallVectorImpl<RepairingPlacement> &RepairPts, 4450b57cec5SDimitry Andric const RegBankSelect::MappingCost *BestCost) { 4460b57cec5SDimitry Andric assert((MBFI || !BestCost) && "Costs comparison require MBFI"); 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric if (!InstrMapping.isValid()) 4490b57cec5SDimitry Andric return MappingCost::ImpossibleCost(); 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric // If mapped with InstrMapping, MI will have the recorded cost. 452*5f757f3fSDimitry Andric MappingCost Cost(MBFI ? MBFI->getBlockFreq(MI.getParent()) 453*5f757f3fSDimitry Andric : BlockFrequency(1)); 4540b57cec5SDimitry Andric bool Saturated = Cost.addLocalCost(InstrMapping.getCost()); 4550b57cec5SDimitry Andric assert(!Saturated && "Possible mapping saturated the cost"); 4560b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Evaluating mapping cost for: " << MI); 4570b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "With: " << InstrMapping << '\n'); 4580b57cec5SDimitry Andric RepairPts.clear(); 4590b57cec5SDimitry Andric if (BestCost && Cost > *BestCost) { 4600b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Mapping is too expensive from the start\n"); 4610b57cec5SDimitry Andric return Cost; 4620b57cec5SDimitry Andric } 463bdd1243dSDimitry Andric const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric // Moreover, to realize this mapping, the register bank of each operand must 4660b57cec5SDimitry Andric // match this mapping. In other words, we may need to locally reassign the 4670b57cec5SDimitry Andric // register banks. Account for that repairing cost as well. 4680b57cec5SDimitry Andric // In this context, local means in the surrounding of MI. 4690b57cec5SDimitry Andric for (unsigned OpIdx = 0, EndOpIdx = InstrMapping.getNumOperands(); 4700b57cec5SDimitry Andric OpIdx != EndOpIdx; ++OpIdx) { 4710b57cec5SDimitry Andric const MachineOperand &MO = MI.getOperand(OpIdx); 4720b57cec5SDimitry Andric if (!MO.isReg()) 4730b57cec5SDimitry Andric continue; 4740b57cec5SDimitry Andric Register Reg = MO.getReg(); 4750b57cec5SDimitry Andric if (!Reg) 4760b57cec5SDimitry Andric continue; 477bdd1243dSDimitry Andric LLT Ty = MRI.getType(Reg); 478bdd1243dSDimitry Andric if (!Ty.isValid()) 479bdd1243dSDimitry Andric continue; 480bdd1243dSDimitry Andric 4810b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Opd" << OpIdx << '\n'); 4820b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping = 4830b57cec5SDimitry Andric InstrMapping.getOperandMapping(OpIdx); 4840b57cec5SDimitry Andric // If Reg is already properly mapped, this is free. 4850b57cec5SDimitry Andric bool Assign; 4860b57cec5SDimitry Andric if (assignmentMatch(Reg, ValMapping, Assign)) { 4870b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "=> is free (match).\n"); 4880b57cec5SDimitry Andric continue; 4890b57cec5SDimitry Andric } 4900b57cec5SDimitry Andric if (Assign) { 4910b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "=> is free (simple assignment).\n"); 4920b57cec5SDimitry Andric RepairPts.emplace_back(RepairingPlacement(MI, OpIdx, *TRI, *this, 4930b57cec5SDimitry Andric RepairingPlacement::Reassign)); 4940b57cec5SDimitry Andric continue; 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric // Find the insertion point for the repairing code. 4980b57cec5SDimitry Andric RepairPts.emplace_back( 4990b57cec5SDimitry Andric RepairingPlacement(MI, OpIdx, *TRI, *this, RepairingPlacement::Insert)); 5000b57cec5SDimitry Andric RepairingPlacement &RepairPt = RepairPts.back(); 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric // If we need to split a basic block to materialize this insertion point, 5030b57cec5SDimitry Andric // we may give a higher cost to this mapping. 5040b57cec5SDimitry Andric // Nevertheless, we may get away with the split, so try that first. 5050b57cec5SDimitry Andric if (RepairPt.hasSplit()) 5060b57cec5SDimitry Andric tryAvoidingSplit(RepairPt, MO, ValMapping); 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric // Check that the materialization of the repairing is possible. 5090b57cec5SDimitry Andric if (!RepairPt.canMaterialize()) { 5100b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Mapping involves impossible repairing\n"); 5110b57cec5SDimitry Andric return MappingCost::ImpossibleCost(); 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric // Account for the split cost and repair cost. 5150b57cec5SDimitry Andric // Unless the cost is already saturated or we do not care about the cost. 5160b57cec5SDimitry Andric if (!BestCost || Saturated) 5170b57cec5SDimitry Andric continue; 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric // To get accurate information we need MBFI and MBPI. 5200b57cec5SDimitry Andric // Thus, if we end up here this information should be here. 5210b57cec5SDimitry Andric assert(MBFI && MBPI && "Cost computation requires MBFI and MBPI"); 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric // FIXME: We will have to rework the repairing cost model. 5240b57cec5SDimitry Andric // The repairing cost depends on the register bank that MO has. 5250b57cec5SDimitry Andric // However, when we break down the value into different values, 5260b57cec5SDimitry Andric // MO may not have a register bank while still needing repairing. 5270b57cec5SDimitry Andric // For the fast mode, we don't compute the cost so that is fine, 5280b57cec5SDimitry Andric // but still for the repairing code, we will have to make a choice. 5290b57cec5SDimitry Andric // For the greedy mode, we should choose greedily what is the best 5300b57cec5SDimitry Andric // choice based on the next use of MO. 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric // Sums up the repairing cost of MO at each insertion point. 5330b57cec5SDimitry Andric uint64_t RepairCost = getRepairCost(MO, ValMapping); 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric // This is an impossible to repair cost. 5360b57cec5SDimitry Andric if (RepairCost == std::numeric_limits<unsigned>::max()) 5370b57cec5SDimitry Andric return MappingCost::ImpossibleCost(); 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric // Bias used for splitting: 5%. 5400b57cec5SDimitry Andric const uint64_t PercentageForBias = 5; 5410b57cec5SDimitry Andric uint64_t Bias = (RepairCost * PercentageForBias + 99) / 100; 5420b57cec5SDimitry Andric // We should not need more than a couple of instructions to repair 5430b57cec5SDimitry Andric // an assignment. In other words, the computation should not 5440b57cec5SDimitry Andric // overflow because the repairing cost is free of basic block 5450b57cec5SDimitry Andric // frequency. 5460b57cec5SDimitry Andric assert(((RepairCost < RepairCost * PercentageForBias) && 5470b57cec5SDimitry Andric (RepairCost * PercentageForBias < 5480b57cec5SDimitry Andric RepairCost * PercentageForBias + 99)) && 5490b57cec5SDimitry Andric "Repairing involves more than a billion of instructions?!"); 5500b57cec5SDimitry Andric for (const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) { 5510b57cec5SDimitry Andric assert(InsertPt->canMaterialize() && "We should not have made it here"); 5520b57cec5SDimitry Andric // We will applied some basic block frequency and those uses uint64_t. 5530b57cec5SDimitry Andric if (!InsertPt->isSplit()) 5540b57cec5SDimitry Andric Saturated = Cost.addLocalCost(RepairCost); 5550b57cec5SDimitry Andric else { 5560b57cec5SDimitry Andric uint64_t CostForInsertPt = RepairCost; 5570b57cec5SDimitry Andric // Again we shouldn't overflow here givent that 5580b57cec5SDimitry Andric // CostForInsertPt is frequency free at this point. 5590b57cec5SDimitry Andric assert(CostForInsertPt + Bias > CostForInsertPt && 5600b57cec5SDimitry Andric "Repairing + split bias overflows"); 5610b57cec5SDimitry Andric CostForInsertPt += Bias; 5620b57cec5SDimitry Andric uint64_t PtCost = InsertPt->frequency(*this) * CostForInsertPt; 5630b57cec5SDimitry Andric // Check if we just overflowed. 5640b57cec5SDimitry Andric if ((Saturated = PtCost < CostForInsertPt)) 5650b57cec5SDimitry Andric Cost.saturate(); 5660b57cec5SDimitry Andric else 5670b57cec5SDimitry Andric Saturated = Cost.addNonLocalCost(PtCost); 5680b57cec5SDimitry Andric } 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric // Stop looking into what it takes to repair, this is already 5710b57cec5SDimitry Andric // too expensive. 5720b57cec5SDimitry Andric if (BestCost && Cost > *BestCost) { 5730b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Mapping is too expensive, stop processing\n"); 5740b57cec5SDimitry Andric return Cost; 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric // No need to accumulate more cost information. 5780b57cec5SDimitry Andric // We need to still gather the repairing information though. 5790b57cec5SDimitry Andric if (Saturated) 5800b57cec5SDimitry Andric break; 5810b57cec5SDimitry Andric } 5820b57cec5SDimitry Andric } 5830b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Total cost is: " << Cost << "\n"); 5840b57cec5SDimitry Andric return Cost; 5850b57cec5SDimitry Andric } 5860b57cec5SDimitry Andric 5870b57cec5SDimitry Andric bool RegBankSelect::applyMapping( 5880b57cec5SDimitry Andric MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, 5890b57cec5SDimitry Andric SmallVectorImpl<RegBankSelect::RepairingPlacement> &RepairPts) { 5900b57cec5SDimitry Andric // OpdMapper will hold all the information needed for the rewriting. 5910b57cec5SDimitry Andric RegisterBankInfo::OperandsMapper OpdMapper(MI, InstrMapping, *MRI); 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric // First, place the repairing code. 5940b57cec5SDimitry Andric for (RepairingPlacement &RepairPt : RepairPts) { 5950b57cec5SDimitry Andric if (!RepairPt.canMaterialize() || 5960b57cec5SDimitry Andric RepairPt.getKind() == RepairingPlacement::Impossible) 5970b57cec5SDimitry Andric return false; 5980b57cec5SDimitry Andric assert(RepairPt.getKind() != RepairingPlacement::None && 5990b57cec5SDimitry Andric "This should not make its way in the list"); 6000b57cec5SDimitry Andric unsigned OpIdx = RepairPt.getOpIdx(); 6010b57cec5SDimitry Andric MachineOperand &MO = MI.getOperand(OpIdx); 6020b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping = 6030b57cec5SDimitry Andric InstrMapping.getOperandMapping(OpIdx); 6040b57cec5SDimitry Andric Register Reg = MO.getReg(); 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric switch (RepairPt.getKind()) { 6070b57cec5SDimitry Andric case RepairingPlacement::Reassign: 6080b57cec5SDimitry Andric assert(ValMapping.NumBreakDowns == 1 && 6090b57cec5SDimitry Andric "Reassignment should only be for simple mapping"); 6100b57cec5SDimitry Andric MRI->setRegBank(Reg, *ValMapping.BreakDown[0].RegBank); 6110b57cec5SDimitry Andric break; 6120b57cec5SDimitry Andric case RepairingPlacement::Insert: 613bdd1243dSDimitry Andric // Don't insert additional instruction for debug instruction. 614bdd1243dSDimitry Andric if (MI.isDebugInstr()) 615bdd1243dSDimitry Andric break; 6160b57cec5SDimitry Andric OpdMapper.createVRegs(OpIdx); 6170b57cec5SDimitry Andric if (!repairReg(MO, ValMapping, RepairPt, OpdMapper.getVRegs(OpIdx))) 6180b57cec5SDimitry Andric return false; 6190b57cec5SDimitry Andric break; 6200b57cec5SDimitry Andric default: 6210b57cec5SDimitry Andric llvm_unreachable("Other kind should not happen"); 6220b57cec5SDimitry Andric } 6230b57cec5SDimitry Andric } 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric // Second, rewrite the instruction. 6260b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Actual mapping of the operands: " << OpdMapper << '\n'); 627*5f757f3fSDimitry Andric RBI->applyMapping(MIRBuilder, OpdMapper); 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric return true; 6300b57cec5SDimitry Andric } 6310b57cec5SDimitry Andric 6320b57cec5SDimitry Andric bool RegBankSelect::assignInstr(MachineInstr &MI) { 6330b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Assign: " << MI); 634fe6060f1SDimitry Andric 635fe6060f1SDimitry Andric unsigned Opc = MI.getOpcode(); 636fe6060f1SDimitry Andric if (isPreISelGenericOptimizationHint(Opc)) { 637fe6060f1SDimitry Andric assert((Opc == TargetOpcode::G_ASSERT_ZEXT || 63804eeddc0SDimitry Andric Opc == TargetOpcode::G_ASSERT_SEXT || 63904eeddc0SDimitry Andric Opc == TargetOpcode::G_ASSERT_ALIGN) && 640fe6060f1SDimitry Andric "Unexpected hint opcode!"); 641fe6060f1SDimitry Andric // The only correct mapping for these is to always use the source register 642fe6060f1SDimitry Andric // bank. 64381ad6265SDimitry Andric const RegisterBank *RB = 64481ad6265SDimitry Andric RBI->getRegBank(MI.getOperand(1).getReg(), *MRI, *TRI); 645fe6060f1SDimitry Andric // We can assume every instruction above this one has a selected register 646fe6060f1SDimitry Andric // bank. 647fe6060f1SDimitry Andric assert(RB && "Expected source register to have a register bank?"); 648fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << "... Hint always uses source's register bank.\n"); 649fe6060f1SDimitry Andric MRI->setRegBank(MI.getOperand(0).getReg(), *RB); 650fe6060f1SDimitry Andric return true; 651fe6060f1SDimitry Andric } 652fe6060f1SDimitry Andric 6530b57cec5SDimitry Andric // Remember the repairing placement for all the operands. 6540b57cec5SDimitry Andric SmallVector<RepairingPlacement, 4> RepairPts; 6550b57cec5SDimitry Andric 6560b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping *BestMapping; 6570b57cec5SDimitry Andric if (OptMode == RegBankSelect::Mode::Fast) { 6580b57cec5SDimitry Andric BestMapping = &RBI->getInstrMapping(MI); 6590b57cec5SDimitry Andric MappingCost DefaultCost = computeMapping(MI, *BestMapping, RepairPts); 6600b57cec5SDimitry Andric (void)DefaultCost; 6610b57cec5SDimitry Andric if (DefaultCost == MappingCost::ImpossibleCost()) 6620b57cec5SDimitry Andric return false; 6630b57cec5SDimitry Andric } else { 6640b57cec5SDimitry Andric RegisterBankInfo::InstructionMappings PossibleMappings = 6650b57cec5SDimitry Andric RBI->getInstrPossibleMappings(MI); 6660b57cec5SDimitry Andric if (PossibleMappings.empty()) 6670b57cec5SDimitry Andric return false; 6680b57cec5SDimitry Andric BestMapping = &findBestMapping(MI, PossibleMappings, RepairPts); 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric // Make sure the mapping is valid for MI. 6710b57cec5SDimitry Andric assert(BestMapping->verify(MI) && "Invalid instruction mapping"); 6720b57cec5SDimitry Andric 6730b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Best Mapping: " << *BestMapping << '\n'); 6740b57cec5SDimitry Andric 6750b57cec5SDimitry Andric // After this call, MI may not be valid anymore. 6760b57cec5SDimitry Andric // Do not use it. 6770b57cec5SDimitry Andric return applyMapping(MI, *BestMapping, RepairPts); 6780b57cec5SDimitry Andric } 6790b57cec5SDimitry Andric 680bdd1243dSDimitry Andric bool RegBankSelect::assignRegisterBanks(MachineFunction &MF) { 6810b57cec5SDimitry Andric // Walk the function and assign register banks to all operands. 6820b57cec5SDimitry Andric // Use a RPOT to make sure all registers are assigned before we choose 6830b57cec5SDimitry Andric // the best mapping of the current instruction. 6840b57cec5SDimitry Andric ReversePostOrderTraversal<MachineFunction*> RPOT(&MF); 6850b57cec5SDimitry Andric for (MachineBasicBlock *MBB : RPOT) { 6860b57cec5SDimitry Andric // Set a sensible insertion point so that subsequent calls to 6870b57cec5SDimitry Andric // MIRBuilder. 6880b57cec5SDimitry Andric MIRBuilder.setMBB(*MBB); 689349cc55cSDimitry Andric SmallVector<MachineInstr *> WorkList( 690349cc55cSDimitry Andric make_pointer_range(reverse(MBB->instrs()))); 691349cc55cSDimitry Andric 692349cc55cSDimitry Andric while (!WorkList.empty()) { 693349cc55cSDimitry Andric MachineInstr &MI = *WorkList.pop_back_val(); 6940b57cec5SDimitry Andric 6958bcb0991SDimitry Andric // Ignore target-specific post-isel instructions: they should use proper 6968bcb0991SDimitry Andric // regclasses. 6978bcb0991SDimitry Andric if (isTargetSpecificOpcode(MI.getOpcode()) && !MI.isPreISelOpcode()) 6980b57cec5SDimitry Andric continue; 6990b57cec5SDimitry Andric 7005ffd83dbSDimitry Andric // Ignore inline asm instructions: they should use physical 7015ffd83dbSDimitry Andric // registers/regclasses 7025ffd83dbSDimitry Andric if (MI.isInlineAsm()) 7035ffd83dbSDimitry Andric continue; 7045ffd83dbSDimitry Andric 705fe6060f1SDimitry Andric // Ignore IMPLICIT_DEF which must have a regclass. 706fe6060f1SDimitry Andric if (MI.isImplicitDef()) 707fe6060f1SDimitry Andric continue; 708fe6060f1SDimitry Andric 7090b57cec5SDimitry Andric if (!assignInstr(MI)) { 7100b57cec5SDimitry Andric reportGISelFailure(MF, *TPC, *MORE, "gisel-regbankselect", 7110b57cec5SDimitry Andric "unable to map instruction", MI); 7120b57cec5SDimitry Andric return false; 7130b57cec5SDimitry Andric } 7140b57cec5SDimitry Andric } 7150b57cec5SDimitry Andric } 7160b57cec5SDimitry Andric 717bdd1243dSDimitry Andric return true; 718bdd1243dSDimitry Andric } 719bdd1243dSDimitry Andric 720bdd1243dSDimitry Andric bool RegBankSelect::checkFunctionIsLegal(MachineFunction &MF) const { 721bdd1243dSDimitry Andric #ifndef NDEBUG 722bdd1243dSDimitry Andric if (!DisableGISelLegalityCheck) { 723bdd1243dSDimitry Andric if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) { 724bdd1243dSDimitry Andric reportGISelFailure(MF, *TPC, *MORE, "gisel-regbankselect", 725bdd1243dSDimitry Andric "instruction is not legal", *MI); 726bdd1243dSDimitry Andric return false; 727bdd1243dSDimitry Andric } 728bdd1243dSDimitry Andric } 729bdd1243dSDimitry Andric #endif 730bdd1243dSDimitry Andric return true; 731bdd1243dSDimitry Andric } 732bdd1243dSDimitry Andric 733bdd1243dSDimitry Andric bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) { 734bdd1243dSDimitry Andric // If the ISel pipeline failed, do not bother running that pass. 735bdd1243dSDimitry Andric if (MF.getProperties().hasProperty( 736bdd1243dSDimitry Andric MachineFunctionProperties::Property::FailedISel)) 737bdd1243dSDimitry Andric return false; 738bdd1243dSDimitry Andric 739bdd1243dSDimitry Andric LLVM_DEBUG(dbgs() << "Assign register banks for: " << MF.getName() << '\n'); 740bdd1243dSDimitry Andric const Function &F = MF.getFunction(); 741bdd1243dSDimitry Andric Mode SaveOptMode = OptMode; 742bdd1243dSDimitry Andric if (F.hasOptNone()) 743bdd1243dSDimitry Andric OptMode = Mode::Fast; 744bdd1243dSDimitry Andric init(MF); 745bdd1243dSDimitry Andric 746bdd1243dSDimitry Andric #ifndef NDEBUG 747bdd1243dSDimitry Andric if (!checkFunctionIsLegal(MF)) 748bdd1243dSDimitry Andric return false; 749bdd1243dSDimitry Andric #endif 750bdd1243dSDimitry Andric 751bdd1243dSDimitry Andric assignRegisterBanks(MF); 752bdd1243dSDimitry Andric 7530b57cec5SDimitry Andric OptMode = SaveOptMode; 7540b57cec5SDimitry Andric return false; 7550b57cec5SDimitry Andric } 7560b57cec5SDimitry Andric 7570b57cec5SDimitry Andric //------------------------------------------------------------------------------ 7580b57cec5SDimitry Andric // Helper Classes Implementation 7590b57cec5SDimitry Andric //------------------------------------------------------------------------------ 7600b57cec5SDimitry Andric RegBankSelect::RepairingPlacement::RepairingPlacement( 7610b57cec5SDimitry Andric MachineInstr &MI, unsigned OpIdx, const TargetRegisterInfo &TRI, Pass &P, 7620b57cec5SDimitry Andric RepairingPlacement::RepairingKind Kind) 7630b57cec5SDimitry Andric // Default is, we are going to insert code to repair OpIdx. 7640b57cec5SDimitry Andric : Kind(Kind), OpIdx(OpIdx), 7650b57cec5SDimitry Andric CanMaterialize(Kind != RepairingKind::Impossible), P(P) { 7660b57cec5SDimitry Andric const MachineOperand &MO = MI.getOperand(OpIdx); 7670b57cec5SDimitry Andric assert(MO.isReg() && "Trying to repair a non-reg operand"); 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric if (Kind != RepairingKind::Insert) 7700b57cec5SDimitry Andric return; 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andric // Repairings for definitions happen after MI, uses happen before. 7730b57cec5SDimitry Andric bool Before = !MO.isDef(); 7740b57cec5SDimitry Andric 7750b57cec5SDimitry Andric // Check if we are done with MI. 7760b57cec5SDimitry Andric if (!MI.isPHI() && !MI.isTerminator()) { 7770b57cec5SDimitry Andric addInsertPoint(MI, Before); 7780b57cec5SDimitry Andric // We are done with the initialization. 7790b57cec5SDimitry Andric return; 7800b57cec5SDimitry Andric } 7810b57cec5SDimitry Andric 7820b57cec5SDimitry Andric // Now, look for the special cases. 7830b57cec5SDimitry Andric if (MI.isPHI()) { 7840b57cec5SDimitry Andric // - PHI must be the first instructions: 7850b57cec5SDimitry Andric // * Before, we have to split the related incoming edge. 7860b57cec5SDimitry Andric // * After, move the insertion point past the last phi. 7870b57cec5SDimitry Andric if (!Before) { 7880b57cec5SDimitry Andric MachineBasicBlock::iterator It = MI.getParent()->getFirstNonPHI(); 7890b57cec5SDimitry Andric if (It != MI.getParent()->end()) 7900b57cec5SDimitry Andric addInsertPoint(*It, /*Before*/ true); 7910b57cec5SDimitry Andric else 7920b57cec5SDimitry Andric addInsertPoint(*(--It), /*Before*/ false); 7930b57cec5SDimitry Andric return; 7940b57cec5SDimitry Andric } 7950b57cec5SDimitry Andric // We repair a use of a phi, we may need to split the related edge. 7960b57cec5SDimitry Andric MachineBasicBlock &Pred = *MI.getOperand(OpIdx + 1).getMBB(); 7970b57cec5SDimitry Andric // Check if we can move the insertion point prior to the 7980b57cec5SDimitry Andric // terminators of the predecessor. 7990b57cec5SDimitry Andric Register Reg = MO.getReg(); 8000b57cec5SDimitry Andric MachineBasicBlock::iterator It = Pred.getLastNonDebugInstr(); 8010b57cec5SDimitry Andric for (auto Begin = Pred.begin(); It != Begin && It->isTerminator(); --It) 8020b57cec5SDimitry Andric if (It->modifiesRegister(Reg, &TRI)) { 8030b57cec5SDimitry Andric // We cannot hoist the repairing code in the predecessor. 8040b57cec5SDimitry Andric // Split the edge. 8050b57cec5SDimitry Andric addInsertPoint(Pred, *MI.getParent()); 8060b57cec5SDimitry Andric return; 8070b57cec5SDimitry Andric } 8080b57cec5SDimitry Andric // At this point, we can insert in Pred. 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andric // - If It is invalid, Pred is empty and we can insert in Pred 8110b57cec5SDimitry Andric // wherever we want. 8120b57cec5SDimitry Andric // - If It is valid, It is the first non-terminator, insert after It. 8130b57cec5SDimitry Andric if (It == Pred.end()) 8140b57cec5SDimitry Andric addInsertPoint(Pred, /*Beginning*/ false); 8150b57cec5SDimitry Andric else 8160b57cec5SDimitry Andric addInsertPoint(*It, /*Before*/ false); 8170b57cec5SDimitry Andric } else { 8180b57cec5SDimitry Andric // - Terminators must be the last instructions: 8190b57cec5SDimitry Andric // * Before, move the insert point before the first terminator. 8200b57cec5SDimitry Andric // * After, we have to split the outcoming edges. 8210b57cec5SDimitry Andric if (Before) { 8220b57cec5SDimitry Andric // Check whether Reg is defined by any terminator. 8230b57cec5SDimitry Andric MachineBasicBlock::reverse_iterator It = MI; 8240b57cec5SDimitry Andric auto REnd = MI.getParent()->rend(); 8250b57cec5SDimitry Andric 8260b57cec5SDimitry Andric for (; It != REnd && It->isTerminator(); ++It) { 8270b57cec5SDimitry Andric assert(!It->modifiesRegister(MO.getReg(), &TRI) && 8280b57cec5SDimitry Andric "copy insertion in middle of terminators not handled"); 8290b57cec5SDimitry Andric } 8300b57cec5SDimitry Andric 8310b57cec5SDimitry Andric if (It == REnd) { 8320b57cec5SDimitry Andric addInsertPoint(*MI.getParent()->begin(), true); 8330b57cec5SDimitry Andric return; 8340b57cec5SDimitry Andric } 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric // We are sure to be right before the first terminator. 8370b57cec5SDimitry Andric addInsertPoint(*It, /*Before*/ false); 8380b57cec5SDimitry Andric return; 8390b57cec5SDimitry Andric } 8400b57cec5SDimitry Andric // Make sure Reg is not redefined by other terminators, otherwise 8410b57cec5SDimitry Andric // we do not know how to split. 8420b57cec5SDimitry Andric for (MachineBasicBlock::iterator It = MI, End = MI.getParent()->end(); 8430b57cec5SDimitry Andric ++It != End;) 8440b57cec5SDimitry Andric // The machine verifier should reject this kind of code. 8450b57cec5SDimitry Andric assert(It->modifiesRegister(MO.getReg(), &TRI) && 8460b57cec5SDimitry Andric "Do not know where to split"); 8470b57cec5SDimitry Andric // Split each outcoming edges. 8480b57cec5SDimitry Andric MachineBasicBlock &Src = *MI.getParent(); 8490b57cec5SDimitry Andric for (auto &Succ : Src.successors()) 8500b57cec5SDimitry Andric addInsertPoint(Src, Succ); 8510b57cec5SDimitry Andric } 8520b57cec5SDimitry Andric } 8530b57cec5SDimitry Andric 8540b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint(MachineInstr &MI, 8550b57cec5SDimitry Andric bool Before) { 8560b57cec5SDimitry Andric addInsertPoint(*new InstrInsertPoint(MI, Before)); 8570b57cec5SDimitry Andric } 8580b57cec5SDimitry Andric 8590b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint(MachineBasicBlock &MBB, 8600b57cec5SDimitry Andric bool Beginning) { 8610b57cec5SDimitry Andric addInsertPoint(*new MBBInsertPoint(MBB, Beginning)); 8620b57cec5SDimitry Andric } 8630b57cec5SDimitry Andric 8640b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint(MachineBasicBlock &Src, 8650b57cec5SDimitry Andric MachineBasicBlock &Dst) { 8660b57cec5SDimitry Andric addInsertPoint(*new EdgeInsertPoint(Src, Dst, P)); 8670b57cec5SDimitry Andric } 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint( 8700b57cec5SDimitry Andric RegBankSelect::InsertPoint &Point) { 8710b57cec5SDimitry Andric CanMaterialize &= Point.canMaterialize(); 8720b57cec5SDimitry Andric HasSplit |= Point.isSplit(); 8730b57cec5SDimitry Andric InsertPoints.emplace_back(&Point); 8740b57cec5SDimitry Andric } 8750b57cec5SDimitry Andric 8760b57cec5SDimitry Andric RegBankSelect::InstrInsertPoint::InstrInsertPoint(MachineInstr &Instr, 8770b57cec5SDimitry Andric bool Before) 87804eeddc0SDimitry Andric : Instr(Instr), Before(Before) { 8790b57cec5SDimitry Andric // Since we do not support splitting, we do not need to update 8800b57cec5SDimitry Andric // liveness and such, so do not do anything with P. 8810b57cec5SDimitry Andric assert((!Before || !Instr.isPHI()) && 8820b57cec5SDimitry Andric "Splitting before phis requires more points"); 8830b57cec5SDimitry Andric assert((!Before || !Instr.getNextNode() || !Instr.getNextNode()->isPHI()) && 8840b57cec5SDimitry Andric "Splitting between phis does not make sense"); 8850b57cec5SDimitry Andric } 8860b57cec5SDimitry Andric 8870b57cec5SDimitry Andric void RegBankSelect::InstrInsertPoint::materialize() { 8880b57cec5SDimitry Andric if (isSplit()) { 8890b57cec5SDimitry Andric // Slice and return the beginning of the new block. 8900b57cec5SDimitry Andric // If we need to split between the terminators, we theoritically 8910b57cec5SDimitry Andric // need to know where the first and second set of terminators end 8920b57cec5SDimitry Andric // to update the successors properly. 8930b57cec5SDimitry Andric // Now, in pratice, we should have a maximum of 2 branch 8940b57cec5SDimitry Andric // instructions; one conditional and one unconditional. Therefore 8950b57cec5SDimitry Andric // we know how to update the successor by looking at the target of 8960b57cec5SDimitry Andric // the unconditional branch. 8970b57cec5SDimitry Andric // If we end up splitting at some point, then, we should update 8980b57cec5SDimitry Andric // the liveness information and such. I.e., we would need to 8990b57cec5SDimitry Andric // access P here. 9000b57cec5SDimitry Andric // The machine verifier should actually make sure such cases 9010b57cec5SDimitry Andric // cannot happen. 9020b57cec5SDimitry Andric llvm_unreachable("Not yet implemented"); 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric // Otherwise the insertion point is just the current or next 9050b57cec5SDimitry Andric // instruction depending on Before. I.e., there is nothing to do 9060b57cec5SDimitry Andric // here. 9070b57cec5SDimitry Andric } 9080b57cec5SDimitry Andric 9090b57cec5SDimitry Andric bool RegBankSelect::InstrInsertPoint::isSplit() const { 9100b57cec5SDimitry Andric // If the insertion point is after a terminator, we need to split. 9110b57cec5SDimitry Andric if (!Before) 9120b57cec5SDimitry Andric return Instr.isTerminator(); 9130b57cec5SDimitry Andric // If we insert before an instruction that is after a terminator, 9140b57cec5SDimitry Andric // we are still after a terminator. 9150b57cec5SDimitry Andric return Instr.getPrevNode() && Instr.getPrevNode()->isTerminator(); 9160b57cec5SDimitry Andric } 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric uint64_t RegBankSelect::InstrInsertPoint::frequency(const Pass &P) const { 9190b57cec5SDimitry Andric // Even if we need to split, because we insert between terminators, 9200b57cec5SDimitry Andric // this split has actually the same frequency as the instruction. 9210b57cec5SDimitry Andric const MachineBlockFrequencyInfo *MBFI = 9220b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBlockFrequencyInfo>(); 9230b57cec5SDimitry Andric if (!MBFI) 9240b57cec5SDimitry Andric return 1; 9250b57cec5SDimitry Andric return MBFI->getBlockFreq(Instr.getParent()).getFrequency(); 9260b57cec5SDimitry Andric } 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric uint64_t RegBankSelect::MBBInsertPoint::frequency(const Pass &P) const { 9290b57cec5SDimitry Andric const MachineBlockFrequencyInfo *MBFI = 9300b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBlockFrequencyInfo>(); 9310b57cec5SDimitry Andric if (!MBFI) 9320b57cec5SDimitry Andric return 1; 9330b57cec5SDimitry Andric return MBFI->getBlockFreq(&MBB).getFrequency(); 9340b57cec5SDimitry Andric } 9350b57cec5SDimitry Andric 9360b57cec5SDimitry Andric void RegBankSelect::EdgeInsertPoint::materialize() { 9370b57cec5SDimitry Andric // If we end up repairing twice at the same place before materializing the 9380b57cec5SDimitry Andric // insertion point, we may think we have to split an edge twice. 9390b57cec5SDimitry Andric // We should have a factory for the insert point such that identical points 9400b57cec5SDimitry Andric // are the same instance. 9410b57cec5SDimitry Andric assert(Src.isSuccessor(DstOrSplit) && DstOrSplit->isPredecessor(&Src) && 9420b57cec5SDimitry Andric "This point has already been split"); 9430b57cec5SDimitry Andric MachineBasicBlock *NewBB = Src.SplitCriticalEdge(DstOrSplit, P); 9440b57cec5SDimitry Andric assert(NewBB && "Invalid call to materialize"); 9450b57cec5SDimitry Andric // We reuse the destination block to hold the information of the new block. 9460b57cec5SDimitry Andric DstOrSplit = NewBB; 9470b57cec5SDimitry Andric } 9480b57cec5SDimitry Andric 9490b57cec5SDimitry Andric uint64_t RegBankSelect::EdgeInsertPoint::frequency(const Pass &P) const { 9500b57cec5SDimitry Andric const MachineBlockFrequencyInfo *MBFI = 9510b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBlockFrequencyInfo>(); 9520b57cec5SDimitry Andric if (!MBFI) 9530b57cec5SDimitry Andric return 1; 9540b57cec5SDimitry Andric if (WasMaterialized) 9550b57cec5SDimitry Andric return MBFI->getBlockFreq(DstOrSplit).getFrequency(); 9560b57cec5SDimitry Andric 9570b57cec5SDimitry Andric const MachineBranchProbabilityInfo *MBPI = 9580b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBranchProbabilityInfo>(); 9590b57cec5SDimitry Andric if (!MBPI) 9600b57cec5SDimitry Andric return 1; 9610b57cec5SDimitry Andric // The basic block will be on the edge. 9620b57cec5SDimitry Andric return (MBFI->getBlockFreq(&Src) * MBPI->getEdgeProbability(&Src, DstOrSplit)) 9630b57cec5SDimitry Andric .getFrequency(); 9640b57cec5SDimitry Andric } 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric bool RegBankSelect::EdgeInsertPoint::canMaterialize() const { 9670b57cec5SDimitry Andric // If this is not a critical edge, we should not have used this insert 9680b57cec5SDimitry Andric // point. Indeed, either the successor or the predecessor should 9690b57cec5SDimitry Andric // have do. 9700b57cec5SDimitry Andric assert(Src.succ_size() > 1 && DstOrSplit->pred_size() > 1 && 9710b57cec5SDimitry Andric "Edge is not critical"); 9720b57cec5SDimitry Andric return Src.canSplitCriticalEdge(DstOrSplit); 9730b57cec5SDimitry Andric } 9740b57cec5SDimitry Andric 975*5f757f3fSDimitry Andric RegBankSelect::MappingCost::MappingCost(BlockFrequency LocalFreq) 9760b57cec5SDimitry Andric : LocalFreq(LocalFreq.getFrequency()) {} 9770b57cec5SDimitry Andric 9780b57cec5SDimitry Andric bool RegBankSelect::MappingCost::addLocalCost(uint64_t Cost) { 9790b57cec5SDimitry Andric // Check if this overflows. 9800b57cec5SDimitry Andric if (LocalCost + Cost < LocalCost) { 9810b57cec5SDimitry Andric saturate(); 9820b57cec5SDimitry Andric return true; 9830b57cec5SDimitry Andric } 9840b57cec5SDimitry Andric LocalCost += Cost; 9850b57cec5SDimitry Andric return isSaturated(); 9860b57cec5SDimitry Andric } 9870b57cec5SDimitry Andric 9880b57cec5SDimitry Andric bool RegBankSelect::MappingCost::addNonLocalCost(uint64_t Cost) { 9890b57cec5SDimitry Andric // Check if this overflows. 9900b57cec5SDimitry Andric if (NonLocalCost + Cost < NonLocalCost) { 9910b57cec5SDimitry Andric saturate(); 9920b57cec5SDimitry Andric return true; 9930b57cec5SDimitry Andric } 9940b57cec5SDimitry Andric NonLocalCost += Cost; 9950b57cec5SDimitry Andric return isSaturated(); 9960b57cec5SDimitry Andric } 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric bool RegBankSelect::MappingCost::isSaturated() const { 9990b57cec5SDimitry Andric return LocalCost == UINT64_MAX - 1 && NonLocalCost == UINT64_MAX && 10000b57cec5SDimitry Andric LocalFreq == UINT64_MAX; 10010b57cec5SDimitry Andric } 10020b57cec5SDimitry Andric 10030b57cec5SDimitry Andric void RegBankSelect::MappingCost::saturate() { 10040b57cec5SDimitry Andric *this = ImpossibleCost(); 10050b57cec5SDimitry Andric --LocalCost; 10060b57cec5SDimitry Andric } 10070b57cec5SDimitry Andric 10080b57cec5SDimitry Andric RegBankSelect::MappingCost RegBankSelect::MappingCost::ImpossibleCost() { 10090b57cec5SDimitry Andric return MappingCost(UINT64_MAX, UINT64_MAX, UINT64_MAX); 10100b57cec5SDimitry Andric } 10110b57cec5SDimitry Andric 10120b57cec5SDimitry Andric bool RegBankSelect::MappingCost::operator<(const MappingCost &Cost) const { 10130b57cec5SDimitry Andric // Sort out the easy cases. 10140b57cec5SDimitry Andric if (*this == Cost) 10150b57cec5SDimitry Andric return false; 10160b57cec5SDimitry Andric // If one is impossible to realize the other is cheaper unless it is 10170b57cec5SDimitry Andric // impossible as well. 10180b57cec5SDimitry Andric if ((*this == ImpossibleCost()) || (Cost == ImpossibleCost())) 10190b57cec5SDimitry Andric return (*this == ImpossibleCost()) < (Cost == ImpossibleCost()); 10200b57cec5SDimitry Andric // If one is saturated the other is cheaper, unless it is saturated 10210b57cec5SDimitry Andric // as well. 10220b57cec5SDimitry Andric if (isSaturated() || Cost.isSaturated()) 10230b57cec5SDimitry Andric return isSaturated() < Cost.isSaturated(); 10240b57cec5SDimitry Andric // At this point we know both costs hold sensible values. 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric // If both values have a different base frequency, there is no much 10270b57cec5SDimitry Andric // we can do but to scale everything. 10280b57cec5SDimitry Andric // However, if they have the same base frequency we can avoid making 10290b57cec5SDimitry Andric // complicated computation. 10300b57cec5SDimitry Andric uint64_t ThisLocalAdjust; 10310b57cec5SDimitry Andric uint64_t OtherLocalAdjust; 10320b57cec5SDimitry Andric if (LLVM_LIKELY(LocalFreq == Cost.LocalFreq)) { 10330b57cec5SDimitry Andric 10340b57cec5SDimitry Andric // At this point, we know the local costs are comparable. 10350b57cec5SDimitry Andric // Do the case that do not involve potential overflow first. 10360b57cec5SDimitry Andric if (NonLocalCost == Cost.NonLocalCost) 10370b57cec5SDimitry Andric // Since the non-local costs do not discriminate on the result, 10380b57cec5SDimitry Andric // just compare the local costs. 10390b57cec5SDimitry Andric return LocalCost < Cost.LocalCost; 10400b57cec5SDimitry Andric 10410b57cec5SDimitry Andric // The base costs are comparable so we may only keep the relative 10420b57cec5SDimitry Andric // value to increase our chances of avoiding overflows. 10430b57cec5SDimitry Andric ThisLocalAdjust = 0; 10440b57cec5SDimitry Andric OtherLocalAdjust = 0; 10450b57cec5SDimitry Andric if (LocalCost < Cost.LocalCost) 10460b57cec5SDimitry Andric OtherLocalAdjust = Cost.LocalCost - LocalCost; 10470b57cec5SDimitry Andric else 10480b57cec5SDimitry Andric ThisLocalAdjust = LocalCost - Cost.LocalCost; 10490b57cec5SDimitry Andric } else { 10500b57cec5SDimitry Andric ThisLocalAdjust = LocalCost; 10510b57cec5SDimitry Andric OtherLocalAdjust = Cost.LocalCost; 10520b57cec5SDimitry Andric } 10530b57cec5SDimitry Andric 10540b57cec5SDimitry Andric // The non-local costs are comparable, just keep the relative value. 10550b57cec5SDimitry Andric uint64_t ThisNonLocalAdjust = 0; 10560b57cec5SDimitry Andric uint64_t OtherNonLocalAdjust = 0; 10570b57cec5SDimitry Andric if (NonLocalCost < Cost.NonLocalCost) 10580b57cec5SDimitry Andric OtherNonLocalAdjust = Cost.NonLocalCost - NonLocalCost; 10590b57cec5SDimitry Andric else 10600b57cec5SDimitry Andric ThisNonLocalAdjust = NonLocalCost - Cost.NonLocalCost; 10610b57cec5SDimitry Andric // Scale everything to make them comparable. 10620b57cec5SDimitry Andric uint64_t ThisScaledCost = ThisLocalAdjust * LocalFreq; 10630b57cec5SDimitry Andric // Check for overflow on that operation. 10640b57cec5SDimitry Andric bool ThisOverflows = ThisLocalAdjust && (ThisScaledCost < ThisLocalAdjust || 10650b57cec5SDimitry Andric ThisScaledCost < LocalFreq); 10660b57cec5SDimitry Andric uint64_t OtherScaledCost = OtherLocalAdjust * Cost.LocalFreq; 10670b57cec5SDimitry Andric // Check for overflow on the last operation. 10680b57cec5SDimitry Andric bool OtherOverflows = 10690b57cec5SDimitry Andric OtherLocalAdjust && 10700b57cec5SDimitry Andric (OtherScaledCost < OtherLocalAdjust || OtherScaledCost < Cost.LocalFreq); 10710b57cec5SDimitry Andric // Add the non-local costs. 10720b57cec5SDimitry Andric ThisOverflows |= ThisNonLocalAdjust && 10730b57cec5SDimitry Andric ThisScaledCost + ThisNonLocalAdjust < ThisNonLocalAdjust; 10740b57cec5SDimitry Andric ThisScaledCost += ThisNonLocalAdjust; 10750b57cec5SDimitry Andric OtherOverflows |= OtherNonLocalAdjust && 10760b57cec5SDimitry Andric OtherScaledCost + OtherNonLocalAdjust < OtherNonLocalAdjust; 10770b57cec5SDimitry Andric OtherScaledCost += OtherNonLocalAdjust; 10780b57cec5SDimitry Andric // If both overflows, we cannot compare without additional 10790b57cec5SDimitry Andric // precision, e.g., APInt. Just give up on that case. 10800b57cec5SDimitry Andric if (ThisOverflows && OtherOverflows) 10810b57cec5SDimitry Andric return false; 10820b57cec5SDimitry Andric // If one overflows but not the other, we can still compare. 10830b57cec5SDimitry Andric if (ThisOverflows || OtherOverflows) 10840b57cec5SDimitry Andric return ThisOverflows < OtherOverflows; 10850b57cec5SDimitry Andric // Otherwise, just compare the values. 10860b57cec5SDimitry Andric return ThisScaledCost < OtherScaledCost; 10870b57cec5SDimitry Andric } 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andric bool RegBankSelect::MappingCost::operator==(const MappingCost &Cost) const { 10900b57cec5SDimitry Andric return LocalCost == Cost.LocalCost && NonLocalCost == Cost.NonLocalCost && 10910b57cec5SDimitry Andric LocalFreq == Cost.LocalFreq; 10920b57cec5SDimitry Andric } 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 10950b57cec5SDimitry Andric LLVM_DUMP_METHOD void RegBankSelect::MappingCost::dump() const { 10960b57cec5SDimitry Andric print(dbgs()); 10970b57cec5SDimitry Andric dbgs() << '\n'; 10980b57cec5SDimitry Andric } 10990b57cec5SDimitry Andric #endif 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andric void RegBankSelect::MappingCost::print(raw_ostream &OS) const { 11020b57cec5SDimitry Andric if (*this == ImpossibleCost()) { 11030b57cec5SDimitry Andric OS << "impossible"; 11040b57cec5SDimitry Andric return; 11050b57cec5SDimitry Andric } 11060b57cec5SDimitry Andric if (isSaturated()) { 11070b57cec5SDimitry Andric OS << "saturated"; 11080b57cec5SDimitry Andric return; 11090b57cec5SDimitry Andric } 11100b57cec5SDimitry Andric OS << LocalFreq << " * " << LocalCost << " + " << NonLocalCost; 11110b57cec5SDimitry Andric } 1112