diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h index 3836002e5ac..f66cf156e6c 100644 --- a/include/llvm/CodeGen/RegisterScavenging.h +++ b/include/llvm/CodeGen/RegisterScavenging.h @@ -91,6 +91,9 @@ public: bool isUsed(unsigned Reg) const { return !RegStates[Reg]; } bool isUnused(unsigned Reg) const { return RegStates[Reg]; } + /// getRegsUsed - return all registers currently in use in used. + void getRegsUsed(BitVector &used, bool includeReserved); + /// setUsed / setUnused - Mark the state of one or a number of registers. /// void setUsed(unsigned Reg) { RegStates.reset(Reg); } diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index d6bedb844bd..1f5d6752b65 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -21,8 +21,10 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/MRegisterInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" @@ -49,7 +51,9 @@ namespace { MachineBasicBlock *NewDest); MachineBasicBlock *SplitMBBAt(MachineBasicBlock &CurMBB, MachineBasicBlock::iterator BBI1); - + + const MRegisterInfo *RegInfo; + RegScavenger *RS; // Branch optzn. bool OptimizeBranches(MachineFunction &MF); void OptimizeBlock(MachineBasicBlock *MBB); @@ -95,6 +99,9 @@ bool BranchFolder::runOnMachineFunction(MachineFunction &MF) { TII = MF.getTarget().getInstrInfo(); if (!TII) return false; + RegInfo = MF.getTarget().getRegisterInfo(); + RS = RegInfo->requiresRegisterScavenging(MF) ? new RegScavenger() : NULL; + MMI = getAnalysisToUpdate(); bool EverMadeChange = false; @@ -153,6 +160,7 @@ bool BranchFolder::runOnMachineFunction(MachineFunction &MF) { } } + delete RS; return EverMadeChange; } @@ -280,6 +288,19 @@ MachineBasicBlock *BranchFolder::SplitMBBAt(MachineBasicBlock &CurMBB, // Splice the code over. NewMBB->splice(NewMBB->end(), &CurMBB, BBI1, CurMBB.end()); + + // For targets that use the register scavenger, we must maintain LiveIns. + if (RS) { + RS->enterBasicBlock(&CurMBB); + if (!CurMBB.empty()) + RS->forward(prior(CurMBB.end())); + BitVector RegsLiveAtExit(RegInfo->getNumRegs()); + RS->getRegsUsed(RegsLiveAtExit, false); + for (unsigned int i=0, e=RegInfo->getNumRegs(); i!=e; i++) + if (RegsLiveAtExit[i]) + NewMBB->addLiveIn(i); + } + return NewMBB; } diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index d73dd3d757e..e5729abdf49 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -180,6 +180,13 @@ void RegScavenger::backward() { setUsed(ChangedRegs); } +void RegScavenger::getRegsUsed(BitVector &used, bool includeReserved) { + if (includeReserved) + used = RegStates; + else + used = RegStates & ~ReservedRegs; +} + /// CreateRegClassMask - Set the bits that represent the registers in the /// TargetRegisterClass. static void CreateRegClassMask(const TargetRegisterClass *RC, BitVector &Mask) {