X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineLICM.cpp;h=d0baaa87ae1beed2d477d98721c803d098e9af08;hb=b6e223a9e806921183da972253c49082a2e07944;hp=829583054459cba8e38d3cf2d202383d83f94416;hpb=e4fc1ccd4dd66a7421e911528c1af5337c20167b;p=oota-llvm.git diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp index 82958305445..d0baaa87ae1 100644 --- a/lib/CodeGen/MachineLICM.cpp +++ b/lib/CodeGen/MachineLICM.cpp @@ -34,7 +34,6 @@ namespace { class VISIBILITY_HIDDEN MachineLICM : public MachineFunctionPass { const TargetMachine *TM; const TargetInstrInfo *TII; - MachineFunction *CurMF; // Current MachineFunction // Various analyses that we use... MachineLoopInfo *LI; // Current MachineLoopInfo @@ -46,10 +45,12 @@ namespace { MachineLoop *CurLoop; // The current loop we are working on. public: static char ID; // Pass identification, replacement for typeid - MachineLICM() : MachineFunctionPass((intptr_t)&ID) {} + MachineLICM() : MachineFunctionPass(&ID) {} virtual bool runOnMachineFunction(MachineFunction &MF); + const char *getPassName() const { return "Machine Instruction LICM"; } + // FIXME: Loop preheaders? virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); @@ -112,30 +113,7 @@ namespace { /// void MoveInstToEndOfBlock(MachineBasicBlock *ToMBB, MachineBasicBlock *FromMBB, - MachineInstr *MI) { - DEBUG({ - DOUT << "Hoisting " << *MI; - if (ToMBB->getBasicBlock()) - DOUT << " to MachineBasicBlock " - << ToMBB->getBasicBlock()->getName(); - if (FromMBB->getBasicBlock()) - DOUT << " from MachineBasicBlock " - << FromMBB->getBasicBlock()->getName(); - DOUT << "\n"; - }); - - MachineBasicBlock::iterator WhereIter = ToMBB->getFirstTerminator(); - MachineBasicBlock::iterator To, From = FromMBB->begin(); - - while (&*From != MI) - ++From; - - assert(From != FromMBB->end() && "Didn't find instr in BB!"); - - To = From; - ToMBB->splice(WhereIter, FromMBB, From, ++To); - ++NumHoisted; - } + MachineInstr *MI); /// HoistRegion - Walk the specified region of the CFG (defined by all /// blocks dominated by the specified block, and that are in the current @@ -150,12 +128,12 @@ namespace { /// void Hoist(MachineInstr &MI); }; - - char MachineLICM::ID = 0; - RegisterPass X("machine-licm", - "Machine Loop Invariant Code Motion"); } // end anonymous namespace +char MachineLICM::ID = 0; +static RegisterPass +X("machinelicm", "Machine Loop Invariant Code Motion"); + FunctionPass *llvm::createMachineLICMPass() { return new MachineLICM(); } /// Hoist expressions out of the specified loop. Note, alias info for inner loop @@ -166,10 +144,9 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { DOUT << "******** Machine LICM ********\n"; Changed = false; - CurMF = &MF; - TM = &CurMF->getTarget(); + TM = &MF.getTarget(); TII = TM->getInstrInfo(); - RegInfo = &CurMF->getRegInfo(); + RegInfo = &MF.getRegInfo(); // Get our Loop information... LI = &getAnalysis(); @@ -228,7 +205,7 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { const TargetInstrDesc &TID = I.getDesc(); // Ignore stuff that we obviously can't hoist. - if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch() || + if (TID.mayStore() || TID.isCall() || TID.isTerminator() || TID.hasUnmodeledSideEffects()) return false; @@ -264,11 +241,23 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { } }); + if (I.getDesc().getImplicitDefs() || I.getDesc().getImplicitUses()) { + DOUT << "Cannot hoist with implicit defines or uses\n"; + return false; + } + // The instruction is loop invariant if all of its operands are. for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { const MachineOperand &MO = I.getOperand(i); - if (!MO.isRegister() || !MO.isUse()) + if (!MO.isReg()) + continue; + + if (MO.isDef() && TargetRegisterInfo::isPhysicalRegister(MO.getReg())) + // Don't hoist an instruction that defines a physical register. + return false; + + if (!MO.isUse()) continue; unsigned Reg = MO.getReg(); @@ -291,16 +280,42 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { return true; } +/// MoveInstToEndOfBlock - Moves the machine instruction to the bottom of the +/// predecessor basic block (but before the terminator instructions). +/// +void MachineLICM::MoveInstToEndOfBlock(MachineBasicBlock *ToMBB, + MachineBasicBlock *FromMBB, + MachineInstr *MI) { + DEBUG({ + DOUT << "Hoisting " << *MI; + if (ToMBB->getBasicBlock()) + DOUT << " to MachineBasicBlock " + << ToMBB->getBasicBlock()->getName(); + if (FromMBB->getBasicBlock()) + DOUT << " from MachineBasicBlock " + << FromMBB->getBasicBlock()->getName(); + DOUT << "\n"; + }); + + MachineBasicBlock::iterator WhereIter = ToMBB->getFirstTerminator(); + MachineBasicBlock::iterator To, From = FromMBB->begin(); + + while (&*From != MI) + ++From; + + assert(From != FromMBB->end() && "Didn't find instr in BB!"); + + To = From; + ToMBB->splice(WhereIter, FromMBB, From, ++To); + ++NumHoisted; +} + /// Hoist - When an instruction is found to use only loop invariant operands /// that are safe to hoist, this instruction is called to do the dirty work. /// void MachineLICM::Hoist(MachineInstr &MI) { if (!IsLoopInvariantInst(MI)) return; - // Hoisting things that are trivially rematerializable may result in worse - // code than before. - if (TII->isTriviallyReMaterializable(&MI)) return; - std::vector Preds; // Non-back-edge predecessors. @@ -310,9 +325,9 @@ void MachineLICM::Hoist(MachineInstr &MI) { // is forbidden. if (Preds.empty() || Preds.size() != 1) return; - // Check that the predecessor is qualified to take the hoisted - // instruction. I.e., there is only one edge from the predecessor, and it's to - // the loop header. + // Check that the predecessor is qualified to take the hoisted instruction. + // I.e., there is only one edge from the predecessor, and it's to the loop + // header. MachineBasicBlock *MBB = Preds.front(); // FIXME: We are assuming at first that the basic block coming into this loop