492 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			492 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
//===------------- PPCExpandISEL.cpp - Expand ISEL instruction ------------===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
// A pass that expands the ISEL instruction into an if-then-else sequence.
 | 
						|
// This pass must be run post-RA since all operands must be physical registers.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "PPC.h"
 | 
						|
#include "PPCInstrInfo.h"
 | 
						|
#include "PPCSubtarget.h"
 | 
						|
#include "llvm/ADT/DenseMap.h"
 | 
						|
#include "llvm/ADT/Statistic.h"
 | 
						|
#include "llvm/CodeGen/LivePhysRegs.h"
 | 
						|
#include "llvm/CodeGen/MachineFunctionPass.h"
 | 
						|
#include "llvm/CodeGen/MachineInstrBuilder.h"
 | 
						|
#include "llvm/CodeGen/MachineRegisterInfo.h"
 | 
						|
#include "llvm/Support/CommandLine.h"
 | 
						|
#include "llvm/Support/Debug.h"
 | 
						|
#include "llvm/Support/raw_ostream.h"
 | 
						|
 | 
						|
using namespace llvm;
 | 
						|
 | 
						|
#define DEBUG_TYPE "ppc-expand-isel"
 | 
						|
 | 
						|
STATISTIC(NumExpanded, "Number of ISEL instructions expanded");
 | 
						|
STATISTIC(NumRemoved, "Number of ISEL instructions removed");
 | 
						|
STATISTIC(NumFolded, "Number of ISEL instructions folded");
 | 
						|
 | 
						|
// If -ppc-gen-isel=false is set, we will disable generating the ISEL
 | 
						|
// instruction on all PPC targets. Otherwise, if the user set option
 | 
						|
// -misel or the platform supports ISEL by default, still generate the
 | 
						|
// ISEL instruction, else expand it.
 | 
						|
static cl::opt<bool>
 | 
						|
    GenerateISEL("ppc-gen-isel",
 | 
						|
                 cl::desc("Enable generating the ISEL instruction."),
 | 
						|
                 cl::init(true), cl::Hidden);
 | 
						|
 | 
						|
