29#define DEBUG_TYPE "ppc-expand-isel"
31STATISTIC(NumExpanded,
"Number of ISEL instructions expanded");
32STATISTIC(NumRemoved,
"Number of ISEL instructions removed");
33STATISTIC(NumFolded,
"Number of ISEL instructions folded");
41 cl::desc(
"Enable generating the ISEL instruction."),
49 bool IsTrueBlockRequired;
50 bool IsFalseBlockRequired;
63 ISELInstructionList ISELInstructions;
70 void populateBlocks(BlockISELList &BIL);
71 void expandMergeableISELs(BlockISELList &BIL);
72 void expandAndMergeISELs();
78 return (
MI.getOpcode() == PPC::ISEL ||
MI.getOpcode() == PPC::ISEL8);
83 return (
MI.getOpcode() == PPC::ISEL8);
99 bool collectISELInstructions();
124 void DumpISELInstructions()
const;
131 if (!collectISELInstructions()) {
137 DumpISELInstructions();
140 expandAndMergeISELs();
150 ISELInstructions.clear();
157bool PPCExpandISEL::collectISELInstructions() {
159 BlockISELList thisBlockISELs;
162 thisBlockISELs.push_back(&
MI);
163 if (!thisBlockISELs.empty())
164 ISELInstructions.insert(std::make_pair(
MBB.
getNumber(), thisBlockISELs));
166 return !ISELInstructions.empty();
170void PPCExpandISEL::DumpISELInstructions()
const {
171 for (
const auto &
I : ISELInstructions) {
174 for (
const auto &VI :
I.second)
183 if (!useSameRegister(PrevPushedMI->
getOperand(3),
MI->getOperand(3)))
188 return (std::prev(
MBBI) == PrevPushedMBBI);
191void PPCExpandISEL::expandAndMergeISELs() {
192 bool ExpandISELEnabled = isExpandISELEnabled(*MF);
194 for (
auto &BlockList : ISELInstructions) {
196 dbgs() <<
"Expanding ISEL instructions in "
199 BlockISELList &CurrentISELList = BlockList.second;
200 auto I = CurrentISELList.begin();
201 auto E = CurrentISELList.end();
204 assert(isISEL(**
I) &&
"Expecting an ISEL instruction");
212 if (useSameRegister(Dest, TrueValue) &&
213 useSameRegister(Dest, FalseValue)) {
220 (*I)->eraseFromParent();
222 }
else if (useSameRegister(TrueValue, FalseValue)) {
229 dbgs() <<
"Fold the ISEL instruction to an unconditional copy:\n");
240 }
else if (ExpandISELEnabled) {
243 BlockISELList SubISELList;
244 SubISELList.push_back(*
I++);
249 while (
I != E && canMerge(SubISELList.back(), *
I)) {
251 SubISELList.push_back(*
I++);
254 expandMergeableISELs(SubISELList);
262void PPCExpandISEL::handleSpecialCases(BlockISELList &BIL,
264 IsTrueBlockRequired =
false;
265 IsFalseBlockRequired =
false;
267 auto MI = BIL.begin();
268 while (
MI != BIL.end()) {
269 assert(isISEL(**
MI) &&
"Expecting an ISEL instruction");
282 bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);
283 bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);
286 if (!IsADDIInstRequired && !IsORIInstRequired) {
292 (*MI)->eraseFromParent();
305 if (useSameRegister(TrueValue, FalseValue) && (BIL.size() == 1)) {
307 dbgs() <<
"Fold the ISEL instruction to an unconditional copy.");
321 IsTrueBlockRequired |= IsADDIInstRequired;
322 IsFalseBlockRequired |= IsORIInstRequired;
327void PPCExpandISEL::reorganizeBlockLayout(BlockISELList &BIL,
332 assert((IsTrueBlockRequired || IsFalseBlockRequired) &&
333 "Should have been handled by special cases earlier!");
343 ? MF->CreateMachineBasicBlock(LLVM_BB)
365 if (IsFalseBlockRequired) {
366 FalseBlock = MF->CreateMachineBasicBlock(LLVM_BB);
367 MF->
insert(It, FalseBlock);
370 if (IsTrueBlockRequired) {
371 TrueBlock = MF->CreateMachineBasicBlock(LLVM_BB);
372 MF->
insert(It, TrueBlock);
376 MF->insert(It, NewSuccessor);
399 if (IsTrueBlockRequired) {
400 TrueBlockI = TrueBlock->
begin();
404 if (IsFalseBlockRequired) {
405 FalseBlockI = FalseBlock->
begin();
411 .
add(BIL.back()->getOperand(3))
415 BuildMI(*(IsFalseBlockRequired ? FalseBlock :
MBB),
416 (IsFalseBlockRequired ? FalseBlockI : BIL.back()), dl,
420 if (IsFalseBlockRequired)
421 FalseBlockI = FalseBlock->
begin();
424void PPCExpandISEL::populateBlocks(BlockISELList &BIL) {
425 for (
auto &
MI : BIL) {
426 assert(isISEL(*
MI) &&
"Expecting an ISEL instruction");
441 bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);
442 bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);
445 if (IsADDIInstRequired)
446 BuildMI(*TrueBlock, TrueBlockI, dl,
447 TII->get(isISEL8(*
MI) ? PPC::ADDI8 : PPC::ADDI))
453 if (IsORIInstRequired)
454 BuildMI(*FalseBlock, FalseBlockI, dl,
455 TII->get(isISEL8(*
MI) ? PPC::ORI8 : PPC::ORI))
460 MI->eraseFromParent();
465 if (IsTrueBlockRequired) {
471 if (IsFalseBlockRequired) {
478void PPCExpandISEL::expandMergeableISELs(BlockISELList &BIL) {
482 handleSpecialCases(BIL,
MBB);
483 reorganizeBlockLayout(BIL,
MBB);
489char PPCExpandISEL::
ID = 0;
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file defines the DenseMap class.
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static cl::opt< bool > GenerateISEL("ppc-gen-isel", cl::desc("Enable generating the ISEL instruction."), cl::init(true), cl::Hidden)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
LLVM Basic Block Representation.
FunctionPass class - This class is used to implement most global optimizations.
A set of physical registers with utility functions to track liveness when walking backward/forward th...
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
bool canFallThrough()
Return true if the block can implicitly transfer control to the block after it by falling off the end...
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
virtual const TargetInstrInfo * getInstrInfo() const
self_iterator getIterator()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().
FunctionPass * createPPCExpandISELPass()
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
void initializePPCExpandISELPass(PassRegistry &)