Path: blob/main/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCExpandISEL.cpp
35266 views
//===------------- PPCExpandISEL.cpp - Expand ISEL instruction ------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// A pass that expands the ISEL instruction into an if-then-else sequence.9// This pass must be run post-RA since all operands must be physical registers.10//11//===----------------------------------------------------------------------===//1213#include "PPC.h"14#include "PPCInstrInfo.h"15#include "PPCSubtarget.h"16#include "llvm/ADT/DenseMap.h"17#include "llvm/ADT/Statistic.h"18#include "llvm/CodeGen/LivePhysRegs.h"19#include "llvm/CodeGen/MachineFunctionPass.h"20#include "llvm/CodeGen/MachineInstrBuilder.h"21#include "llvm/CodeGen/MachineRegisterInfo.h"22#include "llvm/Support/CommandLine.h"23#include "llvm/Support/Debug.h"24#include "llvm/Support/raw_ostream.h"2526using namespace llvm;2728#define DEBUG_TYPE "ppc-expand-isel"2930STATISTIC(NumExpanded, "Number of ISEL instructions expanded");31STATISTIC(NumRemoved, "Number of ISEL instructions removed");32STATISTIC(NumFolded, "Number of ISEL instructions folded");3334// If -ppc-gen-isel=false is set, we will disable generating the ISEL35// instruction on all PPC targets. Otherwise, if the user set option36// -misel or the platform supports ISEL by default, still generate the37// ISEL instruction, else expand it.38static cl::opt<bool>39GenerateISEL("ppc-gen-isel",40cl::desc("Enable generating the ISEL instruction."),41cl::init(true), cl::Hidden);4243namespace {44class PPCExpandISEL : public MachineFunctionPass {45DebugLoc dl;46MachineFunction *MF;47const TargetInstrInfo *TII;48bool IsTrueBlockRequired;49bool IsFalseBlockRequired;50MachineBasicBlock *TrueBlock;51MachineBasicBlock *FalseBlock;52MachineBasicBlock *NewSuccessor;53MachineBasicBlock::iterator TrueBlockI;54MachineBasicBlock::iterator FalseBlockI;5556typedef SmallVector<MachineInstr *, 4> BlockISELList;57typedef SmallDenseMap<int, BlockISELList> ISELInstructionList;5859// A map of MBB numbers to their lists of contained ISEL instructions.60// Please note when we traverse this list and expand ISEL, we only remove61// the ISEL from the MBB not from this list.62ISELInstructionList ISELInstructions;6364/// Initialize the object.65void initialize(MachineFunction &MFParam);6667void handleSpecialCases(BlockISELList &BIL, MachineBasicBlock *MBB);68void reorganizeBlockLayout(BlockISELList &BIL, MachineBasicBlock *MBB);69void populateBlocks(BlockISELList &BIL);70void expandMergeableISELs(BlockISELList &BIL);71void expandAndMergeISELs();7273bool canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI);7475/// Is this instruction an ISEL or ISEL8?76static bool isISEL(const MachineInstr &MI) {77return (MI.getOpcode() == PPC::ISEL || MI.getOpcode() == PPC::ISEL8);78}7980/// Is this instruction an ISEL8?81static bool isISEL8(const MachineInstr &MI) {82return (MI.getOpcode() == PPC::ISEL8);83}8485/// Are the two operands using the same register?86bool useSameRegister(const MachineOperand &Op1, const MachineOperand &Op2) {87return (Op1.getReg() == Op2.getReg());88}8990///91/// Collect all ISEL instructions from the current function.92///93/// Walk the current function and collect all the ISEL instructions that are94/// found. The instructions are placed in the ISELInstructions vector.95///96/// \return true if any ISEL instructions were found, false otherwise97///98bool collectISELInstructions();99100public:101static char ID;102PPCExpandISEL() : MachineFunctionPass(ID) {103initializePPCExpandISELPass(*PassRegistry::getPassRegistry());104}105106///107/// Determine whether to generate the ISEL instruction or expand it.108///109/// Expand ISEL instruction into if-then-else sequence when one of110/// the following two conditions hold:111/// (1) -ppc-gen-isel=false112/// (2) hasISEL() return false113/// Otherwise, still generate ISEL instruction.114/// The -ppc-gen-isel option is set to true by default. Which means the ISEL115/// instruction is still generated by default on targets that support them.116///117/// \return true if ISEL should be expanded into if-then-else code sequence;118/// false if ISEL instruction should be generated, i.e. not expanded.119///120static bool isExpandISELEnabled(const MachineFunction &MF);121122#ifndef NDEBUG123void DumpISELInstructions() const;124#endif125126bool runOnMachineFunction(MachineFunction &MF) override {127LLVM_DEBUG(dbgs() << "Function: "; MF.dump(); dbgs() << "\n");128initialize(MF);129130if (!collectISELInstructions()) {131LLVM_DEBUG(dbgs() << "No ISEL instructions in this function\n");132return false;133}134135#ifndef NDEBUG136DumpISELInstructions();137#endif138139expandAndMergeISELs();140141return true;142}143};144} // end anonymous namespace145146void PPCExpandISEL::initialize(MachineFunction &MFParam) {147MF = &MFParam;148TII = MF->getSubtarget().getInstrInfo();149ISELInstructions.clear();150}151152bool PPCExpandISEL::isExpandISELEnabled(const MachineFunction &MF) {153return !GenerateISEL || !MF.getSubtarget<PPCSubtarget>().hasISEL();154}155156bool PPCExpandISEL::collectISELInstructions() {157for (MachineBasicBlock &MBB : *MF) {158BlockISELList thisBlockISELs;159for (MachineInstr &MI : MBB)160if (isISEL(MI))161thisBlockISELs.push_back(&MI);162if (!thisBlockISELs.empty())163ISELInstructions.insert(std::make_pair(MBB.getNumber(), thisBlockISELs));164}165return !ISELInstructions.empty();166}167168#ifndef NDEBUG169void PPCExpandISEL::DumpISELInstructions() const {170for (const auto &I : ISELInstructions) {171LLVM_DEBUG(dbgs() << printMBBReference(*MF->getBlockNumbered(I.first))172<< ":\n");173for (const auto &VI : I.second)174LLVM_DEBUG(dbgs() << " "; VI->print(dbgs()));175}176}177#endif178179/// Contiguous ISELs that have the same condition can be merged.180bool PPCExpandISEL::canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI) {181// Same Condition Register?182if (!useSameRegister(PrevPushedMI->getOperand(3), MI->getOperand(3)))183return false;184185MachineBasicBlock::iterator PrevPushedMBBI = *PrevPushedMI;186MachineBasicBlock::iterator MBBI = *MI;187return (std::prev(MBBI) == PrevPushedMBBI); // Contiguous ISELs?188}189190void PPCExpandISEL::expandAndMergeISELs() {191bool ExpandISELEnabled = isExpandISELEnabled(*MF);192193for (auto &BlockList : ISELInstructions) {194LLVM_DEBUG(195dbgs() << "Expanding ISEL instructions in "196<< printMBBReference(*MF->getBlockNumbered(BlockList.first))197<< "\n");198BlockISELList &CurrentISELList = BlockList.second;199auto I = CurrentISELList.begin();200auto E = CurrentISELList.end();201202while (I != E) {203assert(isISEL(**I) && "Expecting an ISEL instruction");204MachineOperand &Dest = (*I)->getOperand(0);205MachineOperand &TrueValue = (*I)->getOperand(1);206MachineOperand &FalseValue = (*I)->getOperand(2);207208// Special case 1, all registers used by ISEL are the same one.209// The non-redundant isel 0, 0, 0, N would not satisfy these conditions210// as it would be ISEL %R0, %ZERO, %R0, %CRN.211if (useSameRegister(Dest, TrueValue) &&212useSameRegister(Dest, FalseValue)) {213LLVM_DEBUG(dbgs() << "Remove redundant ISEL instruction: " << **I214<< "\n");215// FIXME: if the CR field used has no other uses, we could eliminate the216// instruction that defines it. This would have to be done manually217// since this pass runs too late to run DCE after it.218NumRemoved++;219(*I)->eraseFromParent();220I++;221} else if (useSameRegister(TrueValue, FalseValue)) {222// Special case 2, the two input registers used by ISEL are the same.223// Note: the non-foldable isel RX, 0, 0, N would not satisfy this224// condition as it would be ISEL %RX, %ZERO, %R0, %CRN, which makes it225// safe to fold ISEL to MR(OR) instead of ADDI.226MachineBasicBlock *MBB = (*I)->getParent();227LLVM_DEBUG(228dbgs() << "Fold the ISEL instruction to an unconditional copy:\n");229LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n");230NumFolded++;231// Note: we're using both the TrueValue and FalseValue operands so as232// not to lose the kill flag if it is set on either of them.233BuildMI(*MBB, (*I), dl, TII->get(isISEL8(**I) ? PPC::OR8 : PPC::OR))234.add(Dest)235.add(TrueValue)236.add(FalseValue);237(*I)->eraseFromParent();238I++;239} else if (ExpandISELEnabled) { // Normal cases expansion enabled240LLVM_DEBUG(dbgs() << "Expand ISEL instructions:\n");241LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n");242BlockISELList SubISELList;243SubISELList.push_back(*I++);244// Collect the ISELs that can be merged together.245// This will eat up ISEL instructions without considering whether they246// may be redundant or foldable to a register copy. So we still keep247// the handleSpecialCases() downstream to handle them.248while (I != E && canMerge(SubISELList.back(), *I)) {249LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n");250SubISELList.push_back(*I++);251}252253expandMergeableISELs(SubISELList);254} else { // Normal cases expansion disabled255I++; // leave the ISEL as it is256}257} // end while258} // end for259}260261void PPCExpandISEL::handleSpecialCases(BlockISELList &BIL,262MachineBasicBlock *MBB) {263IsTrueBlockRequired = false;264IsFalseBlockRequired = false;265266auto MI = BIL.begin();267while (MI != BIL.end()) {268assert(isISEL(**MI) && "Expecting an ISEL instruction");269LLVM_DEBUG(dbgs() << "ISEL: " << **MI << "\n");270271MachineOperand &Dest = (*MI)->getOperand(0);272MachineOperand &TrueValue = (*MI)->getOperand(1);273MachineOperand &FalseValue = (*MI)->getOperand(2);274275// If at least one of the ISEL instructions satisfy the following276// condition, we need the True Block:277// The Dest Register and True Value Register are not the same278// Similarly, if at least one of the ISEL instructions satisfy the279// following condition, we need the False Block:280// The Dest Register and False Value Register are not the same.281bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);282bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);283284// Special case 1, all registers used by ISEL are the same one.285if (!IsADDIInstRequired && !IsORIInstRequired) {286LLVM_DEBUG(dbgs() << "Remove redundant ISEL instruction.");287// FIXME: if the CR field used has no other uses, we could eliminate the288// instruction that defines it. This would have to be done manually289// since this pass runs too late to run DCE after it.290NumRemoved++;291(*MI)->eraseFromParent();292// Setting MI to the erase result keeps the iterator valid and increased.293MI = BIL.erase(MI);294continue;295}296297// Special case 2, the two input registers used by ISEL are the same.298// Note 1: We favor merging ISEL expansions over folding a single one. If299// the passed list has multiple merge-able ISEL's, we won't fold any.300// Note 2: There is no need to test for PPC::R0/PPC::X0 because PPC::ZERO/301// PPC::ZERO8 will be used for the first operand if the value is meant to302// be zero. In this case, the useSameRegister method will return false,303// thereby preventing this ISEL from being folded.304if (useSameRegister(TrueValue, FalseValue) && (BIL.size() == 1)) {305LLVM_DEBUG(306dbgs() << "Fold the ISEL instruction to an unconditional copy.");307NumFolded++;308// Note: we're using both the TrueValue and FalseValue operands so as309// not to lose the kill flag if it is set on either of them.310BuildMI(*MBB, (*MI), dl, TII->get(isISEL8(**MI) ? PPC::OR8 : PPC::OR))311.add(Dest)312.add(TrueValue)313.add(FalseValue);314(*MI)->eraseFromParent();315// Setting MI to the erase result keeps the iterator valid and increased.316MI = BIL.erase(MI);317continue;318}319320IsTrueBlockRequired |= IsADDIInstRequired;321IsFalseBlockRequired |= IsORIInstRequired;322MI++;323}324}325326void PPCExpandISEL::reorganizeBlockLayout(BlockISELList &BIL,327MachineBasicBlock *MBB) {328if (BIL.empty())329return;330331assert((IsTrueBlockRequired || IsFalseBlockRequired) &&332"Should have been handled by special cases earlier!");333334MachineBasicBlock *Successor = nullptr;335const BasicBlock *LLVM_BB = MBB->getBasicBlock();336MachineBasicBlock::iterator MBBI = (*BIL.back());337NewSuccessor = (MBBI != MBB->getLastNonDebugInstr() || !MBB->canFallThrough())338// Another BB is needed to move the instructions that339// follow this ISEL. If the ISEL is the last instruction340// in a block that can't fall through, we also need a block341// to branch to.342? MF->CreateMachineBasicBlock(LLVM_BB)343: nullptr;344345MachineFunction::iterator It = MBB->getIterator();346++It; // Point to the successor block of MBB.347348// If NewSuccessor is NULL then the last ISEL in this group is the last349// non-debug instruction in this block. Find the fall-through successor350// of this block to use when updating the CFG below.351if (!NewSuccessor) {352for (auto &Succ : MBB->successors()) {353if (MBB->isLayoutSuccessor(Succ)) {354Successor = Succ;355break;356}357}358} else359Successor = NewSuccessor;360361// The FalseBlock and TrueBlock are inserted after the MBB block but before362// its successor.363// Note this need to be done *after* the above setting the Successor code.364if (IsFalseBlockRequired) {365FalseBlock = MF->CreateMachineBasicBlock(LLVM_BB);366MF->insert(It, FalseBlock);367}368369if (IsTrueBlockRequired) {370TrueBlock = MF->CreateMachineBasicBlock(LLVM_BB);371MF->insert(It, TrueBlock);372}373374if (NewSuccessor) {375MF->insert(It, NewSuccessor);376377// Transfer the rest of this block into the new successor block.378NewSuccessor->splice(NewSuccessor->end(), MBB,379std::next(MachineBasicBlock::iterator(BIL.back())),380MBB->end());381NewSuccessor->transferSuccessorsAndUpdatePHIs(MBB);382383// Update the liveins for NewSuccessor.384LivePhysRegs LPR;385computeAndAddLiveIns(LPR, *NewSuccessor);386387} else {388// Remove successor from MBB.389MBB->removeSuccessor(Successor);390}391392// Note that this needs to be done *after* transfering the successors from MBB393// to the NewSuccessor block, otherwise these blocks will also be transferred394// as successors!395MBB->addSuccessor(IsTrueBlockRequired ? TrueBlock : Successor);396MBB->addSuccessor(IsFalseBlockRequired ? FalseBlock : Successor);397398if (IsTrueBlockRequired) {399TrueBlockI = TrueBlock->begin();400TrueBlock->addSuccessor(Successor);401}402403if (IsFalseBlockRequired) {404FalseBlockI = FalseBlock->begin();405FalseBlock->addSuccessor(Successor);406}407408// Conditional branch to the TrueBlock or Successor409BuildMI(*MBB, BIL.back(), dl, TII->get(PPC::BC))410.add(BIL.back()->getOperand(3))411.addMBB(IsTrueBlockRequired ? TrueBlock : Successor);412413// Jump over the true block to the new successor if the condition is false.414BuildMI(*(IsFalseBlockRequired ? FalseBlock : MBB),415(IsFalseBlockRequired ? FalseBlockI : BIL.back()), dl,416TII->get(PPC::B))417.addMBB(Successor);418419if (IsFalseBlockRequired)420FalseBlockI = FalseBlock->begin(); // get the position of PPC::B421}422423void PPCExpandISEL::populateBlocks(BlockISELList &BIL) {424for (auto &MI : BIL) {425assert(isISEL(*MI) && "Expecting an ISEL instruction");426427MachineOperand &Dest = MI->getOperand(0); // location to store to428MachineOperand &TrueValue = MI->getOperand(1); // Value to store if429// condition is true430MachineOperand &FalseValue = MI->getOperand(2); // Value to store if431// condition is false432433LLVM_DEBUG(dbgs() << "Dest: " << Dest << "\n");434LLVM_DEBUG(dbgs() << "TrueValue: " << TrueValue << "\n");435LLVM_DEBUG(dbgs() << "FalseValue: " << FalseValue << "\n");436LLVM_DEBUG(dbgs() << "ConditionRegister: " << MI->getOperand(3) << "\n");437438// If the Dest Register and True Value Register are not the same one, we439// need the True Block.440bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);441bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);442443// Copy the result into the destination if the condition is true.444if (IsADDIInstRequired)445BuildMI(*TrueBlock, TrueBlockI, dl,446TII->get(isISEL8(*MI) ? PPC::ADDI8 : PPC::ADDI))447.add(Dest)448.add(TrueValue)449.add(MachineOperand::CreateImm(0));450451// Copy the result into the destination if the condition is false.452if (IsORIInstRequired)453BuildMI(*FalseBlock, FalseBlockI, dl,454TII->get(isISEL8(*MI) ? PPC::ORI8 : PPC::ORI))455.add(Dest)456.add(FalseValue)457.add(MachineOperand::CreateImm(0));458459MI->eraseFromParent(); // Remove the ISEL instruction.460461NumExpanded++;462}463464if (IsTrueBlockRequired) {465// Update the liveins for TrueBlock.466LivePhysRegs LPR;467computeAndAddLiveIns(LPR, *TrueBlock);468}469470if (IsFalseBlockRequired) {471// Update the liveins for FalseBlock.472LivePhysRegs LPR;473computeAndAddLiveIns(LPR, *FalseBlock);474}475}476477void PPCExpandISEL::expandMergeableISELs(BlockISELList &BIL) {478// At this stage all the ISELs of BIL are in the same MBB.479MachineBasicBlock *MBB = BIL.back()->getParent();480481handleSpecialCases(BIL, MBB);482reorganizeBlockLayout(BIL, MBB);483populateBlocks(BIL);484}485486INITIALIZE_PASS(PPCExpandISEL, DEBUG_TYPE, "PowerPC Expand ISEL Generation",487false, false)488char PPCExpandISEL::ID = 0;489490FunctionPass *llvm::createPPCExpandISELPass() { return new PPCExpandISEL(); }491492493