X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FEarlyIfConversion.cpp;h=fbc4d97c4987a55029198aa6264403b6dc283039;hb=9758b4ae957d85e4b1e7fff1592f276ae684ee98;hp=6c679b222829190f22f561015ab480f1a0301a70;hpb=c9efaeb53b5b4b325fdb45767eacd7970ee629c5;p=oota-llvm.git diff --git a/lib/CodeGen/EarlyIfConversion.cpp b/lib/CodeGen/EarlyIfConversion.cpp index 6c679b22282..fbc4d97c498 100644 --- a/lib/CodeGen/EarlyIfConversion.cpp +++ b/lib/CodeGen/EarlyIfConversion.cpp @@ -16,7 +16,6 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "early-ifcvt" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/SetVector.h" @@ -40,6 +39,8 @@ using namespace llvm; +#define DEBUG_TYPE "early-ifcvt" + // Absolute maximum number of instructions allowed per speculated block. // This bypasses all other heuristics, so it should be set fairly high. static cl::opt @@ -152,8 +153,8 @@ private: public: /// runOnMachineFunction - Initialize per-function data structures. void runOnMachineFunction(MachineFunction &MF) { - TII = MF.getTarget().getInstrInfo(); - TRI = MF.getTarget().getRegisterInfo(); + TII = MF.getSubtarget().getInstrInfo(); + TRI = MF.getSubtarget().getRegisterInfo(); MRI = &MF.getRegInfo(); LiveRegUnits.clear(); LiveRegUnits.setUniverse(TRI->getNumRegUnits()); @@ -219,32 +220,32 @@ bool SSAIfConv::canSpeculateInstrs(MachineBasicBlock *MBB) { // We never speculate stores, so an AA pointer isn't necessary. bool DontMoveAcrossStore = true; - if (!I->isSafeToMove(TII, 0, DontMoveAcrossStore)) { + if (!I->isSafeToMove(nullptr, DontMoveAcrossStore)) { DEBUG(dbgs() << "Can't speculate: " << *I); return false; } // Check for any dependencies on Head instructions. - for (MIOperands MO(I); MO.isValid(); ++MO) { - if (MO->isRegMask()) { + for (const MachineOperand &MO : I->operands()) { + if (MO.isRegMask()) { DEBUG(dbgs() << "Won't speculate regmask: " << *I); return false; } - if (!MO->isReg()) + if (!MO.isReg()) continue; - unsigned Reg = MO->getReg(); + unsigned Reg = MO.getReg(); // Remember clobbered regunits. - if (MO->isDef() && TargetRegisterInfo::isPhysicalRegister(Reg)) + if (MO.isDef() && TargetRegisterInfo::isPhysicalRegister(Reg)) for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) ClobberedRegUnits.set(*Units); - if (!MO->readsReg() || !TargetRegisterInfo::isVirtualRegister(Reg)) + if (!MO.readsReg() || !TargetRegisterInfo::isVirtualRegister(Reg)) continue; MachineInstr *DefMI = MRI->getVRegDef(Reg); if (!DefMI || DefMI->getParent() != Head) continue; - if (InsertAfter.insert(DefMI)) + if (InsertAfter.insert(DefMI).second) DEBUG(dbgs() << "BB#" << MBB->getNumber() << " depends on " << *DefMI); if (DefMI->isTerminator()) { DEBUG(dbgs() << "Can't insert instructions below terminator.\n"); @@ -283,19 +284,19 @@ bool SSAIfConv::findInsertionPoint() { } // Update live regunits. - for (MIOperands MO(I); MO.isValid(); ++MO) { + for (const MachineOperand &MO : I->operands()) { // We're ignoring regmask operands. That is conservatively correct. - if (!MO->isReg()) + if (!MO.isReg()) continue; - unsigned Reg = MO->getReg(); + unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; // I clobbers Reg, so it isn't live before I. - if (MO->isDef()) + if (MO.isDef()) for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) LiveRegUnits.erase(*Units); // Unless I reads Reg. - if (MO->readsReg()) + if (MO.readsReg()) Reads.push_back(Reg); } // Anything read by I is live before I. @@ -338,7 +339,7 @@ bool SSAIfConv::findInsertionPoint() { /// bool SSAIfConv::canConvertIf(MachineBasicBlock *MBB) { Head = MBB; - TBB = FBB = Tail = 0; + TBB = FBB = Tail = nullptr; if (Head->succ_size() != 2) return false; @@ -459,12 +460,11 @@ void SSAIfConv::replacePHIInstrs() { for (unsigned i = 0, e = PHIs.size(); i != e; ++i) { PHIInfo &PI = PHIs[i]; DEBUG(dbgs() << "If-converting " << *PI.PHI); - assert(PI.PHI->getNumOperands() == 5 && "Unexpected PHI operands."); unsigned DstReg = PI.PHI->getOperand(0).getReg(); TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg, Cond, PI.TReg, PI.FReg); - DEBUG(dbgs() << " --> " << *llvm::prior(FirstTerm)); + DEBUG(dbgs() << " --> " << *std::prev(FirstTerm)); PI.PHI->eraseFromParent(); - PI.PHI = 0; + PI.PHI = nullptr; } } @@ -479,11 +479,20 @@ void SSAIfConv::rewritePHIOperands() { // Convert all PHIs to select instructions inserted before FirstTerm. for (unsigned i = 0, e = PHIs.size(); i != e; ++i) { PHIInfo &PI = PHIs[i]; + unsigned DstReg = 0; + DEBUG(dbgs() << "If-converting " << *PI.PHI); - unsigned PHIDst = PI.PHI->getOperand(0).getReg(); - unsigned DstReg = MRI->createVirtualRegister(MRI->getRegClass(PHIDst)); - TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg, Cond, PI.TReg, PI.FReg); - DEBUG(dbgs() << " --> " << *llvm::prior(FirstTerm)); + if (PI.TReg == PI.FReg) { + // We do not need the select instruction if both incoming values are + // equal. + DstReg = PI.TReg; + } else { + unsigned PHIDst = PI.PHI->getOperand(0).getReg(); + DstReg = MRI->createVirtualRegister(MRI->getRegClass(PHIDst)); + TII->insertSelect(*Head, FirstTerm, HeadDL, + DstReg, Cond, PI.TReg, PI.FReg); + DEBUG(dbgs() << " --> " << *std::prev(FirstTerm)); + } // Rewrite PHI operands TPred -> (DstReg, Head), remove FPred. for (unsigned i = PI.PHI->getNumOperands(); i != 1; i -= 2) { @@ -565,7 +574,7 @@ void SSAIfConv::convertIf(SmallVectorImpl &RemovedBlocks) { // We need a branch to Tail, let code placement work it out later. DEBUG(dbgs() << "Converting to unconditional branch.\n"); SmallVector EmptyCond; - TII->InsertBranch(*Head, Tail, 0, EmptyCond, HeadDL); + TII->InsertBranch(*Head, Tail, nullptr, EmptyCond, HeadDL); Head->addSuccessor(Tail); } DEBUG(dbgs() << *Head); @@ -580,7 +589,7 @@ namespace { class EarlyIfConverter : public MachineFunctionPass { const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; - const MCSchedModel *SchedModel; + MCSchedModel SchedModel; MachineRegisterInfo *MRI; MachineDominatorTree *DomTree; MachineLoopInfo *Loops; @@ -591,9 +600,9 @@ class EarlyIfConverter : public MachineFunctionPass { public: static char ID; EarlyIfConverter() : MachineFunctionPass(ID) {} - void getAnalysisUsage(AnalysisUsage &AU) const; - bool runOnMachineFunction(MachineFunction &MF); - const char *getPassName() const { return "Early If-Conversion"; } + void getAnalysisUsage(AnalysisUsage &AU) const override; + bool runOnMachineFunction(MachineFunction &MF) override; + const char *getPassName() const override { return "Early If-Conversion"; } private: bool tryConvertIf(MachineBasicBlock*); @@ -688,7 +697,7 @@ bool EarlyIfConverter::shouldConvertIf() { FBBTrace.getCriticalPath()); // Set a somewhat arbitrary limit on the critical path extension we accept. - unsigned CritLimit = SchedModel->MispredictPenalty/2; + unsigned CritLimit = SchedModel.MispredictPenalty/2; // If-conversion only makes sense when there is unexploited ILP. Compute the // maximum-ILP resource length of the trace after if-conversion. Compare it @@ -776,15 +785,19 @@ bool EarlyIfConverter::tryConvertIf(MachineBasicBlock *MBB) { bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) { DEBUG(dbgs() << "********** EARLY IF-CONVERSION **********\n" << "********** Function: " << MF.getName() << '\n'); - TII = MF.getTarget().getInstrInfo(); - TRI = MF.getTarget().getRegisterInfo(); - SchedModel = - MF.getTarget().getSubtarget().getSchedModel(); + // Only run if conversion if the target wants it. + const TargetSubtargetInfo &STI = MF.getSubtarget(); + if (!STI.enableEarlyIfConversion()) + return false; + + TII = STI.getInstrInfo(); + TRI = STI.getRegisterInfo(); + SchedModel = STI.getSchedModel(); MRI = &MF.getRegInfo(); DomTree = &getAnalysis(); Loops = getAnalysisIfAvailable(); Traces = &getAnalysis(); - MinInstr = 0; + MinInstr = nullptr; bool Changed = false; IfConv.runOnMachineFunction(MF); @@ -793,9 +806,8 @@ bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) { // if-conversion in a single pass. The tryConvertIf() function may erase // blocks, but only blocks dominated by the head block. This makes it safe to // update the dominator tree while the post-order iterator is still active. - for (po_iterator - I = po_begin(DomTree), E = po_end(DomTree); I != E; ++I) - if (tryConvertIf(I->getBlock())) + for (auto DomNode : post_order(DomTree)) + if (tryConvertIf(DomNode->getBlock())) Changed = true; return Changed;