X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineSink.cpp;h=1610e6c9610caf30b6cce89e468579f79535f13f;hb=b7a31709171ba42d83d2fb575818e7ccd900fb03;hp=0f3b33f54d46129c32e1c32035f4ec940f5d7dac;hpb=a70dca156fa76d452f54829b5c5f962ddfd94ef2;p=oota-llvm.git diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp index 0f3b33f54d4..1610e6c9610 100644 --- a/lib/CodeGen/MachineSink.cpp +++ b/lib/CodeGen/MachineSink.cpp @@ -20,12 +20,12 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/Statistic.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -33,13 +33,12 @@ using namespace llvm; STATISTIC(NumSunk, "Number of machine instructions sunk"); namespace { - class VISIBILITY_HIDDEN MachineSinking : public MachineFunctionPass { - const TargetMachine *TM; + class MachineSinking : public MachineFunctionPass { const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; - MachineFunction *CurMF; // Current MachineFunction MachineRegisterInfo *RegInfo; // Machine register information MachineDominatorTree *DT; // Machine dominator tree + MachineLoopInfo *LI; AliasAnalysis *AA; BitVector AllocatableSet; // Which physregs are allocatable? @@ -54,7 +53,9 @@ namespace { MachineFunctionPass::getAnalysisUsage(AU); AU.addRequired(); AU.addRequired(); + AU.addRequired(); AU.addPreserved(); + AU.addPreserved(); } private: bool ProcessBlock(MachineBasicBlock &MBB); @@ -75,12 +76,17 @@ bool MachineSinking::AllUsesDominatedByBlock(unsigned Reg, MachineBasicBlock *MBB) const { assert(TargetRegisterInfo::isVirtualRegister(Reg) && "Only makes sense for vregs"); - for (MachineRegisterInfo::use_iterator I = RegInfo->use_begin(Reg), - E = RegInfo->use_end(); I != E; ++I) { + // Ignoring debug uses is necessary so debug info doesn't affect the code. + // This may leave a referencing dbg_value in the original block, before + // the definition of the vreg. Dwarf generator handles this although the + // user might not get the right info at runtime. + for (MachineRegisterInfo::use_nodbg_iterator I = + RegInfo->use_nodbg_begin(Reg), + E = RegInfo->use_nodbg_end(); I != E; ++I) { // Determine the block of the use. MachineInstr *UseInst = &*I; MachineBasicBlock *UseBlock = UseInst->getParent(); - if (UseInst->getOpcode() == TargetInstrInfo::PHI) { + if (UseInst->isPHI()) { // PHI nodes use the operand in the predecessor block, not the block with // the PHI. UseBlock = UseInst->getOperand(I.getOperandNo()+1).getMBB(); @@ -92,19 +98,17 @@ bool MachineSinking::AllUsesDominatedByBlock(unsigned Reg, return true; } - - bool MachineSinking::runOnMachineFunction(MachineFunction &MF) { - DEBUG(errs() << "******** Machine Sinking ********\n"); + DEBUG(dbgs() << "******** Machine Sinking ********\n"); - CurMF = &MF; - TM = &CurMF->getTarget(); - TII = TM->getInstrInfo(); - TRI = TM->getRegisterInfo(); - RegInfo = &CurMF->getRegInfo(); + const TargetMachine &TM = MF.getTarget(); + TII = TM.getInstrInfo(); + TRI = TM.getRegisterInfo(); + RegInfo = &MF.getRegInfo(); DT = &getAnalysis(); + LI = &getAnalysis(); AA = &getAnalysis(); - AllocatableSet = TRI->getAllocatableSet(*CurMF); + AllocatableSet = TRI->getAllocatableSet(MF); bool EverMadeChange = false; @@ -112,7 +116,7 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) { bool MadeChange = false; // Process all basic blocks. - for (MachineFunction::iterator I = CurMF->begin(), E = CurMF->end(); + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) MadeChange |= ProcessBlock(*I); @@ -127,6 +131,11 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) { // Can't sink anything out of a block that has less than two successors. if (MBB.succ_size() <= 1 || MBB.empty()) return false; + // Don't bother sinking code out of unreachable blocks. In addition to being + // unprofitable, it can also lead to infinite looping, because in an unreachable + // loop there may be nowhere to stop. + if (!DT->isReachableFromEntry(&MBB)) return false; + bool MadeChange = false; // Walk the basic block bottom-up. Remember if we saw a store. @@ -141,7 +150,10 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) { ProcessedBegin = I == MBB.begin(); if (!ProcessedBegin) --I; - + + if (MI->isDebugValue()) + continue; + if (SinkInstruction(MI, SawStore)) ++NumSunk, MadeChange = true; @@ -155,7 +167,7 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) { /// instruction out of its current block into a successor. bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) { // Check if it's safe to move the instruction. - if (!MI->isSafeToMove(TII, SawStore, AA)) + if (!MI->isSafeToMove(TII, AA, SawStore)) return false; // FIXME: This should include support for sinking instructions within the @@ -256,31 +268,56 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) { if (SuccToSinkTo->isLandingPad()) return false; - // If is not possible to sink an instruction into its own block. This can + // It is not possible to sink an instruction into its own block. This can // happen with loops. if (MI->getParent() == SuccToSinkTo) return false; - DEBUG(errs() << "Sink instr " << *MI); - DEBUG(errs() << "to block " << *SuccToSinkTo); + DEBUG(dbgs() << "Sink instr " << *MI); + DEBUG(dbgs() << "to block " << *SuccToSinkTo); // If the block has multiple predecessors, this would introduce computation on // a path that it doesn't already exist. We could split the critical edge, // but for now we just punt. // FIXME: Split critical edges if not backedges. if (SuccToSinkTo->pred_size() > 1) { - DEBUG(errs() << " *** PUNTING: Critical edge found\n"); - return false; + // We cannot sink a load across a critical edge - there may be stores in + // other code paths. + bool store = true; + if (!MI->isSafeToMove(TII, AA, store)) { + DEBUG(dbgs() << " *** PUNTING: Wont sink load along critical edge.\n"); + return false; + } + + // We don't want to sink across a critical edge if we don't dominate the + // successor. We could be introducing calculations to new code paths. + if (!DT->dominates(ParentBlock, SuccToSinkTo)) { + DEBUG(dbgs() << " *** PUNTING: Critical edge found\n"); + return false; + } + + // Don't sink instructions into a loop. + if (LI->isLoopHeader(SuccToSinkTo)) { + DEBUG(dbgs() << " *** PUNTING: Loop header found\n"); + return false; + } + + // Otherwise we are OK with sinking along a critical edge. + DEBUG(dbgs() << "Sinking along critical edge.\n"); } // Determine where to insert into. Skip phi nodes. MachineBasicBlock::iterator InsertPos = SuccToSinkTo->begin(); - while (InsertPos != SuccToSinkTo->end() && - InsertPos->getOpcode() == TargetInstrInfo::PHI) + while (InsertPos != SuccToSinkTo->end() && InsertPos->isPHI()) ++InsertPos; // Move the instruction. SuccToSinkTo->splice(InsertPos, ParentBlock, MI, ++MachineBasicBlock::iterator(MI)); + + // Conservatively, clear any kill flags, since it's possible that + // they are no longer correct. + MI->clearKillInfo(); + return true; }