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/RegisterBank.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/Utils.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.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/Attributes.h" 340b57cec5SDimitry Andric #include "llvm/IR/Function.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 720b57cec5SDimitry Andric RegBankSelect::RegBankSelect(Mode RunningMode) 730b57cec5SDimitry Andric : MachineFunctionPass(ID), 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); 95*8bcb0991SDimitry 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); 1210b57cec5SDimitry Andric const RegisterBank *DesiredRegBrank = 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 "; 1280b57cec5SDimitry Andric assert(DesiredRegBrank && "The mapping must be valid"); 1290b57cec5SDimitry Andric dbgs() << *DesiredRegBrank << '\n';); 1300b57cec5SDimitry Andric return CurRegBank == DesiredRegBrank; 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. 142*8bcb0991SDimitry 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 1560b57cec5SDimitry Andric assert((RepairPt.getNumInsertPoints() == 1 || 157*8bcb0991SDimitry Andric Register::isPhysicalRegister(Dst)) && 1580b57cec5SDimitry Andric "We are about to create several defs for Dst"); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric // Build the instruction used to repair, then clone it at the right 1610b57cec5SDimitry Andric // places. Avoiding buildCopy bypasses the check that Src and Dst have the 1620b57cec5SDimitry Andric // same types because the type is a placeholder when this function is called. 1630b57cec5SDimitry Andric MI = MIRBuilder.buildInstrNoInsert(TargetOpcode::COPY) 1640b57cec5SDimitry Andric .addDef(Dst) 1650b57cec5SDimitry Andric .addUse(Src); 1660b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Copy: " << printReg(Src) << " to: " << printReg(Dst) 1670b57cec5SDimitry Andric << '\n'); 1680b57cec5SDimitry Andric } else { 1690b57cec5SDimitry Andric // TODO: Support with G_IMPLICIT_DEF + G_INSERT sequence or G_EXTRACT 1700b57cec5SDimitry Andric // sequence. 1710b57cec5SDimitry Andric assert(ValMapping.partsAllUniform() && "irregular breakdowns not supported"); 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric LLT RegTy = MRI->getType(MO.getReg()); 1740b57cec5SDimitry Andric if (MO.isDef()) { 1750b57cec5SDimitry Andric unsigned MergeOp; 1760b57cec5SDimitry Andric if (RegTy.isVector()) { 1770b57cec5SDimitry Andric if (ValMapping.NumBreakDowns == RegTy.getNumElements()) 1780b57cec5SDimitry Andric MergeOp = TargetOpcode::G_BUILD_VECTOR; 1790b57cec5SDimitry Andric else { 1800b57cec5SDimitry Andric assert( 1810b57cec5SDimitry Andric (ValMapping.BreakDown[0].Length * ValMapping.NumBreakDowns == 1820b57cec5SDimitry Andric RegTy.getSizeInBits()) && 1830b57cec5SDimitry Andric (ValMapping.BreakDown[0].Length % RegTy.getScalarSizeInBits() == 1840b57cec5SDimitry Andric 0) && 1850b57cec5SDimitry Andric "don't understand this value breakdown"); 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric MergeOp = TargetOpcode::G_CONCAT_VECTORS; 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric } else 1900b57cec5SDimitry Andric MergeOp = TargetOpcode::G_MERGE_VALUES; 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric auto MergeBuilder = 1930b57cec5SDimitry Andric MIRBuilder.buildInstrNoInsert(MergeOp) 1940b57cec5SDimitry Andric .addDef(MO.getReg()); 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric for (Register SrcReg : NewVRegs) 1970b57cec5SDimitry Andric MergeBuilder.addUse(SrcReg); 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric MI = MergeBuilder; 2000b57cec5SDimitry Andric } else { 2010b57cec5SDimitry Andric MachineInstrBuilder UnMergeBuilder = 2020b57cec5SDimitry Andric MIRBuilder.buildInstrNoInsert(TargetOpcode::G_UNMERGE_VALUES); 2030b57cec5SDimitry Andric for (Register DefReg : NewVRegs) 2040b57cec5SDimitry Andric UnMergeBuilder.addDef(DefReg); 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric UnMergeBuilder.addUse(MO.getReg()); 2070b57cec5SDimitry Andric MI = UnMergeBuilder; 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric if (RepairPt.getNumInsertPoints() != 1) 2120b57cec5SDimitry Andric report_fatal_error("need testcase to support multiple insertion points"); 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric // TODO: 2150b57cec5SDimitry Andric // Check if MI is legal. if not, we need to legalize all the 2160b57cec5SDimitry Andric // instructions we are going to insert. 2170b57cec5SDimitry Andric std::unique_ptr<MachineInstr *[]> NewInstrs( 2180b57cec5SDimitry Andric new MachineInstr *[RepairPt.getNumInsertPoints()]); 2190b57cec5SDimitry Andric bool IsFirst = true; 2200b57cec5SDimitry Andric unsigned Idx = 0; 2210b57cec5SDimitry Andric for (const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) { 2220b57cec5SDimitry Andric MachineInstr *CurMI; 2230b57cec5SDimitry Andric if (IsFirst) 2240b57cec5SDimitry Andric CurMI = MI; 2250b57cec5SDimitry Andric else 2260b57cec5SDimitry Andric CurMI = MIRBuilder.getMF().CloneMachineInstr(MI); 2270b57cec5SDimitry Andric InsertPt->insert(*CurMI); 2280b57cec5SDimitry Andric NewInstrs[Idx++] = CurMI; 2290b57cec5SDimitry Andric IsFirst = false; 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric // TODO: 2320b57cec5SDimitry Andric // Legalize NewInstrs if need be. 2330b57cec5SDimitry Andric return true; 2340b57cec5SDimitry Andric } 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric uint64_t RegBankSelect::getRepairCost( 2370b57cec5SDimitry Andric const MachineOperand &MO, 2380b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping) const { 2390b57cec5SDimitry Andric assert(MO.isReg() && "We should only repair register operand"); 2400b57cec5SDimitry Andric assert(ValMapping.NumBreakDowns && "Nothing to map??"); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric bool IsSameNumOfValues = ValMapping.NumBreakDowns == 1; 2430b57cec5SDimitry Andric const RegisterBank *CurRegBank = RBI->getRegBank(MO.getReg(), *MRI, *TRI); 2440b57cec5SDimitry Andric // If MO does not have a register bank, we should have just been 2450b57cec5SDimitry Andric // able to set one unless we have to break the value down. 2460b57cec5SDimitry Andric assert(CurRegBank || MO.isDef()); 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric // Def: Val <- NewDefs 2490b57cec5SDimitry Andric // Same number of values: copy 2500b57cec5SDimitry Andric // Different number: Val = build_sequence Defs1, Defs2, ... 2510b57cec5SDimitry Andric // Use: NewSources <- Val. 2520b57cec5SDimitry Andric // Same number of values: copy. 2530b57cec5SDimitry Andric // Different number: Src1, Src2, ... = 2540b57cec5SDimitry Andric // extract_value Val, Src1Begin, Src1Len, Src2Begin, Src2Len, ... 2550b57cec5SDimitry Andric // We should remember that this value is available somewhere else to 2560b57cec5SDimitry Andric // coalesce the value. 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric if (ValMapping.NumBreakDowns != 1) 2590b57cec5SDimitry Andric return RBI->getBreakDownCost(ValMapping, CurRegBank); 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric if (IsSameNumOfValues) { 2620b57cec5SDimitry Andric const RegisterBank *DesiredRegBrank = ValMapping.BreakDown[0].RegBank; 2630b57cec5SDimitry Andric // If we repair a definition, swap the source and destination for 2640b57cec5SDimitry Andric // the repairing. 2650b57cec5SDimitry Andric if (MO.isDef()) 2660b57cec5SDimitry Andric std::swap(CurRegBank, DesiredRegBrank); 2670b57cec5SDimitry Andric // TODO: It may be possible to actually avoid the copy. 2680b57cec5SDimitry Andric // If we repair something where the source is defined by a copy 2690b57cec5SDimitry Andric // and the source of that copy is on the right bank, we can reuse 2700b57cec5SDimitry Andric // it for free. 2710b57cec5SDimitry Andric // E.g., 2720b57cec5SDimitry Andric // RegToRepair<BankA> = copy AlternativeSrc<BankB> 2730b57cec5SDimitry Andric // = op RegToRepair<BankA> 2740b57cec5SDimitry Andric // We can simply propagate AlternativeSrc instead of copying RegToRepair 2750b57cec5SDimitry Andric // into a new virtual register. 2760b57cec5SDimitry Andric // We would also need to propagate this information in the 2770b57cec5SDimitry Andric // repairing placement. 2780b57cec5SDimitry Andric unsigned Cost = RBI->copyCost(*DesiredRegBrank, *CurRegBank, 2790b57cec5SDimitry Andric RBI->getSizeInBits(MO.getReg(), *MRI, *TRI)); 2800b57cec5SDimitry Andric // TODO: use a dedicated constant for ImpossibleCost. 2810b57cec5SDimitry Andric if (Cost != std::numeric_limits<unsigned>::max()) 2820b57cec5SDimitry Andric return Cost; 2830b57cec5SDimitry Andric // Return the legalization cost of that repairing. 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric return std::numeric_limits<unsigned>::max(); 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping( 2890b57cec5SDimitry Andric MachineInstr &MI, RegisterBankInfo::InstructionMappings &PossibleMappings, 2900b57cec5SDimitry Andric SmallVectorImpl<RepairingPlacement> &RepairPts) { 2910b57cec5SDimitry Andric assert(!PossibleMappings.empty() && 2920b57cec5SDimitry Andric "Do not know how to map this instruction"); 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping *BestMapping = nullptr; 2950b57cec5SDimitry Andric MappingCost Cost = MappingCost::ImpossibleCost(); 2960b57cec5SDimitry Andric SmallVector<RepairingPlacement, 4> LocalRepairPts; 2970b57cec5SDimitry Andric for (const RegisterBankInfo::InstructionMapping *CurMapping : 2980b57cec5SDimitry Andric PossibleMappings) { 2990b57cec5SDimitry Andric MappingCost CurCost = 3000b57cec5SDimitry Andric computeMapping(MI, *CurMapping, LocalRepairPts, &Cost); 3010b57cec5SDimitry Andric if (CurCost < Cost) { 3020b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "New best: " << CurCost << '\n'); 3030b57cec5SDimitry Andric Cost = CurCost; 3040b57cec5SDimitry Andric BestMapping = CurMapping; 3050b57cec5SDimitry Andric RepairPts.clear(); 3060b57cec5SDimitry Andric for (RepairingPlacement &RepairPt : LocalRepairPts) 3070b57cec5SDimitry Andric RepairPts.emplace_back(std::move(RepairPt)); 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric if (!BestMapping && !TPC->isGlobalISelAbortEnabled()) { 3110b57cec5SDimitry Andric // If none of the mapping worked that means they are all impossible. 3120b57cec5SDimitry Andric // Thus, pick the first one and set an impossible repairing point. 3130b57cec5SDimitry Andric // It will trigger the failed isel mode. 3140b57cec5SDimitry Andric BestMapping = *PossibleMappings.begin(); 3150b57cec5SDimitry Andric RepairPts.emplace_back( 3160b57cec5SDimitry Andric RepairingPlacement(MI, 0, *TRI, *this, RepairingPlacement::Impossible)); 3170b57cec5SDimitry Andric } else 3180b57cec5SDimitry Andric assert(BestMapping && "No suitable mapping for instruction"); 3190b57cec5SDimitry Andric return *BestMapping; 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric void RegBankSelect::tryAvoidingSplit( 3230b57cec5SDimitry Andric RegBankSelect::RepairingPlacement &RepairPt, const MachineOperand &MO, 3240b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping) const { 3250b57cec5SDimitry Andric const MachineInstr &MI = *MO.getParent(); 3260b57cec5SDimitry Andric assert(RepairPt.hasSplit() && "We should not have to adjust for split"); 3270b57cec5SDimitry Andric // Splitting should only occur for PHIs or between terminators, 3280b57cec5SDimitry Andric // because we only do local repairing. 3290b57cec5SDimitry Andric assert((MI.isPHI() || MI.isTerminator()) && "Why do we split?"); 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric assert(&MI.getOperand(RepairPt.getOpIdx()) == &MO && 3320b57cec5SDimitry Andric "Repairing placement does not match operand"); 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric // If we need splitting for phis, that means it is because we 3350b57cec5SDimitry Andric // could not find an insertion point before the terminators of 3360b57cec5SDimitry Andric // the predecessor block for this argument. In other words, 3370b57cec5SDimitry Andric // the input value is defined by one of the terminators. 3380b57cec5SDimitry Andric assert((!MI.isPHI() || !MO.isDef()) && "Need split for phi def?"); 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric // We split to repair the use of a phi or a terminator. 3410b57cec5SDimitry Andric if (!MO.isDef()) { 3420b57cec5SDimitry Andric if (MI.isTerminator()) { 3430b57cec5SDimitry Andric assert(&MI != &(*MI.getParent()->getFirstTerminator()) && 3440b57cec5SDimitry Andric "Need to split for the first terminator?!"); 3450b57cec5SDimitry Andric } else { 3460b57cec5SDimitry Andric // For the PHI case, the split may not be actually required. 3470b57cec5SDimitry Andric // In the copy case, a phi is already a copy on the incoming edge, 3480b57cec5SDimitry Andric // therefore there is no need to split. 3490b57cec5SDimitry Andric if (ValMapping.NumBreakDowns == 1) 3500b57cec5SDimitry Andric // This is a already a copy, there is nothing to do. 3510b57cec5SDimitry Andric RepairPt.switchTo(RepairingPlacement::RepairingKind::Reassign); 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric return; 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric // At this point, we need to repair a defintion of a terminator. 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric // Technically we need to fix the def of MI on all outgoing 3590b57cec5SDimitry Andric // edges of MI to keep the repairing local. In other words, we 3600b57cec5SDimitry Andric // will create several definitions of the same register. This 3610b57cec5SDimitry Andric // does not work for SSA unless that definition is a physical 3620b57cec5SDimitry Andric // register. 3630b57cec5SDimitry Andric // However, there are other cases where we can get away with 3640b57cec5SDimitry Andric // that while still keeping the repairing local. 3650b57cec5SDimitry Andric assert(MI.isTerminator() && MO.isDef() && 3660b57cec5SDimitry Andric "This code is for the def of a terminator"); 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric // Since we use RPO traversal, if we need to repair a definition 3690b57cec5SDimitry Andric // this means this definition could be: 3700b57cec5SDimitry Andric // 1. Used by PHIs (i.e., this VReg has been visited as part of the 3710b57cec5SDimitry Andric // uses of a phi.), or 3720b57cec5SDimitry Andric // 2. Part of a target specific instruction (i.e., the target applied 3730b57cec5SDimitry Andric // some register class constraints when creating the instruction.) 3740b57cec5SDimitry Andric // If the constraints come for #2, the target said that another mapping 3750b57cec5SDimitry Andric // is supported so we may just drop them. Indeed, if we do not change 3760b57cec5SDimitry Andric // the number of registers holding that value, the uses will get fixed 3770b57cec5SDimitry Andric // when we get to them. 3780b57cec5SDimitry Andric // Uses in PHIs may have already been proceeded though. 3790b57cec5SDimitry Andric // If the constraints come for #1, then, those are weak constraints and 3800b57cec5SDimitry Andric // no actual uses may rely on them. However, the problem remains mainly 3810b57cec5SDimitry Andric // the same as for #2. If the value stays in one register, we could 3820b57cec5SDimitry Andric // just switch the register bank of the definition, but we would need to 3830b57cec5SDimitry Andric // account for a repairing cost for each phi we silently change. 3840b57cec5SDimitry Andric // 3850b57cec5SDimitry Andric // In any case, if the value needs to be broken down into several 3860b57cec5SDimitry Andric // registers, the repairing is not local anymore as we need to patch 3870b57cec5SDimitry Andric // every uses to rebuild the value in just one register. 3880b57cec5SDimitry Andric // 3890b57cec5SDimitry Andric // To summarize: 3900b57cec5SDimitry Andric // - If the value is in a physical register, we can do the split and 3910b57cec5SDimitry Andric // fix locally. 3920b57cec5SDimitry Andric // Otherwise if the value is in a virtual register: 3930b57cec5SDimitry Andric // - If the value remains in one register, we do not have to split 3940b57cec5SDimitry Andric // just switching the register bank would do, but we need to account 3950b57cec5SDimitry Andric // in the repairing cost all the phi we changed. 3960b57cec5SDimitry Andric // - If the value spans several registers, then we cannot do a local 3970b57cec5SDimitry Andric // repairing. 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric // Check if this is a physical or virtual register. 4000b57cec5SDimitry Andric Register Reg = MO.getReg(); 401*8bcb0991SDimitry Andric if (Register::isPhysicalRegister(Reg)) { 4020b57cec5SDimitry Andric // We are going to split every outgoing edges. 4030b57cec5SDimitry Andric // Check that this is possible. 4040b57cec5SDimitry Andric // FIXME: The machine representation is currently broken 4050b57cec5SDimitry Andric // since it also several terminators in one basic block. 4060b57cec5SDimitry Andric // Because of that we would technically need a way to get 4070b57cec5SDimitry Andric // the targets of just one terminator to know which edges 4080b57cec5SDimitry Andric // we have to split. 4090b57cec5SDimitry Andric // Assert that we do not hit the ill-formed representation. 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric // If there are other terminators before that one, some of 4120b57cec5SDimitry Andric // the outgoing edges may not be dominated by this definition. 4130b57cec5SDimitry Andric assert(&MI == &(*MI.getParent()->getFirstTerminator()) && 4140b57cec5SDimitry Andric "Do not know which outgoing edges are relevant"); 4150b57cec5SDimitry Andric const MachineInstr *Next = MI.getNextNode(); 4160b57cec5SDimitry Andric assert((!Next || Next->isUnconditionalBranch()) && 4170b57cec5SDimitry Andric "Do not know where each terminator ends up"); 4180b57cec5SDimitry Andric if (Next) 4190b57cec5SDimitry Andric // If the next terminator uses Reg, this means we have 4200b57cec5SDimitry Andric // to split right after MI and thus we need a way to ask 4210b57cec5SDimitry Andric // which outgoing edges are affected. 4220b57cec5SDimitry Andric assert(!Next->readsRegister(Reg) && "Need to split between terminators"); 4230b57cec5SDimitry Andric // We will split all the edges and repair there. 4240b57cec5SDimitry Andric } else { 4250b57cec5SDimitry Andric // This is a virtual register defined by a terminator. 4260b57cec5SDimitry Andric if (ValMapping.NumBreakDowns == 1) { 4270b57cec5SDimitry Andric // There is nothing to repair, but we may actually lie on 4280b57cec5SDimitry Andric // the repairing cost because of the PHIs already proceeded 4290b57cec5SDimitry Andric // as already stated. 4300b57cec5SDimitry Andric // Though the code will be correct. 4310b57cec5SDimitry Andric assert(false && "Repairing cost may not be accurate"); 4320b57cec5SDimitry Andric } else { 4330b57cec5SDimitry Andric // We need to do non-local repairing. Basically, patch all 4340b57cec5SDimitry Andric // the uses (i.e., phis) that we already proceeded. 4350b57cec5SDimitry Andric // For now, just say this mapping is not possible. 4360b57cec5SDimitry Andric RepairPt.switchTo(RepairingPlacement::RepairingKind::Impossible); 4370b57cec5SDimitry Andric } 4380b57cec5SDimitry Andric } 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric RegBankSelect::MappingCost RegBankSelect::computeMapping( 4420b57cec5SDimitry Andric MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, 4430b57cec5SDimitry Andric SmallVectorImpl<RepairingPlacement> &RepairPts, 4440b57cec5SDimitry Andric const RegBankSelect::MappingCost *BestCost) { 4450b57cec5SDimitry Andric assert((MBFI || !BestCost) && "Costs comparison require MBFI"); 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric if (!InstrMapping.isValid()) 4480b57cec5SDimitry Andric return MappingCost::ImpossibleCost(); 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric // If mapped with InstrMapping, MI will have the recorded cost. 4510b57cec5SDimitry Andric MappingCost Cost(MBFI ? MBFI->getBlockFreq(MI.getParent()) : 1); 4520b57cec5SDimitry Andric bool Saturated = Cost.addLocalCost(InstrMapping.getCost()); 4530b57cec5SDimitry Andric assert(!Saturated && "Possible mapping saturated the cost"); 4540b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Evaluating mapping cost for: " << MI); 4550b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "With: " << InstrMapping << '\n'); 4560b57cec5SDimitry Andric RepairPts.clear(); 4570b57cec5SDimitry Andric if (BestCost && Cost > *BestCost) { 4580b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Mapping is too expensive from the start\n"); 4590b57cec5SDimitry Andric return Cost; 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric // Moreover, to realize this mapping, the register bank of each operand must 4630b57cec5SDimitry Andric // match this mapping. In other words, we may need to locally reassign the 4640b57cec5SDimitry Andric // register banks. Account for that repairing cost as well. 4650b57cec5SDimitry Andric // In this context, local means in the surrounding of MI. 4660b57cec5SDimitry Andric for (unsigned OpIdx = 0, EndOpIdx = InstrMapping.getNumOperands(); 4670b57cec5SDimitry Andric OpIdx != EndOpIdx; ++OpIdx) { 4680b57cec5SDimitry Andric const MachineOperand &MO = MI.getOperand(OpIdx); 4690b57cec5SDimitry Andric if (!MO.isReg()) 4700b57cec5SDimitry Andric continue; 4710b57cec5SDimitry Andric Register Reg = MO.getReg(); 4720b57cec5SDimitry Andric if (!Reg) 4730b57cec5SDimitry Andric continue; 4740b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Opd" << OpIdx << '\n'); 4750b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping = 4760b57cec5SDimitry Andric InstrMapping.getOperandMapping(OpIdx); 4770b57cec5SDimitry Andric // If Reg is already properly mapped, this is free. 4780b57cec5SDimitry Andric bool Assign; 4790b57cec5SDimitry Andric if (assignmentMatch(Reg, ValMapping, Assign)) { 4800b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "=> is free (match).\n"); 4810b57cec5SDimitry Andric continue; 4820b57cec5SDimitry Andric } 4830b57cec5SDimitry Andric if (Assign) { 4840b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "=> is free (simple assignment).\n"); 4850b57cec5SDimitry Andric RepairPts.emplace_back(RepairingPlacement(MI, OpIdx, *TRI, *this, 4860b57cec5SDimitry Andric RepairingPlacement::Reassign)); 4870b57cec5SDimitry Andric continue; 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric // Find the insertion point for the repairing code. 4910b57cec5SDimitry Andric RepairPts.emplace_back( 4920b57cec5SDimitry Andric RepairingPlacement(MI, OpIdx, *TRI, *this, RepairingPlacement::Insert)); 4930b57cec5SDimitry Andric RepairingPlacement &RepairPt = RepairPts.back(); 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric // If we need to split a basic block to materialize this insertion point, 4960b57cec5SDimitry Andric // we may give a higher cost to this mapping. 4970b57cec5SDimitry Andric // Nevertheless, we may get away with the split, so try that first. 4980b57cec5SDimitry Andric if (RepairPt.hasSplit()) 4990b57cec5SDimitry Andric tryAvoidingSplit(RepairPt, MO, ValMapping); 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric // Check that the materialization of the repairing is possible. 5020b57cec5SDimitry Andric if (!RepairPt.canMaterialize()) { 5030b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Mapping involves impossible repairing\n"); 5040b57cec5SDimitry Andric return MappingCost::ImpossibleCost(); 5050b57cec5SDimitry Andric } 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric // Account for the split cost and repair cost. 5080b57cec5SDimitry Andric // Unless the cost is already saturated or we do not care about the cost. 5090b57cec5SDimitry Andric if (!BestCost || Saturated) 5100b57cec5SDimitry Andric continue; 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric // To get accurate information we need MBFI and MBPI. 5130b57cec5SDimitry Andric // Thus, if we end up here this information should be here. 5140b57cec5SDimitry Andric assert(MBFI && MBPI && "Cost computation requires MBFI and MBPI"); 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric // FIXME: We will have to rework the repairing cost model. 5170b57cec5SDimitry Andric // The repairing cost depends on the register bank that MO has. 5180b57cec5SDimitry Andric // However, when we break down the value into different values, 5190b57cec5SDimitry Andric // MO may not have a register bank while still needing repairing. 5200b57cec5SDimitry Andric // For the fast mode, we don't compute the cost so that is fine, 5210b57cec5SDimitry Andric // but still for the repairing code, we will have to make a choice. 5220b57cec5SDimitry Andric // For the greedy mode, we should choose greedily what is the best 5230b57cec5SDimitry Andric // choice based on the next use of MO. 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric // Sums up the repairing cost of MO at each insertion point. 5260b57cec5SDimitry Andric uint64_t RepairCost = getRepairCost(MO, ValMapping); 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andric // This is an impossible to repair cost. 5290b57cec5SDimitry Andric if (RepairCost == std::numeric_limits<unsigned>::max()) 5300b57cec5SDimitry Andric return MappingCost::ImpossibleCost(); 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric // Bias used for splitting: 5%. 5330b57cec5SDimitry Andric const uint64_t PercentageForBias = 5; 5340b57cec5SDimitry Andric uint64_t Bias = (RepairCost * PercentageForBias + 99) / 100; 5350b57cec5SDimitry Andric // We should not need more than a couple of instructions to repair 5360b57cec5SDimitry Andric // an assignment. In other words, the computation should not 5370b57cec5SDimitry Andric // overflow because the repairing cost is free of basic block 5380b57cec5SDimitry Andric // frequency. 5390b57cec5SDimitry Andric assert(((RepairCost < RepairCost * PercentageForBias) && 5400b57cec5SDimitry Andric (RepairCost * PercentageForBias < 5410b57cec5SDimitry Andric RepairCost * PercentageForBias + 99)) && 5420b57cec5SDimitry Andric "Repairing involves more than a billion of instructions?!"); 5430b57cec5SDimitry Andric for (const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) { 5440b57cec5SDimitry Andric assert(InsertPt->canMaterialize() && "We should not have made it here"); 5450b57cec5SDimitry Andric // We will applied some basic block frequency and those uses uint64_t. 5460b57cec5SDimitry Andric if (!InsertPt->isSplit()) 5470b57cec5SDimitry Andric Saturated = Cost.addLocalCost(RepairCost); 5480b57cec5SDimitry Andric else { 5490b57cec5SDimitry Andric uint64_t CostForInsertPt = RepairCost; 5500b57cec5SDimitry Andric // Again we shouldn't overflow here givent that 5510b57cec5SDimitry Andric // CostForInsertPt is frequency free at this point. 5520b57cec5SDimitry Andric assert(CostForInsertPt + Bias > CostForInsertPt && 5530b57cec5SDimitry Andric "Repairing + split bias overflows"); 5540b57cec5SDimitry Andric CostForInsertPt += Bias; 5550b57cec5SDimitry Andric uint64_t PtCost = InsertPt->frequency(*this) * CostForInsertPt; 5560b57cec5SDimitry Andric // Check if we just overflowed. 5570b57cec5SDimitry Andric if ((Saturated = PtCost < CostForInsertPt)) 5580b57cec5SDimitry Andric Cost.saturate(); 5590b57cec5SDimitry Andric else 5600b57cec5SDimitry Andric Saturated = Cost.addNonLocalCost(PtCost); 5610b57cec5SDimitry Andric } 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric // Stop looking into what it takes to repair, this is already 5640b57cec5SDimitry Andric // too expensive. 5650b57cec5SDimitry Andric if (BestCost && Cost > *BestCost) { 5660b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Mapping is too expensive, stop processing\n"); 5670b57cec5SDimitry Andric return Cost; 5680b57cec5SDimitry Andric } 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric // No need to accumulate more cost information. 5710b57cec5SDimitry Andric // We need to still gather the repairing information though. 5720b57cec5SDimitry Andric if (Saturated) 5730b57cec5SDimitry Andric break; 5740b57cec5SDimitry Andric } 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Total cost is: " << Cost << "\n"); 5770b57cec5SDimitry Andric return Cost; 5780b57cec5SDimitry Andric } 5790b57cec5SDimitry Andric 5800b57cec5SDimitry Andric bool RegBankSelect::applyMapping( 5810b57cec5SDimitry Andric MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, 5820b57cec5SDimitry Andric SmallVectorImpl<RegBankSelect::RepairingPlacement> &RepairPts) { 5830b57cec5SDimitry Andric // OpdMapper will hold all the information needed for the rewriting. 5840b57cec5SDimitry Andric RegisterBankInfo::OperandsMapper OpdMapper(MI, InstrMapping, *MRI); 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric // First, place the repairing code. 5870b57cec5SDimitry Andric for (RepairingPlacement &RepairPt : RepairPts) { 5880b57cec5SDimitry Andric if (!RepairPt.canMaterialize() || 5890b57cec5SDimitry Andric RepairPt.getKind() == RepairingPlacement::Impossible) 5900b57cec5SDimitry Andric return false; 5910b57cec5SDimitry Andric assert(RepairPt.getKind() != RepairingPlacement::None && 5920b57cec5SDimitry Andric "This should not make its way in the list"); 5930b57cec5SDimitry Andric unsigned OpIdx = RepairPt.getOpIdx(); 5940b57cec5SDimitry Andric MachineOperand &MO = MI.getOperand(OpIdx); 5950b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping &ValMapping = 5960b57cec5SDimitry Andric InstrMapping.getOperandMapping(OpIdx); 5970b57cec5SDimitry Andric Register Reg = MO.getReg(); 5980b57cec5SDimitry Andric 5990b57cec5SDimitry Andric switch (RepairPt.getKind()) { 6000b57cec5SDimitry Andric case RepairingPlacement::Reassign: 6010b57cec5SDimitry Andric assert(ValMapping.NumBreakDowns == 1 && 6020b57cec5SDimitry Andric "Reassignment should only be for simple mapping"); 6030b57cec5SDimitry Andric MRI->setRegBank(Reg, *ValMapping.BreakDown[0].RegBank); 6040b57cec5SDimitry Andric break; 6050b57cec5SDimitry Andric case RepairingPlacement::Insert: 6060b57cec5SDimitry Andric OpdMapper.createVRegs(OpIdx); 6070b57cec5SDimitry Andric if (!repairReg(MO, ValMapping, RepairPt, OpdMapper.getVRegs(OpIdx))) 6080b57cec5SDimitry Andric return false; 6090b57cec5SDimitry Andric break; 6100b57cec5SDimitry Andric default: 6110b57cec5SDimitry Andric llvm_unreachable("Other kind should not happen"); 6120b57cec5SDimitry Andric } 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric 6150b57cec5SDimitry Andric // Second, rewrite the instruction. 6160b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Actual mapping of the operands: " << OpdMapper << '\n'); 6170b57cec5SDimitry Andric RBI->applyMapping(OpdMapper); 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric return true; 6200b57cec5SDimitry Andric } 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric bool RegBankSelect::assignInstr(MachineInstr &MI) { 6230b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Assign: " << MI); 6240b57cec5SDimitry Andric // Remember the repairing placement for all the operands. 6250b57cec5SDimitry Andric SmallVector<RepairingPlacement, 4> RepairPts; 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping *BestMapping; 6280b57cec5SDimitry Andric if (OptMode == RegBankSelect::Mode::Fast) { 6290b57cec5SDimitry Andric BestMapping = &RBI->getInstrMapping(MI); 6300b57cec5SDimitry Andric MappingCost DefaultCost = computeMapping(MI, *BestMapping, RepairPts); 6310b57cec5SDimitry Andric (void)DefaultCost; 6320b57cec5SDimitry Andric if (DefaultCost == MappingCost::ImpossibleCost()) 6330b57cec5SDimitry Andric return false; 6340b57cec5SDimitry Andric } else { 6350b57cec5SDimitry Andric RegisterBankInfo::InstructionMappings PossibleMappings = 6360b57cec5SDimitry Andric RBI->getInstrPossibleMappings(MI); 6370b57cec5SDimitry Andric if (PossibleMappings.empty()) 6380b57cec5SDimitry Andric return false; 6390b57cec5SDimitry Andric BestMapping = &findBestMapping(MI, PossibleMappings, RepairPts); 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric // Make sure the mapping is valid for MI. 6420b57cec5SDimitry Andric assert(BestMapping->verify(MI) && "Invalid instruction mapping"); 6430b57cec5SDimitry Andric 6440b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Best Mapping: " << *BestMapping << '\n'); 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric // After this call, MI may not be valid anymore. 6470b57cec5SDimitry Andric // Do not use it. 6480b57cec5SDimitry Andric return applyMapping(MI, *BestMapping, RepairPts); 6490b57cec5SDimitry Andric } 6500b57cec5SDimitry Andric 6510b57cec5SDimitry Andric bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) { 6520b57cec5SDimitry Andric // If the ISel pipeline failed, do not bother running that pass. 6530b57cec5SDimitry Andric if (MF.getProperties().hasProperty( 6540b57cec5SDimitry Andric MachineFunctionProperties::Property::FailedISel)) 6550b57cec5SDimitry Andric return false; 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Assign register banks for: " << MF.getName() << '\n'); 6580b57cec5SDimitry Andric const Function &F = MF.getFunction(); 6590b57cec5SDimitry Andric Mode SaveOptMode = OptMode; 6600b57cec5SDimitry Andric if (F.hasOptNone()) 6610b57cec5SDimitry Andric OptMode = Mode::Fast; 6620b57cec5SDimitry Andric init(MF); 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric #ifndef NDEBUG 6650b57cec5SDimitry Andric // Check that our input is fully legal: we require the function to have the 6660b57cec5SDimitry Andric // Legalized property, so it should be. 6670b57cec5SDimitry Andric // FIXME: This should be in the MachineVerifier. 6680b57cec5SDimitry Andric if (!DisableGISelLegalityCheck) 6690b57cec5SDimitry Andric if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) { 6700b57cec5SDimitry Andric reportGISelFailure(MF, *TPC, *MORE, "gisel-regbankselect", 6710b57cec5SDimitry Andric "instruction is not legal", *MI); 6720b57cec5SDimitry Andric return false; 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric #endif 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric // Walk the function and assign register banks to all operands. 6770b57cec5SDimitry Andric // Use a RPOT to make sure all registers are assigned before we choose 6780b57cec5SDimitry Andric // the best mapping of the current instruction. 6790b57cec5SDimitry Andric ReversePostOrderTraversal<MachineFunction*> RPOT(&MF); 6800b57cec5SDimitry Andric for (MachineBasicBlock *MBB : RPOT) { 6810b57cec5SDimitry Andric // Set a sensible insertion point so that subsequent calls to 6820b57cec5SDimitry Andric // MIRBuilder. 6830b57cec5SDimitry Andric MIRBuilder.setMBB(*MBB); 6840b57cec5SDimitry Andric for (MachineBasicBlock::iterator MII = MBB->begin(), End = MBB->end(); 6850b57cec5SDimitry Andric MII != End;) { 6860b57cec5SDimitry Andric // MI might be invalidated by the assignment, so move the 6870b57cec5SDimitry Andric // iterator before hand. 6880b57cec5SDimitry Andric MachineInstr &MI = *MII++; 6890b57cec5SDimitry Andric 690*8bcb0991SDimitry Andric // Ignore target-specific post-isel instructions: they should use proper 691*8bcb0991SDimitry Andric // regclasses. 692*8bcb0991SDimitry Andric if (isTargetSpecificOpcode(MI.getOpcode()) && !MI.isPreISelOpcode()) 6930b57cec5SDimitry Andric continue; 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric if (!assignInstr(MI)) { 6960b57cec5SDimitry Andric reportGISelFailure(MF, *TPC, *MORE, "gisel-regbankselect", 6970b57cec5SDimitry Andric "unable to map instruction", MI); 6980b57cec5SDimitry Andric return false; 6990b57cec5SDimitry Andric } 7000b57cec5SDimitry Andric 7010b57cec5SDimitry Andric // It's possible the mapping changed control flow, and moved the following 7020b57cec5SDimitry Andric // instruction to a new block, so figure out the new parent. 7030b57cec5SDimitry Andric if (MII != End) { 7040b57cec5SDimitry Andric MachineBasicBlock *NextInstBB = MII->getParent(); 7050b57cec5SDimitry Andric if (NextInstBB != MBB) { 7060b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Instruction mapping changed control flow\n"); 7070b57cec5SDimitry Andric MBB = NextInstBB; 7080b57cec5SDimitry Andric MIRBuilder.setMBB(*MBB); 7090b57cec5SDimitry Andric End = MBB->end(); 7100b57cec5SDimitry Andric } 7110b57cec5SDimitry Andric } 7120b57cec5SDimitry Andric } 7130b57cec5SDimitry Andric } 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric OptMode = SaveOptMode; 7160b57cec5SDimitry Andric return false; 7170b57cec5SDimitry Andric } 7180b57cec5SDimitry Andric 7190b57cec5SDimitry Andric //------------------------------------------------------------------------------ 7200b57cec5SDimitry Andric // Helper Classes Implementation 7210b57cec5SDimitry Andric //------------------------------------------------------------------------------ 7220b57cec5SDimitry Andric RegBankSelect::RepairingPlacement::RepairingPlacement( 7230b57cec5SDimitry Andric MachineInstr &MI, unsigned OpIdx, const TargetRegisterInfo &TRI, Pass &P, 7240b57cec5SDimitry Andric RepairingPlacement::RepairingKind Kind) 7250b57cec5SDimitry Andric // Default is, we are going to insert code to repair OpIdx. 7260b57cec5SDimitry Andric : Kind(Kind), OpIdx(OpIdx), 7270b57cec5SDimitry Andric CanMaterialize(Kind != RepairingKind::Impossible), P(P) { 7280b57cec5SDimitry Andric const MachineOperand &MO = MI.getOperand(OpIdx); 7290b57cec5SDimitry Andric assert(MO.isReg() && "Trying to repair a non-reg operand"); 7300b57cec5SDimitry Andric 7310b57cec5SDimitry Andric if (Kind != RepairingKind::Insert) 7320b57cec5SDimitry Andric return; 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric // Repairings for definitions happen after MI, uses happen before. 7350b57cec5SDimitry Andric bool Before = !MO.isDef(); 7360b57cec5SDimitry Andric 7370b57cec5SDimitry Andric // Check if we are done with MI. 7380b57cec5SDimitry Andric if (!MI.isPHI() && !MI.isTerminator()) { 7390b57cec5SDimitry Andric addInsertPoint(MI, Before); 7400b57cec5SDimitry Andric // We are done with the initialization. 7410b57cec5SDimitry Andric return; 7420b57cec5SDimitry Andric } 7430b57cec5SDimitry Andric 7440b57cec5SDimitry Andric // Now, look for the special cases. 7450b57cec5SDimitry Andric if (MI.isPHI()) { 7460b57cec5SDimitry Andric // - PHI must be the first instructions: 7470b57cec5SDimitry Andric // * Before, we have to split the related incoming edge. 7480b57cec5SDimitry Andric // * After, move the insertion point past the last phi. 7490b57cec5SDimitry Andric if (!Before) { 7500b57cec5SDimitry Andric MachineBasicBlock::iterator It = MI.getParent()->getFirstNonPHI(); 7510b57cec5SDimitry Andric if (It != MI.getParent()->end()) 7520b57cec5SDimitry Andric addInsertPoint(*It, /*Before*/ true); 7530b57cec5SDimitry Andric else 7540b57cec5SDimitry Andric addInsertPoint(*(--It), /*Before*/ false); 7550b57cec5SDimitry Andric return; 7560b57cec5SDimitry Andric } 7570b57cec5SDimitry Andric // We repair a use of a phi, we may need to split the related edge. 7580b57cec5SDimitry Andric MachineBasicBlock &Pred = *MI.getOperand(OpIdx + 1).getMBB(); 7590b57cec5SDimitry Andric // Check if we can move the insertion point prior to the 7600b57cec5SDimitry Andric // terminators of the predecessor. 7610b57cec5SDimitry Andric Register Reg = MO.getReg(); 7620b57cec5SDimitry Andric MachineBasicBlock::iterator It = Pred.getLastNonDebugInstr(); 7630b57cec5SDimitry Andric for (auto Begin = Pred.begin(); It != Begin && It->isTerminator(); --It) 7640b57cec5SDimitry Andric if (It->modifiesRegister(Reg, &TRI)) { 7650b57cec5SDimitry Andric // We cannot hoist the repairing code in the predecessor. 7660b57cec5SDimitry Andric // Split the edge. 7670b57cec5SDimitry Andric addInsertPoint(Pred, *MI.getParent()); 7680b57cec5SDimitry Andric return; 7690b57cec5SDimitry Andric } 7700b57cec5SDimitry Andric // At this point, we can insert in Pred. 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andric // - If It is invalid, Pred is empty and we can insert in Pred 7730b57cec5SDimitry Andric // wherever we want. 7740b57cec5SDimitry Andric // - If It is valid, It is the first non-terminator, insert after It. 7750b57cec5SDimitry Andric if (It == Pred.end()) 7760b57cec5SDimitry Andric addInsertPoint(Pred, /*Beginning*/ false); 7770b57cec5SDimitry Andric else 7780b57cec5SDimitry Andric addInsertPoint(*It, /*Before*/ false); 7790b57cec5SDimitry Andric } else { 7800b57cec5SDimitry Andric // - Terminators must be the last instructions: 7810b57cec5SDimitry Andric // * Before, move the insert point before the first terminator. 7820b57cec5SDimitry Andric // * After, we have to split the outcoming edges. 7830b57cec5SDimitry Andric if (Before) { 7840b57cec5SDimitry Andric // Check whether Reg is defined by any terminator. 7850b57cec5SDimitry Andric MachineBasicBlock::reverse_iterator It = MI; 7860b57cec5SDimitry Andric auto REnd = MI.getParent()->rend(); 7870b57cec5SDimitry Andric 7880b57cec5SDimitry Andric for (; It != REnd && It->isTerminator(); ++It) { 7890b57cec5SDimitry Andric assert(!It->modifiesRegister(MO.getReg(), &TRI) && 7900b57cec5SDimitry Andric "copy insertion in middle of terminators not handled"); 7910b57cec5SDimitry Andric } 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric if (It == REnd) { 7940b57cec5SDimitry Andric addInsertPoint(*MI.getParent()->begin(), true); 7950b57cec5SDimitry Andric return; 7960b57cec5SDimitry Andric } 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric // We are sure to be right before the first terminator. 7990b57cec5SDimitry Andric addInsertPoint(*It, /*Before*/ false); 8000b57cec5SDimitry Andric return; 8010b57cec5SDimitry Andric } 8020b57cec5SDimitry Andric // Make sure Reg is not redefined by other terminators, otherwise 8030b57cec5SDimitry Andric // we do not know how to split. 8040b57cec5SDimitry Andric for (MachineBasicBlock::iterator It = MI, End = MI.getParent()->end(); 8050b57cec5SDimitry Andric ++It != End;) 8060b57cec5SDimitry Andric // The machine verifier should reject this kind of code. 8070b57cec5SDimitry Andric assert(It->modifiesRegister(MO.getReg(), &TRI) && 8080b57cec5SDimitry Andric "Do not know where to split"); 8090b57cec5SDimitry Andric // Split each outcoming edges. 8100b57cec5SDimitry Andric MachineBasicBlock &Src = *MI.getParent(); 8110b57cec5SDimitry Andric for (auto &Succ : Src.successors()) 8120b57cec5SDimitry Andric addInsertPoint(Src, Succ); 8130b57cec5SDimitry Andric } 8140b57cec5SDimitry Andric } 8150b57cec5SDimitry Andric 8160b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint(MachineInstr &MI, 8170b57cec5SDimitry Andric bool Before) { 8180b57cec5SDimitry Andric addInsertPoint(*new InstrInsertPoint(MI, Before)); 8190b57cec5SDimitry Andric } 8200b57cec5SDimitry Andric 8210b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint(MachineBasicBlock &MBB, 8220b57cec5SDimitry Andric bool Beginning) { 8230b57cec5SDimitry Andric addInsertPoint(*new MBBInsertPoint(MBB, Beginning)); 8240b57cec5SDimitry Andric } 8250b57cec5SDimitry Andric 8260b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint(MachineBasicBlock &Src, 8270b57cec5SDimitry Andric MachineBasicBlock &Dst) { 8280b57cec5SDimitry Andric addInsertPoint(*new EdgeInsertPoint(Src, Dst, P)); 8290b57cec5SDimitry Andric } 8300b57cec5SDimitry Andric 8310b57cec5SDimitry Andric void RegBankSelect::RepairingPlacement::addInsertPoint( 8320b57cec5SDimitry Andric RegBankSelect::InsertPoint &Point) { 8330b57cec5SDimitry Andric CanMaterialize &= Point.canMaterialize(); 8340b57cec5SDimitry Andric HasSplit |= Point.isSplit(); 8350b57cec5SDimitry Andric InsertPoints.emplace_back(&Point); 8360b57cec5SDimitry Andric } 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andric RegBankSelect::InstrInsertPoint::InstrInsertPoint(MachineInstr &Instr, 8390b57cec5SDimitry Andric bool Before) 8400b57cec5SDimitry Andric : InsertPoint(), Instr(Instr), Before(Before) { 8410b57cec5SDimitry Andric // Since we do not support splitting, we do not need to update 8420b57cec5SDimitry Andric // liveness and such, so do not do anything with P. 8430b57cec5SDimitry Andric assert((!Before || !Instr.isPHI()) && 8440b57cec5SDimitry Andric "Splitting before phis requires more points"); 8450b57cec5SDimitry Andric assert((!Before || !Instr.getNextNode() || !Instr.getNextNode()->isPHI()) && 8460b57cec5SDimitry Andric "Splitting between phis does not make sense"); 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric void RegBankSelect::InstrInsertPoint::materialize() { 8500b57cec5SDimitry Andric if (isSplit()) { 8510b57cec5SDimitry Andric // Slice and return the beginning of the new block. 8520b57cec5SDimitry Andric // If we need to split between the terminators, we theoritically 8530b57cec5SDimitry Andric // need to know where the first and second set of terminators end 8540b57cec5SDimitry Andric // to update the successors properly. 8550b57cec5SDimitry Andric // Now, in pratice, we should have a maximum of 2 branch 8560b57cec5SDimitry Andric // instructions; one conditional and one unconditional. Therefore 8570b57cec5SDimitry Andric // we know how to update the successor by looking at the target of 8580b57cec5SDimitry Andric // the unconditional branch. 8590b57cec5SDimitry Andric // If we end up splitting at some point, then, we should update 8600b57cec5SDimitry Andric // the liveness information and such. I.e., we would need to 8610b57cec5SDimitry Andric // access P here. 8620b57cec5SDimitry Andric // The machine verifier should actually make sure such cases 8630b57cec5SDimitry Andric // cannot happen. 8640b57cec5SDimitry Andric llvm_unreachable("Not yet implemented"); 8650b57cec5SDimitry Andric } 8660b57cec5SDimitry Andric // Otherwise the insertion point is just the current or next 8670b57cec5SDimitry Andric // instruction depending on Before. I.e., there is nothing to do 8680b57cec5SDimitry Andric // here. 8690b57cec5SDimitry Andric } 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andric bool RegBankSelect::InstrInsertPoint::isSplit() const { 8720b57cec5SDimitry Andric // If the insertion point is after a terminator, we need to split. 8730b57cec5SDimitry Andric if (!Before) 8740b57cec5SDimitry Andric return Instr.isTerminator(); 8750b57cec5SDimitry Andric // If we insert before an instruction that is after a terminator, 8760b57cec5SDimitry Andric // we are still after a terminator. 8770b57cec5SDimitry Andric return Instr.getPrevNode() && Instr.getPrevNode()->isTerminator(); 8780b57cec5SDimitry Andric } 8790b57cec5SDimitry Andric 8800b57cec5SDimitry Andric uint64_t RegBankSelect::InstrInsertPoint::frequency(const Pass &P) const { 8810b57cec5SDimitry Andric // Even if we need to split, because we insert between terminators, 8820b57cec5SDimitry Andric // this split has actually the same frequency as the instruction. 8830b57cec5SDimitry Andric const MachineBlockFrequencyInfo *MBFI = 8840b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBlockFrequencyInfo>(); 8850b57cec5SDimitry Andric if (!MBFI) 8860b57cec5SDimitry Andric return 1; 8870b57cec5SDimitry Andric return MBFI->getBlockFreq(Instr.getParent()).getFrequency(); 8880b57cec5SDimitry Andric } 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andric uint64_t RegBankSelect::MBBInsertPoint::frequency(const Pass &P) const { 8910b57cec5SDimitry Andric const MachineBlockFrequencyInfo *MBFI = 8920b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBlockFrequencyInfo>(); 8930b57cec5SDimitry Andric if (!MBFI) 8940b57cec5SDimitry Andric return 1; 8950b57cec5SDimitry Andric return MBFI->getBlockFreq(&MBB).getFrequency(); 8960b57cec5SDimitry Andric } 8970b57cec5SDimitry Andric 8980b57cec5SDimitry Andric void RegBankSelect::EdgeInsertPoint::materialize() { 8990b57cec5SDimitry Andric // If we end up repairing twice at the same place before materializing the 9000b57cec5SDimitry Andric // insertion point, we may think we have to split an edge twice. 9010b57cec5SDimitry Andric // We should have a factory for the insert point such that identical points 9020b57cec5SDimitry Andric // are the same instance. 9030b57cec5SDimitry Andric assert(Src.isSuccessor(DstOrSplit) && DstOrSplit->isPredecessor(&Src) && 9040b57cec5SDimitry Andric "This point has already been split"); 9050b57cec5SDimitry Andric MachineBasicBlock *NewBB = Src.SplitCriticalEdge(DstOrSplit, P); 9060b57cec5SDimitry Andric assert(NewBB && "Invalid call to materialize"); 9070b57cec5SDimitry Andric // We reuse the destination block to hold the information of the new block. 9080b57cec5SDimitry Andric DstOrSplit = NewBB; 9090b57cec5SDimitry Andric } 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric uint64_t RegBankSelect::EdgeInsertPoint::frequency(const Pass &P) const { 9120b57cec5SDimitry Andric const MachineBlockFrequencyInfo *MBFI = 9130b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBlockFrequencyInfo>(); 9140b57cec5SDimitry Andric if (!MBFI) 9150b57cec5SDimitry Andric return 1; 9160b57cec5SDimitry Andric if (WasMaterialized) 9170b57cec5SDimitry Andric return MBFI->getBlockFreq(DstOrSplit).getFrequency(); 9180b57cec5SDimitry Andric 9190b57cec5SDimitry Andric const MachineBranchProbabilityInfo *MBPI = 9200b57cec5SDimitry Andric P.getAnalysisIfAvailable<MachineBranchProbabilityInfo>(); 9210b57cec5SDimitry Andric if (!MBPI) 9220b57cec5SDimitry Andric return 1; 9230b57cec5SDimitry Andric // The basic block will be on the edge. 9240b57cec5SDimitry Andric return (MBFI->getBlockFreq(&Src) * MBPI->getEdgeProbability(&Src, DstOrSplit)) 9250b57cec5SDimitry Andric .getFrequency(); 9260b57cec5SDimitry Andric } 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric bool RegBankSelect::EdgeInsertPoint::canMaterialize() const { 9290b57cec5SDimitry Andric // If this is not a critical edge, we should not have used this insert 9300b57cec5SDimitry Andric // point. Indeed, either the successor or the predecessor should 9310b57cec5SDimitry Andric // have do. 9320b57cec5SDimitry Andric assert(Src.succ_size() > 1 && DstOrSplit->pred_size() > 1 && 9330b57cec5SDimitry Andric "Edge is not critical"); 9340b57cec5SDimitry Andric return Src.canSplitCriticalEdge(DstOrSplit); 9350b57cec5SDimitry Andric } 9360b57cec5SDimitry Andric 9370b57cec5SDimitry Andric RegBankSelect::MappingCost::MappingCost(const BlockFrequency &LocalFreq) 9380b57cec5SDimitry Andric : LocalFreq(LocalFreq.getFrequency()) {} 9390b57cec5SDimitry Andric 9400b57cec5SDimitry Andric bool RegBankSelect::MappingCost::addLocalCost(uint64_t Cost) { 9410b57cec5SDimitry Andric // Check if this overflows. 9420b57cec5SDimitry Andric if (LocalCost + Cost < LocalCost) { 9430b57cec5SDimitry Andric saturate(); 9440b57cec5SDimitry Andric return true; 9450b57cec5SDimitry Andric } 9460b57cec5SDimitry Andric LocalCost += Cost; 9470b57cec5SDimitry Andric return isSaturated(); 9480b57cec5SDimitry Andric } 9490b57cec5SDimitry Andric 9500b57cec5SDimitry Andric bool RegBankSelect::MappingCost::addNonLocalCost(uint64_t Cost) { 9510b57cec5SDimitry Andric // Check if this overflows. 9520b57cec5SDimitry Andric if (NonLocalCost + Cost < NonLocalCost) { 9530b57cec5SDimitry Andric saturate(); 9540b57cec5SDimitry Andric return true; 9550b57cec5SDimitry Andric } 9560b57cec5SDimitry Andric NonLocalCost += Cost; 9570b57cec5SDimitry Andric return isSaturated(); 9580b57cec5SDimitry Andric } 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric bool RegBankSelect::MappingCost::isSaturated() const { 9610b57cec5SDimitry Andric return LocalCost == UINT64_MAX - 1 && NonLocalCost == UINT64_MAX && 9620b57cec5SDimitry Andric LocalFreq == UINT64_MAX; 9630b57cec5SDimitry Andric } 9640b57cec5SDimitry Andric 9650b57cec5SDimitry Andric void RegBankSelect::MappingCost::saturate() { 9660b57cec5SDimitry Andric *this = ImpossibleCost(); 9670b57cec5SDimitry Andric --LocalCost; 9680b57cec5SDimitry Andric } 9690b57cec5SDimitry Andric 9700b57cec5SDimitry Andric RegBankSelect::MappingCost RegBankSelect::MappingCost::ImpossibleCost() { 9710b57cec5SDimitry Andric return MappingCost(UINT64_MAX, UINT64_MAX, UINT64_MAX); 9720b57cec5SDimitry Andric } 9730b57cec5SDimitry Andric 9740b57cec5SDimitry Andric bool RegBankSelect::MappingCost::operator<(const MappingCost &Cost) const { 9750b57cec5SDimitry Andric // Sort out the easy cases. 9760b57cec5SDimitry Andric if (*this == Cost) 9770b57cec5SDimitry Andric return false; 9780b57cec5SDimitry Andric // If one is impossible to realize the other is cheaper unless it is 9790b57cec5SDimitry Andric // impossible as well. 9800b57cec5SDimitry Andric if ((*this == ImpossibleCost()) || (Cost == ImpossibleCost())) 9810b57cec5SDimitry Andric return (*this == ImpossibleCost()) < (Cost == ImpossibleCost()); 9820b57cec5SDimitry Andric // If one is saturated the other is cheaper, unless it is saturated 9830b57cec5SDimitry Andric // as well. 9840b57cec5SDimitry Andric if (isSaturated() || Cost.isSaturated()) 9850b57cec5SDimitry Andric return isSaturated() < Cost.isSaturated(); 9860b57cec5SDimitry Andric // At this point we know both costs hold sensible values. 9870b57cec5SDimitry Andric 9880b57cec5SDimitry Andric // If both values have a different base frequency, there is no much 9890b57cec5SDimitry Andric // we can do but to scale everything. 9900b57cec5SDimitry Andric // However, if they have the same base frequency we can avoid making 9910b57cec5SDimitry Andric // complicated computation. 9920b57cec5SDimitry Andric uint64_t ThisLocalAdjust; 9930b57cec5SDimitry Andric uint64_t OtherLocalAdjust; 9940b57cec5SDimitry Andric if (LLVM_LIKELY(LocalFreq == Cost.LocalFreq)) { 9950b57cec5SDimitry Andric 9960b57cec5SDimitry Andric // At this point, we know the local costs are comparable. 9970b57cec5SDimitry Andric // Do the case that do not involve potential overflow first. 9980b57cec5SDimitry Andric if (NonLocalCost == Cost.NonLocalCost) 9990b57cec5SDimitry Andric // Since the non-local costs do not discriminate on the result, 10000b57cec5SDimitry Andric // just compare the local costs. 10010b57cec5SDimitry Andric return LocalCost < Cost.LocalCost; 10020b57cec5SDimitry Andric 10030b57cec5SDimitry Andric // The base costs are comparable so we may only keep the relative 10040b57cec5SDimitry Andric // value to increase our chances of avoiding overflows. 10050b57cec5SDimitry Andric ThisLocalAdjust = 0; 10060b57cec5SDimitry Andric OtherLocalAdjust = 0; 10070b57cec5SDimitry Andric if (LocalCost < Cost.LocalCost) 10080b57cec5SDimitry Andric OtherLocalAdjust = Cost.LocalCost - LocalCost; 10090b57cec5SDimitry Andric else 10100b57cec5SDimitry Andric ThisLocalAdjust = LocalCost - Cost.LocalCost; 10110b57cec5SDimitry Andric } else { 10120b57cec5SDimitry Andric ThisLocalAdjust = LocalCost; 10130b57cec5SDimitry Andric OtherLocalAdjust = Cost.LocalCost; 10140b57cec5SDimitry Andric } 10150b57cec5SDimitry Andric 10160b57cec5SDimitry Andric // The non-local costs are comparable, just keep the relative value. 10170b57cec5SDimitry Andric uint64_t ThisNonLocalAdjust = 0; 10180b57cec5SDimitry Andric uint64_t OtherNonLocalAdjust = 0; 10190b57cec5SDimitry Andric if (NonLocalCost < Cost.NonLocalCost) 10200b57cec5SDimitry Andric OtherNonLocalAdjust = Cost.NonLocalCost - NonLocalCost; 10210b57cec5SDimitry Andric else 10220b57cec5SDimitry Andric ThisNonLocalAdjust = NonLocalCost - Cost.NonLocalCost; 10230b57cec5SDimitry Andric // Scale everything to make them comparable. 10240b57cec5SDimitry Andric uint64_t ThisScaledCost = ThisLocalAdjust * LocalFreq; 10250b57cec5SDimitry Andric // Check for overflow on that operation. 10260b57cec5SDimitry Andric bool ThisOverflows = ThisLocalAdjust && (ThisScaledCost < ThisLocalAdjust || 10270b57cec5SDimitry Andric ThisScaledCost < LocalFreq); 10280b57cec5SDimitry Andric uint64_t OtherScaledCost = OtherLocalAdjust * Cost.LocalFreq; 10290b57cec5SDimitry Andric // Check for overflow on the last operation. 10300b57cec5SDimitry Andric bool OtherOverflows = 10310b57cec5SDimitry Andric OtherLocalAdjust && 10320b57cec5SDimitry Andric (OtherScaledCost < OtherLocalAdjust || OtherScaledCost < Cost.LocalFreq); 10330b57cec5SDimitry Andric // Add the non-local costs. 10340b57cec5SDimitry Andric ThisOverflows |= ThisNonLocalAdjust && 10350b57cec5SDimitry Andric ThisScaledCost + ThisNonLocalAdjust < ThisNonLocalAdjust; 10360b57cec5SDimitry Andric ThisScaledCost += ThisNonLocalAdjust; 10370b57cec5SDimitry Andric OtherOverflows |= OtherNonLocalAdjust && 10380b57cec5SDimitry Andric OtherScaledCost + OtherNonLocalAdjust < OtherNonLocalAdjust; 10390b57cec5SDimitry Andric OtherScaledCost += OtherNonLocalAdjust; 10400b57cec5SDimitry Andric // If both overflows, we cannot compare without additional 10410b57cec5SDimitry Andric // precision, e.g., APInt. Just give up on that case. 10420b57cec5SDimitry Andric if (ThisOverflows && OtherOverflows) 10430b57cec5SDimitry Andric return false; 10440b57cec5SDimitry Andric // If one overflows but not the other, we can still compare. 10450b57cec5SDimitry Andric if (ThisOverflows || OtherOverflows) 10460b57cec5SDimitry Andric return ThisOverflows < OtherOverflows; 10470b57cec5SDimitry Andric // Otherwise, just compare the values. 10480b57cec5SDimitry Andric return ThisScaledCost < OtherScaledCost; 10490b57cec5SDimitry Andric } 10500b57cec5SDimitry Andric 10510b57cec5SDimitry Andric bool RegBankSelect::MappingCost::operator==(const MappingCost &Cost) const { 10520b57cec5SDimitry Andric return LocalCost == Cost.LocalCost && NonLocalCost == Cost.NonLocalCost && 10530b57cec5SDimitry Andric LocalFreq == Cost.LocalFreq; 10540b57cec5SDimitry Andric } 10550b57cec5SDimitry Andric 10560b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 10570b57cec5SDimitry Andric LLVM_DUMP_METHOD void RegBankSelect::MappingCost::dump() const { 10580b57cec5SDimitry Andric print(dbgs()); 10590b57cec5SDimitry Andric dbgs() << '\n'; 10600b57cec5SDimitry Andric } 10610b57cec5SDimitry Andric #endif 10620b57cec5SDimitry Andric 10630b57cec5SDimitry Andric void RegBankSelect::MappingCost::print(raw_ostream &OS) const { 10640b57cec5SDimitry Andric if (*this == ImpossibleCost()) { 10650b57cec5SDimitry Andric OS << "impossible"; 10660b57cec5SDimitry Andric return; 10670b57cec5SDimitry Andric } 10680b57cec5SDimitry Andric if (isSaturated()) { 10690b57cec5SDimitry Andric OS << "saturated"; 10700b57cec5SDimitry Andric return; 10710b57cec5SDimitry Andric } 10720b57cec5SDimitry Andric OS << LocalFreq << " * " << LocalCost << " + " << NonLocalCost; 10730b57cec5SDimitry Andric } 1074