namespace {
 | 
						|
class PPCExpandISEL : public MachineFunctionPass {
 | 
						|
  DebugLoc dl;
 | 
						|
  MachineFunction *MF;
 | 
						|
  const TargetInstrInfo *TII;
 | 
						|
  bool IsTrueBlockRequired;
 | 
						|
  bool IsFalseBlockRequired;
 | 
						|
  MachineBasicBlock *TrueBlock;
 | 
						|
  MachineBasicBlock *FalseBlock;
 | 
						|
  MachineBasicBlock *NewSuccessor;
 | 
						|
  MachineBasicBlock::iterator TrueBlockI;
 | 
						|
  MachineBasicBlock::iterator FalseBlockI;
 | 
						|
 | 
						|
  typedef SmallVector<MachineInstr *, 4> BlockISELList;
 | 
						|
  typedef SmallDenseMap<int, BlockISELList> ISELInstructionList;
 | 
						|
 | 
						|
  // A map of MBB numbers to their lists of contained ISEL instructions.
 | 
						|
  // Please note when we traverse this list and expand ISEL, we only remove
 | 
						|
  // the ISEL from the MBB not from this list.
 | 
						|
  ISELInstructionList ISELInstructions;
 | 
						|
 | 
						|
  /// Initialize the object.
 | 
						|
  void initialize(MachineFunction &MFParam);
 | 
						|
 | 
						|
  void handleSpecialCases(BlockISELList &BIL, MachineBasicBlock *MBB);
 | 
						|
  void reorganizeBlockLayout(BlockISELList &BIL, MachineBasicBlock *MBB);
 | 
						|
  void populateBlocks(BlockISELList &BIL);
 | 
						|
  void expandMergeableISELs(BlockISELList &BIL);
 | 
						|
  void expandAndMergeISELs();
 | 
						|
 | 
						|
  bool canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI);
 | 
						|
 | 
						|
  ///  Is this instruction an ISEL or ISEL8?
 | 
						|
  static bool isISEL(const MachineInstr &MI) {
 | 
						|
    return (MI.getOpcode() == PPC::ISEL || MI.getOpcode() == PPC::ISEL8);
 | 
						|
  }
 | 
						|
 | 
						|
  ///  Is this instruction an ISEL8?
 | 
						|
  static bool isISEL8(const MachineInstr &MI) {
 | 
						|
    return (MI.getOpcode() == PPC::ISEL8);
 | 
						|
  }
 | 
						|
 | 
						|
  /// Are the two operands using the same register?
 | 
						|
  bool useSameRegister(const MachineOperand &Op1, const MachineOperand &Op2) {
 | 
						|
    return (Op1.getReg() == Op2.getReg());
 | 
						|
  }
 | 
						|
 | 
						|
  ///
 | 
						|
  ///  Collect all ISEL instructions from the current function.
 | 
						|
  ///
 | 
						|
  /// Walk the current function and collect all the ISEL instructions that are
 | 
						|
  /// found. The instructions are placed in the ISELInstructions vector.
 | 
						|
  ///
 | 
						|
  /// \return true if any ISEL instructions were found, false otherwise
 | 
						|
  ///
 | 
						|
  bool collectISELInstructions();
 | 
						|
 | 
						|
public:
 | 
						|
  static char ID;
 | 
						|
  PPCExpandISEL() : MachineFunctionPass(ID) {
 | 
						|
    initializePPCExpandISELPass(*PassRegistry::getPassRegistry());
 | 
						|
  }
 | 
						|
 | 
						|
  ///
 | 
						|
  ///  Determine whether to generate the ISEL instruction or expand it.
 | 
						|
  ///
 | 
						|
  /// Expand ISEL instruction into if-then-else sequence when one of
 | 
						|
  /// the following two conditions hold:
 | 
						|
  /// (1) -ppc-gen-isel=false
 | 
						|
  /// (2) hasISEL() return false
 | 
						|
  /// Otherwise, still generate ISEL instruction.
 | 
						|
  /// The -ppc-gen-isel option is set to true by default. Which means the ISEL
 | 
						|
  /// instruction is still generated by default on targets that support them.
 | 
						|
  ///
 | 
						|
  /// \return true if ISEL should be expanded into if-then-else code sequence;
 | 
						|
  ///         false if ISEL instruction should be generated, i.e. not expanded.
 | 
						|
  ///
 | 
						|
  static bool isExpandISELEnabled(const MachineFunction &MF);
 | 
						|
 | 
						|
#ifndef NDEBUG
 | 
						|
  void DumpISELInstructions() const;
 | 
						|
#endif
 | 
						|
 | 
						|
  bool runOnMachineFunction(MachineFunction &MF) override {
 | 
						|
    LLVM_DEBUG(dbgs() << "Function: "; MF.dump(); dbgs() << "\n");
 | 
						|
    initialize(MF);
 | 
						|
 | 
						|
    if (!collectISELInstructions()) {
 | 
						|
      LLVM_DEBUG(dbgs() << "No ISEL instructions in this function\n");
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
#ifndef NDEBUG
 | 
						|
    DumpISELInstructions();
 | 
						|
#endif
 | 
						|
 | 
						|
    expandAndMergeISELs();
 | 
						|
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
};
 | 
						|
} // end anonymous namespace
 | 
						|
 | 
						|
void PPCExpandISEL::initialize(MachineFunction &MFParam) {
 | 
						|
  MF = &MFParam;
 | 
						|
  TII = MF->getSubtarget().getInstrInfo();
 | 
						|
  ISELInstructions.clear();
 | 
						|
}
 | 
						|
 | 
						|
bool PPCExpandISEL::isExpandISELEnabled(const MachineFunction &MF) {
 | 
						|
  return !GenerateISEL || !MF.getSubtarget<PPCSubtarget>().hasISEL();
 | 
						|
}
 | 
						|
 | 
						|
bool PPCExpandISEL::collectISELInstructions() {
 | 
						|
  for (MachineBasicBlock &MBB : *MF) {
 | 
						|
    BlockISELList thisBlockISELs;
 | 
						|
    for (MachineInstr &MI : MBB)
 | 
						|
      if (isISEL(MI))
 | 
						|
        thisBlockISELs.push_back(&MI);
 | 
						|
    if (!thisBlockISELs.empty())
 | 
						|
      ISELInstructions.insert(std::make_pair(MBB.getNumber(), thisBlockISELs));
 | 
						|
  }
 | 
						|
  return !ISELInstructions.empty();
 | 
						|
}
 | 
						|
 | 
						|
#ifndef NDEBUG
 | 
						|
void PPCExpandISEL::DumpISELInstructions() const {
 | 
						|
  for (const auto &I : ISELInstructions) {
 | 
						|
    LLVM_DEBUG(dbgs() << printMBBReference(*MF->getBlockNumbered(I.first))
 | 
						|
                      << ":\n");
 | 
						|
    for (const auto &VI : I.second)
 | 
						|
      LLVM_DEBUG(dbgs() << "    "; VI->print(dbgs()));
 | 
						|
  }
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
/// Contiguous ISELs that have the same condition can be merged.
 | 
						|
bool PPCExpandISEL::canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI) {
 | 
						|
  // Same Condition Register?
 | 
						|
  if (!useSameRegister(PrevPushedMI->getOperand(3), MI->getOperand(3)))
 | 
						|
    return false;
 | 
						|
 | 
						|
  MachineBasicBlock::iterator PrevPushedMBBI = *PrevPushedMI;
 | 
						|
  MachineBasicBlock::iterator MBBI = *MI;
 | 
						|
  return (std::prev(MBBI) == PrevPushedMBBI); // Contiguous ISELs?
 | 
						|
}
 | 
						|
 | 
						|
void PPCExpandISEL::expandAndMergeISELs() {
 | 
						|
  bool ExpandISELEnabled = isExpandISELEnabled(*MF);
 | 
						|
 | 
						|
  for (auto &BlockList : ISELInstructions) {
 | 
						|
    LLVM_DEBUG(
 | 
						|
        dbgs() << "Expanding ISEL instructions in "
 | 
						|
               << printMBBReference(*MF->getBlockNumbered(BlockList.first))
 | 
						|
               << "\n");
 | 
						|
    BlockISELList &CurrentISELList = BlockList.second;
 | 
						|
    auto I = CurrentISELList.begin();
 | 
						|
    auto E = CurrentISELList.end();
 | 
						|
 | 
						|
    while (I != E) {
 | 
						|
      assert(isISEL(**I) && "Expecting an ISEL instruction");
 | 
						|
      MachineOperand &Dest = (*I)->getOperand(0);
 | 
						|
      MachineOperand &TrueValue = (*I)->getOperand(1);
 | 
						|
      MachineOperand &FalseValue = (*I)->getOperand(2);
 | 
						|
 | 
						|
      // Special case 1, all registers used by ISEL are the same one.
 | 
						|
      // The non-redundant isel 0, 0, 0, N would not satisfy these conditions
 | 
						|
      // as it would be ISEL %R0, %ZERO, %R0, %CRN.
 | 
						|
      if (useSameRegister(Dest, TrueValue) &&
 | 
						|
          useSameRegister(Dest, FalseValue)) {
 | 
						|
        LLVM_DEBUG(dbgs() << "Remove redundant ISEL instruction: " << **I
 | 
						|
                          << "\n");
 | 
						|
        // FIXME: if the CR field used has no other uses, we could eliminate the
 | 
						|
        // instruction that defines it. This would have to be done manually
 | 
						|
        // since this pass runs too late to run DCE after it.
 | 
						|
        NumRemoved++;
 | 
						|
        (*I)->eraseFromParent();
 | 
						|
        I++;
 | 
						|
      } else if (useSameRegister(TrueValue, FalseValue)) {
 | 
						|
        // Special case 2, the two input registers used by ISEL are the same.
 | 
						|
        // Note: the non-foldable isel RX, 0, 0, N would not satisfy this
 | 
						|
        // condition as it would be ISEL %RX, %ZERO, %R0, %CRN, which makes it
 | 
						|
        // safe to fold ISEL to MR(OR) instead of ADDI.
 | 
						|
        MachineBasicBlock *MBB = (*I)->getParent();
 | 
						|
        LLVM_DEBUG(
 | 
						|
            dbgs() << "Fold the ISEL instruction to an unconditional copy:\n");
 | 
						|
        LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n");
 | 
						|
        NumFolded++;
 | 
						|
        // Note: we're using both the TrueValue and FalseValue operands so as
 | 
						|
        // not to lose the kill flag if it is set on either of them.
 | 
						|
        BuildMI(*MBB, (*I), dl, TII->get(isISEL8(**I) ? PPC::OR8 : PPC::OR))
 | 
						|
            .add(Dest)
 | 
						|
            .add(TrueValue)
 | 
						|
            .add(FalseValue);
 | 
						|
        (*I)->eraseFromParent();
 | 
						|
        I++;
 | 
						|
      } else if (ExpandISELEnabled) { // Normal cases expansion enabled
 | 
						|
        LLVM_DEBUG(dbgs() << "Expand ISEL instructions:\n");
 | 
						|
        LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n");
 | 
						|
        BlockISELList SubISELList;
 | 
						|
        SubISELList.push_back(*I++);
 | 
						|
        // Collect the ISELs that can be merged together.
 | 
						|
        // This will eat up ISEL instructions without considering whether they
 | 
						|
        // may be redundant or foldable to a register copy. So we still keep
 | 
						|
        // the handleSpecialCases() downstream to handle them.
 | 
						|
        while (I != E && canMerge(SubISELList.back(), *I)) {
 | 
						|
          LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n");
 | 
						|
          SubISELList.push_back(*I++);
 | 
						|
        }
 | 
						|
 | 
						|
        expandMergeableISELs(SubISELList);
 | 
						|
      } else { // Normal cases expansion disabled
 | 
						|
        I++; // leave the ISEL as it is
 | 
						|
      }
 | 
						|
    } // end while
 | 
						|
  } // end for
 | 
						|
}
 | 
						|
 | 
						|
void PPCExpandISEL::handleSpecialCases(BlockISELList &BIL,
 | 
						|
                                       MachineBasicBlock *MBB) {
 | 
						|
  IsTrueBlockRequired = false;
 | 
						|
  IsFalseBlockRequired = false;
 | 
						|
 | 
						|
  auto MI = BIL.begin();
 | 
						|
  while (MI != BIL.end()) {
 | 
						|
    assert(isISEL(**MI) && "Expecting an ISEL instruction");
 | 
						|
    LLVM_DEBUG(dbgs() << "ISEL: " << **MI << "\n");
 | 
						|
 | 
						|
    MachineOperand &Dest = (*MI)->getOperand(0);
 | 
						|
    MachineOperand &TrueValue = (*MI)->getOperand(1);
 | 
						|
    MachineOperand &FalseValue = (*MI)->getOperand(2);
 | 
						|
 | 
						|
    // If at least one of the ISEL instructions satisfy the following
 | 
						|
    // condition, we need the True Block:
 | 
						|
    // The Dest Register and True Value Register are not the same
 | 
						|
    // Similarly, if at least one of the ISEL instructions satisfy the
 | 
						|
    // following condition, we need the False Block:
 | 
						|
    // The Dest Register and False Value Register are not the same.
 | 
						|
    bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);
 | 
						|
    bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);
 | 
						|
 | 
						|
    // Special case 1, all registers used by ISEL are the same one.
 | 
						|
    if (!IsADDIInstRequired && !IsORIInstRequired) {
 | 
						|
      LLVM_DEBUG(dbgs() << "Remove redundant ISEL instruction.");
 | 
						|
      // FIXME: if the CR field used has no other uses, we could eliminate the
 | 
						|
      // instruction that defines it. This would have to be done manually
 | 
						|
      // since this pass runs too late to run DCE after it.
 | 
						|
      NumRemoved++;
 | 
						|
      (*MI)->eraseFromParent();
 | 
						|
      // Setting MI to the erase result keeps the iterator valid and increased.
 | 
						|
      MI = BIL.erase(MI);
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    // Special case 2, the two input registers used by ISEL are the same.
 | 
						|
    // Note 1: We favor merging ISEL expansions over folding a single one. If
 | 
						|
    // the passed list has multiple merge-able ISEL's, we won't fold any.
 | 
						|
    // Note 2: There is no need to test for PPC::R0/PPC::X0 because PPC::ZERO/
 | 
						|
    // PPC::ZERO8 will be used for the first operand if the value is meant to
 | 
						|
    // be zero. In this case, the useSameRegister method will return false,
 | 
						|
    // thereby preventing this ISEL from being folded.
 | 
						|
    if (useSameRegister(TrueValue, FalseValue) && (BIL.size() == 1)) {
 | 
						|
      LLVM_DEBUG(
 | 
						|
          dbgs() << "Fold the ISEL instruction to an unconditional copy.");
 | 
						|
      NumFolded++;
 | 
						|
      // Note: we're using both the TrueValue and FalseValue operands so as
 | 
						|
      // not to lose the kill flag if it is set on either of them.
 | 
						|
      BuildMI(*MBB, (*MI), dl, TII->get(isISEL8(**MI) ? PPC::OR8 : PPC::OR))
 | 
						|
          .add(Dest)
 | 
						|
          .add(TrueValue)
 | 
						|
          .add(FalseValue);
 | 
						|
      (*MI)->eraseFromParent();
 | 
						|
      // Setting MI to the erase result keeps the iterator valid and increased.
 | 
						|
      MI = BIL.erase(MI);
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    IsTrueBlockRequired |= IsADDIInstRequired;
 | 
						|
    IsFalseBlockRequired |= IsORIInstRequired;
 | 
						|
    MI++;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void PPCExpandISEL::reorganizeBlockLayout(BlockISELList &BIL,
 | 
						|
                                          MachineBasicBlock *MBB) {
 | 
						|
  if (BIL.empty())
 | 
						|
    return;
 | 
						|
 | 
						|
  assert((IsTrueBlockRequired || IsFalseBlockRequired) &&
 | 
						|
         "Should have been handled by special cases earlier!");
 | 
						|
 | 
						|
  MachineBasicBlock *Successor = nullptr;
 | 
						|
  const BasicBlock *LLVM_BB = MBB->getBasicBlock();
 | 
						|
  MachineBasicBlock::iterator MBBI = (*BIL.back());
 | 
						|
  NewSuccessor = (MBBI != MBB->getLastNonDebugInstr() || !MBB->canFallThrough())
 | 
						|
                     // Another BB is needed to move the instructions that
 | 
						|
                     // follow this ISEL.  If the ISEL is the last instruction
 | 
						|
                     // in a block that can't fall through, we also need a block
 | 
						|
                     // to branch to.
 | 
						|
                     ? MF->CreateMachineBasicBlock(LLVM_BB)
 | 
						|
                     : nullptr;
 | 
						|
 | 
						|
  MachineFunction::iterator It = MBB->getIterator();
 | 
						|
  ++It; // Point to the successor block of MBB.
 | 
						|
 | 
						|
  // If NewSuccessor is NULL then the last ISEL in this group is the last
 | 
						|
  // non-debug instruction in this block. Find the fall-through successor
 | 
						|
  // of this block to use when updating the CFG below.
 | 
						|
  if (!NewSuccessor) {
 | 
						|
    for (auto &Succ : MBB->successors()) {
 | 
						|
      if (MBB->isLayoutSuccessor(Succ)) {
 | 
						|
        Successor = Succ;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  } else
 | 
						|
    Successor = NewSuccessor;
 | 
						|
 | 
						|
  // The FalseBlock and TrueBlock are inserted after the MBB block but before
 | 
						|
  // its successor.
 | 
						|
  // Note this need to be done *after* the above setting the Successor code.
 | 
						|
  if (IsFalseBlockRequired) {
 | 
						|
    FalseBlock = MF->CreateMachineBasicBlock(LLVM_BB);
 | 
						|
    MF->insert(It, FalseBlock);
 | 
						|
  }
 | 
						|
 | 
						|
  if (IsTrueBlockRequired) {
 | 
						|
    TrueBlock = MF->CreateMachineBasicBlock(LLVM_BB);
 | 
						|
    MF->insert(It, TrueBlock);
 | 
						|
  }
 | 
						|
 | 
						|
  if (NewSuccessor) {
 | 
						|
    MF->insert(It, NewSuccessor);
 | 
						|
 | 
						|
    // Transfer the rest of this block into the new successor block.
 | 
						|
    NewSuccessor->splice(NewSuccessor->end(), MBB,
 | 
						|
                         std::next(MachineBasicBlock::iterator(BIL.back())),
 | 
						|
                         MBB->end());
 | 
						|
    NewSuccessor->transferSuccessorsAndUpdatePHIs(MBB);
 | 
						|
 | 
						|
    // Update the liveins for NewSuccessor.
 | 
						|
    LivePhysRegs LPR;
 | 
						|
    computeAndAddLiveIns(LPR, *NewSuccessor);
 | 
						|
 | 
						|
  } else {
 | 
						|
    // Remove successor from MBB.
 | 
						|
    MBB->removeSuccessor(Successor);
 | 
						|
  }
 | 
						|
 | 
						|
  // Note that this needs to be done *after* transfering the successors from MBB
 | 
						|
  // to the NewSuccessor block, otherwise these blocks will also be transferred
 | 
						|
  // as successors!
 | 
						|
  MBB->addSuccessor(IsTrueBlockRequired ? TrueBlock : Successor);
 | 
						|
  MBB->addSuccessor(IsFalseBlockRequired ? FalseBlock : Successor);
 | 
						|
 | 
						|
  if (IsTrueBlockRequired) {
 | 
						|
    TrueBlockI = TrueBlock->begin();
 | 
						|
    TrueBlock->addSuccessor(Successor);
 | 
						|
  }
 | 
						|
 | 
						|
  if (IsFalseBlockRequired) {
 | 
						|
    FalseBlockI = FalseBlock->begin();
 | 
						|
    FalseBlock->addSuccessor(Successor);
 | 
						|
  }
 | 
						|
 | 
						|
  // Conditional branch to the TrueBlock or Successor
 | 
						|
  BuildMI(*MBB, BIL.back(), dl, TII->get(PPC::BC))
 | 
						|
      .add(BIL.back()->getOperand(3))
 | 
						|
      .addMBB(IsTrueBlockRequired ? TrueBlock : Successor);
 | 
						|
 | 
						|
  // Jump over the true block to the new successor if the condition is false.
 | 
						|
  BuildMI(*(IsFalseBlockRequired ? FalseBlock : MBB),
 | 
						|
          (IsFalseBlockRequired ? FalseBlockI : BIL.back()), dl,
 | 
						|
          TII->get(PPC::B))
 | 
						|
      .addMBB(Successor);
 | 
						|
 | 
						|
  if (IsFalseBlockRequired)
 | 
						|
    FalseBlockI = FalseBlock->begin(); // get the position of PPC::B
 | 
						|
}
 | 
						|
 | 
						|
void PPCExpandISEL::populateBlocks(BlockISELList &BIL) {
 | 
						|
  for (auto &MI : BIL) {
 | 
						|
    assert(isISEL(*MI) && "Expecting an ISEL instruction");
 | 
						|
 | 
						|
    MachineOperand &Dest = MI->getOperand(0);       // location to store to
 | 
						|
    MachineOperand &TrueValue = MI->getOperand(1);  // Value to store if
 | 
						|
                                                       // condition is true
 | 
						|
    MachineOperand &FalseValue = MI->getOperand(2); // Value to store if
 | 
						|
                                                       // condition is false
 | 
						|
 | 
						|
    LLVM_DEBUG(dbgs() << "Dest: " << Dest << "\n");
 | 
						|
    LLVM_DEBUG(dbgs() << "TrueValue: " << TrueValue << "\n");
 | 
						|
    LLVM_DEBUG(dbgs() << "FalseValue: " << FalseValue << "\n");
 | 
						|
    LLVM_DEBUG(dbgs() << "ConditionRegister: " << MI->getOperand(3) << "\n");
 | 
						|
 | 
						|
    // If the Dest Register and True Value Register are not the same one, we
 | 
						|
    // need the True Block.
 | 
						|
    bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);
 | 
						|
    bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);
 | 
						|
 | 
						|
    // Copy the result into the destination if the condition is true.
 | 
						|
    if (IsADDIInstRequired)
 | 
						|
      BuildMI(*TrueBlock, TrueBlockI, dl,
 | 
						|
              TII->get(isISEL8(*MI) ? PPC::ADDI8 : PPC::ADDI))
 | 
						|
          .add(Dest)
 | 
						|
          .add(TrueValue)
 | 
						|
          .add(MachineOperand::CreateImm(0));
 | 
						|
 | 
						|
    // Copy the result into the destination if the condition is false.
 | 
						|
    if (IsORIInstRequired)
 | 
						|
      BuildMI(*FalseBlock, FalseBlockI, dl,
 | 
						|
              TII->get(isISEL8(*MI) ? PPC::ORI8 : PPC::ORI))
 | 
						|
          .add(Dest)
 | 
						|
          .add(FalseValue)
 | 
						|
          .add(MachineOperand::CreateImm(0));
 | 
						|
 | 
						|
    MI->eraseFromParent(); // Remove the ISEL instruction.
 | 
						|
 | 
						|
    NumExpanded++;
 | 
						|
  }
 | 
						|
 | 
						|
  if (IsTrueBlockRequired) {
 | 
						|
    // Update the liveins for TrueBlock.
 | 
						|
    LivePhysRegs LPR;
 | 
						|
    computeAndAddLiveIns(LPR, *TrueBlock);
 | 
						|
  }
 | 
						|
 | 
						|
  if (IsFalseBlockRequired) {
 | 
						|
    // Update the liveins for FalseBlock.
 | 
						|
    LivePhysRegs LPR;
 | 
						|
    computeAndAddLiveIns(LPR, *FalseBlock);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void PPCExpandISEL::expandMergeableISELs(BlockISELList &BIL) {
 | 
						|
  // At this stage all the ISELs of BIL are in the same MBB.
 | 
						|
  MachineBasicBlock *MBB = BIL.back()->getParent();
 | 
						|
 | 
						|
  handleSpecialCases(BIL, MBB);
 | 
						|
  reorganizeBlockLayout(BIL, MBB);
 | 
						|
  populateBlocks(BIL);
 | 
						|
}
 | 
						|
 | 
						|
INITIALIZE_PASS(PPCExpandISEL, DEBUG_TYPE, "PowerPC Expand ISEL Generation",
 | 
						|
                false, false)
 | 
						|
char PPCExpandISEL::ID = 0;
 | 
						|
 | 
						|
FunctionPass *llvm::createPPCExpandISELPass() { return new PPCExpandISEL(); }
 |