30 #define DEBUG_TYPE "ppc-expand-isel" 32 STATISTIC(NumExpanded,
"Number of ISEL instructions expanded");
33 STATISTIC(NumRemoved,
"Number of ISEL instructions removed");
34 STATISTIC(NumFolded,
"Number of ISEL instructions folded");
42 cl::desc(
"Enable generating the ISEL instruction."),
50 bool IsTrueBlockRequired;
51 bool IsFalseBlockRequired;
64 ISELInstructionList ISELInstructions;
71 void populateBlocks(BlockISELList &BIL);
72 void expandMergeableISELs(BlockISELList &BIL);
73 void expandAndMergeISELs();
100 bool collectISELInstructions();
125 void DumpISELInstructions()
const;
132 if (!collectISELInstructions()) {
138 DumpISELInstructions();
141 expandAndMergeISELs();
151 ISELInstructions.clear();
158 bool PPCExpandISEL::collectISELInstructions() {
160 BlockISELList thisBlockISELs;
163 thisBlockISELs.push_back(&MI);
164 if (!thisBlockISELs.empty())
165 ISELInstructions.insert(std::make_pair(MBB.getNumber(), thisBlockISELs));
167 return !ISELInstructions.empty();
171 void PPCExpandISEL::DumpISELInstructions()
const {
172 for (
const auto &
I : ISELInstructions) {
175 for (
const auto &
VI :
I.second)
189 return (std::prev(MBBI) == PrevPushedMBBI);
192 void PPCExpandISEL::expandAndMergeISELs() {
193 bool ExpandISELEnabled = isExpandISELEnabled(*MF);
195 for (
auto &BlockList : ISELInstructions) {
197 dbgs() <<
"Expanding ISEL instructions in " 200 BlockISELList &CurrentISELList = BlockList.second;
201 auto I = CurrentISELList.begin();
202 auto E = CurrentISELList.end();
205 assert(isISEL(**
I) &&
"Expecting an ISEL instruction");
213 if (useSameRegister(Dest, TrueValue) &&
214 useSameRegister(Dest, FalseValue)) {
221 (*I)->eraseFromParent();
223 }
else if (useSameRegister(TrueValue, FalseValue)) {
230 dbgs() <<
"Fold the ISEL instruction to an unconditional copy:\n");
239 (*I)->eraseFromParent();
241 }
else if (ExpandISELEnabled) {
244 BlockISELList SubISELList;
245 SubISELList.push_back(*
I++);
250 while (
I !=
E && canMerge(SubISELList.back(), *
I)) {
252 SubISELList.push_back(*
I++);
255 expandMergeableISELs(SubISELList);
263 void PPCExpandISEL::handleSpecialCases(BlockISELList &BIL,
265 IsTrueBlockRequired =
false;
266 IsFalseBlockRequired =
false;
268 auto MI = BIL.begin();
269 while (MI != BIL.end()) {
270 assert(isISEL(**MI) &&
"Expecting an ISEL instruction");
283 bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);
284 bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);
287 if (!IsADDIInstRequired && !IsORIInstRequired) {
293 (*MI)->eraseFromParent();
306 if (useSameRegister(TrueValue, FalseValue) && (BIL.size() == 1)) {
308 dbgs() <<
"Fold the ISEL instruction to an unconditional copy.");
312 BuildMI(*MBB, (*MI), dl, TII->
get(isISEL8(**MI) ? PPC::OR8 : PPC::OR))
316 (*MI)->eraseFromParent();
322 IsTrueBlockRequired |= IsADDIInstRequired;
323 IsFalseBlockRequired |= IsORIInstRequired;
328 void PPCExpandISEL::reorganizeBlockLayout(BlockISELList &BIL,
333 assert((IsTrueBlockRequired || IsFalseBlockRequired) &&
334 "Should have been handled by special cases earlier!");
344 ? MF->CreateMachineBasicBlock(LLVM_BB)
361 Successor = NewSuccessor;
366 if (IsFalseBlockRequired) {
367 FalseBlock = MF->CreateMachineBasicBlock(LLVM_BB);
368 MF->
insert(It, FalseBlock);
371 if (IsTrueBlockRequired) {
372 TrueBlock = MF->CreateMachineBasicBlock(LLVM_BB);
373 MF->
insert(It, TrueBlock);
377 MF->insert(It, NewSuccessor);
380 NewSuccessor->
splice(NewSuccessor->
end(), MBB,
386 for (
auto &LI : MBB->
liveins())
397 LPR.stepForward(MI, Clobbers);
402 MBB->removeSuccessor(Successor);
408 MBB->addSuccessor(IsTrueBlockRequired ? TrueBlock : Successor);
409 MBB->addSuccessor(IsFalseBlockRequired ? FalseBlock : Successor);
411 if (IsTrueBlockRequired) {
412 TrueBlockI = TrueBlock->
begin();
416 if (IsFalseBlockRequired) {
417 FalseBlockI = FalseBlock->
begin();
422 BuildMI(*MBB, BIL.back(), dl, TII->
get(PPC::BC))
423 .
add(BIL.back()->getOperand(3))
424 .addMBB(IsTrueBlockRequired ? TrueBlock : Successor);
427 BuildMI(*(IsFalseBlockRequired ? FalseBlock : MBB),
428 (IsFalseBlockRequired ? FalseBlockI : BIL.back()), dl,
432 if (IsFalseBlockRequired)
433 FalseBlockI = FalseBlock->
begin();
436 void PPCExpandISEL::populateBlocks(BlockISELList &BIL) {
437 for (
auto &MI : BIL) {
438 assert(isISEL(*MI) &&
"Expecting an ISEL instruction");
450 LLVM_DEBUG(
dbgs() <<
"ConditionRegister: " << ConditionRegister <<
"\n");
454 bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);
455 bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);
457 if (IsADDIInstRequired) {
459 BuildMI(*TrueBlock, TrueBlockI, dl,
460 TII->
get(isISEL8(*MI) ? PPC::ADDI8 : PPC::ADDI))
469 if (IsORIInstRequired) {
483 if (IsORIInstRequired)
484 BuildMI(*FalseBlock, FalseBlockI, dl,
485 TII->
get(isISEL8(*MI) ? PPC::ORI8 : PPC::ORI))
496 void PPCExpandISEL::expandMergeableISELs(BlockISELList &BIL) {
500 handleSpecialCases(BIL, MBB);
501 reorganizeBlockLayout(BIL, MBB);
507 char PPCExpandISEL::ID = 0;
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
unsigned getReg() const
getReg - Returns the register number.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
STATISTIC(NumFunctions, "Total number of functions")
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
iterator_range< succ_iterator > successors()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool canFallThrough()
Return true if the block can implicitly transfer control to the block after it by falling off the end...
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
virtual const TargetInstrInfo * getInstrInfo() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
LLVM Basic Block Representation.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static ManagedStatic< OptionRegistry > OR
FunctionPass class - This class is used to implement most global optimizations.
self_iterator getIterator()
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const PPCRegisterInfo * getRegisterInfo() const override
Iterator for intrusive lists based on ilist_node.
void initializePPCExpandISELPass(PassRegistry &)
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
MachineOperand class - Representation of each machine instruction operand.
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringRef > StandardNames)
Initialize the set of available library functions based on the specified target triple.
const MachineBasicBlock * getParent() const
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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 '...
A set of physical registers with utility functions to track liveness when walking backward/forward th...
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
static MachineOperand CreateImm(int64_t Val)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
iterator_range< livein_iterator > liveins() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static cl::opt< bool > GenerateISEL("ppc-gen-isel", cl::desc("Enable generating the ISEL instruction."), cl::init(true), cl::Hidden)
const MachineOperand & getOperand(unsigned i) const
FunctionPass * createPPCExpandISELPass()