X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineLICM.cpp;h=7f48ab5499f798bf97c50d05cfcab95a82e6cb18;hb=ebcba612b537f45a033ccd9a60bee0c45e2e2ded;hp=f33acf4a87f0f6e2947e332980a1e4ca19862be1;hpb=b082c6f5d9ee0b70e0ce67a8e26dd0955a034599;p=oota-llvm.git diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp index f33acf4a87f..7f48ab5499f 100644 --- a/lib/CodeGen/MachineLICM.cpp +++ b/lib/CodeGen/MachineLICM.cpp @@ -17,7 +17,7 @@ #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/SmallVector.h" @@ -28,43 +28,36 @@ using namespace llvm; -namespace { - // Hidden options to help debugging - cl::opt - PerformLICM("machine-licm", - cl::init(false), cl::Hidden, - cl::desc("Perform loop-invariant code motion on machine code")); -} - STATISTIC(NumHoisted, "Number of machine instructions hoisted out of loops"); namespace { class VISIBILITY_HIDDEN MachineLICM : public MachineFunctionPass { const TargetMachine *TM; const TargetInstrInfo *TII; - MachineFunction *CurMF; // Current MachineFunction + MachineFunction *CurMF; // Current MachineFunction // Various analyses that we use... - MachineLoopInfo *LI; // Current MachineLoopInfo - MachineDominatorTree *DT; // Machine dominator tree for the current Loop + MachineLoopInfo *LI; // Current MachineLoopInfo + MachineDominatorTree *DT; // Machine dominator tree for the cur loop MachineRegisterInfo *RegInfo; // Machine register information // State that is updated as we process loops - bool Changed; // True if a loop is changed. - MachineLoop *CurLoop; // The current loop we are working on. + bool Changed; // True if a loop is changed. + MachineLoop *CurLoop; // The current loop we are working on. public: static char ID; // Pass identification, replacement for typeid MachineLICM() : MachineFunctionPass((intptr_t)&ID) {} virtual bool runOnMachineFunction(MachineFunction &MF); - /// FIXME: Loop preheaders? - /// + // FIXME: Loop preheaders? virtual void getAnalysisUsage(AnalysisUsage &AU) const { - MachineFunctionPass::getAnalysisUsage(AU); AU.setPreservesCFG(); AU.addRequired(); AU.addRequired(); + AU.addPreserved(); + AU.addPreserved(); + MachineFunctionPass::getAnalysisUsage(AU); } private: /// VisitAllLoops - Visit all of the loops in depth first order and try to @@ -125,6 +118,9 @@ namespace { if (ToMBB->getBasicBlock()) DOUT << " to MachineBasicBlock " << ToMBB->getBasicBlock()->getName(); + if (FromMBB->getBasicBlock()) + DOUT << " from MachineBasicBlock " + << FromMBB->getBasicBlock()->getName(); DOUT << "\n"; }); @@ -154,12 +150,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("machine-licm", "Machine Loop Invariant Code Motion"); + FunctionPass *llvm::createMachineLICMPass() { return new MachineLICM(); } /// Hoist expressions out of the specified loop. Note, alias info for inner loop @@ -167,8 +163,6 @@ FunctionPass *llvm::createMachineLICMPass() { return new MachineLICM(); } /// loop. /// bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { - if (!PerformLICM) return false; // For debugging. - DOUT << "******** Machine LICM ********\n"; Changed = false; @@ -231,46 +225,61 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N) { /// effects that aren't captured by the operands or other flags. /// 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() || + TID.hasUnmodeledSideEffects()) + return false; + + if (TID.mayLoad()) { + // Okay, this instruction does a load. As a refinement, we allow the target + // to decide whether the loaded value is actually a constant. If so, we can + // actually use it as a load. + if (!TII->isInvariantLoad(&I)) + // FIXME: we should be able to sink loads with no other side effects if + // there is nothing that can change memory from here until the end of + // block. This is a trivial form of alias analysis. + return false; + } + DEBUG({ DOUT << "--- Checking if we can hoist " << I; - if (I.getInstrDescriptor()->ImplicitUses) { + if (I.getDesc().getImplicitUses()) { DOUT << " * Instruction has implicit uses:\n"; - const MRegisterInfo *MRI = TM->getRegisterInfo(); - const unsigned *ImpUses = I.getInstrDescriptor()->ImplicitUses; - - for (; *ImpUses; ++ImpUses) - DOUT << " -> " << MRI->getName(*ImpUses) << "\n"; + const TargetRegisterInfo *TRI = TM->getRegisterInfo(); + for (const unsigned *ImpUses = I.getDesc().getImplicitUses(); + *ImpUses; ++ImpUses) + DOUT << " -> " << TRI->getName(*ImpUses) << "\n"; } - if (I.getInstrDescriptor()->ImplicitDefs) { + if (I.getDesc().getImplicitDefs()) { DOUT << " * Instruction has implicit defines:\n"; - const MRegisterInfo *MRI = TM->getRegisterInfo(); - const unsigned *ImpDefs = I.getInstrDescriptor()->ImplicitDefs; - - for (; *ImpDefs; ++ImpDefs) - DOUT << " -> " << MRI->getName(*ImpDefs) << "\n"; + const TargetRegisterInfo *TRI = TM->getRegisterInfo(); + for (const unsigned *ImpDefs = I.getDesc().getImplicitDefs(); + *ImpDefs; ++ImpDefs) + DOUT << " -> " << TRI->getName(*ImpDefs) << "\n"; } - - if (TII->hasUnmodelledSideEffects(&I)) - DOUT << " * Instruction has side effects.\n"; }); - // The instruction is loop invariant if all of its operands are loop-invariant + // 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.getReg() && MO.isUse())) + if (!MO.isRegister() || !MO.isUse()) continue; unsigned Reg = MO.getReg(); + if (Reg == 0) continue; // Don't hoist instructions that access physical registers. - if (!MRegisterInfo::isVirtualRegister(Reg)) + if (TargetRegisterInfo::isPhysicalRegister(Reg)) return false; - assert(RegInfo->getVRegDef(Reg)&&"Machine instr not mapped for this vreg?"); + assert(RegInfo->getVRegDef(Reg) && + "Machine instr not mapped for this vreg?!"); // If the loop contains the definition of an operand, then the instruction // isn't loop invariant. @@ -278,15 +287,12 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { return false; } - // Don't hoist something that has unmodelled side effects. - if (TII->hasUnmodelledSideEffects(&I)) return false; - // If we got this far, the instruction is loop invariant! return true; } -/// Hoist - When an instruction is found to only use loop invariant operands -/// that is safe to hoist, this instruction is called to do the dirty work. +/// 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;