diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-11-04 14:58:56 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-11-04 14:58:56 +0000 |
commit | 7ff99155c39edd73ebf1c6adfa023b1048fee9a4 (patch) | |
tree | b4dc751bcee540346911aa4115729eff2f991657 /lib/CodeGen | |
parent | d1f06de484602e72707476a6152974847bac1570 (diff) | |
download | FreeBSD-src-7ff99155c39edd73ebf1c6adfa023b1048fee9a4.zip FreeBSD-src-7ff99155c39edd73ebf1c6adfa023b1048fee9a4.tar.gz |
Update LLVM to r86025.
Diffstat (limited to 'lib/CodeGen')
70 files changed, 3675 insertions, 1977 deletions
diff --git a/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/lib/CodeGen/AggressiveAntiDepBreaker.cpp new file mode 100644 index 0000000..ffb6315 --- /dev/null +++ b/lib/CodeGen/AggressiveAntiDepBreaker.cpp @@ -0,0 +1,794 @@ +//===----- AggressiveAntiDepBreaker.cpp - Anti-dep breaker -------- ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the AggressiveAntiDepBreaker class, which +// implements register anti-dependence breaking during post-RA +// scheduling. It attempts to break all anti-dependencies within a +// block. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "post-RA-sched" +#include "AggressiveAntiDepBreaker.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +static cl::opt<int> +AntiDepTrials("agg-antidep-trials", + cl::desc("Maximum number of anti-dependency breaking passes"), + cl::init(1), cl::Hidden); + +AggressiveAntiDepState::AggressiveAntiDepState(MachineBasicBlock *BB) : + GroupNodes(TargetRegisterInfo::FirstVirtualRegister, 0) { + // Initialize all registers to be in their own group. Initially we + // assign the register to the same-indexed GroupNode. + for (unsigned i = 0; i < TargetRegisterInfo::FirstVirtualRegister; ++i) + GroupNodeIndices[i] = i; + + // Initialize the indices to indicate that no registers are live. + std::fill(KillIndices, array_endof(KillIndices), ~0u); + std::fill(DefIndices, array_endof(DefIndices), BB->size()); +} + +unsigned AggressiveAntiDepState::GetGroup(unsigned Reg) +{ + unsigned Node = GroupNodeIndices[Reg]; + while (GroupNodes[Node] != Node) + Node = GroupNodes[Node]; + + return Node; +} + +void AggressiveAntiDepState::GetGroupRegs(unsigned Group, std::vector<unsigned> &Regs) +{ + for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { + if (GetGroup(Reg) == Group) + Regs.push_back(Reg); + } +} + +unsigned AggressiveAntiDepState::UnionGroups(unsigned Reg1, unsigned Reg2) +{ + assert(GroupNodes[0] == 0 && "GroupNode 0 not parent!"); + assert(GroupNodeIndices[0] == 0 && "Reg 0 not in Group 0!"); + + // find group for each register + unsigned Group1 = GetGroup(Reg1); + unsigned Group2 = GetGroup(Reg2); + + // if either group is 0, then that must become the parent + unsigned Parent = (Group1 == 0) ? Group1 : Group2; + unsigned Other = (Parent == Group1) ? Group2 : Group1; + GroupNodes.at(Other) = Parent; + return Parent; +} + +unsigned AggressiveAntiDepState::LeaveGroup(unsigned Reg) +{ + // Create a new GroupNode for Reg. Reg's existing GroupNode must + // stay as is because there could be other GroupNodes referring to + // it. + unsigned idx = GroupNodes.size(); + GroupNodes.push_back(idx); + GroupNodeIndices[Reg] = idx; + return idx; +} + +bool AggressiveAntiDepState::IsLive(unsigned Reg) +{ + // KillIndex must be defined and DefIndex not defined for a register + // to be live. + return((KillIndices[Reg] != ~0u) && (DefIndices[Reg] == ~0u)); +} + + + +AggressiveAntiDepBreaker:: +AggressiveAntiDepBreaker(MachineFunction& MFi) : + AntiDepBreaker(), MF(MFi), + MRI(MF.getRegInfo()), + TRI(MF.getTarget().getRegisterInfo()), + AllocatableSet(TRI->getAllocatableSet(MF)), + State(NULL), SavedState(NULL) { +} + +AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() { + delete State; + delete SavedState; +} + +unsigned AggressiveAntiDepBreaker::GetMaxTrials() { + if (AntiDepTrials <= 0) + return 1; + return AntiDepTrials; +} + +void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { + assert(State == NULL); + State = new AggressiveAntiDepState(BB); + + bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); + + // Determine the live-out physregs for this block. + if (IsReturnBlock) { + // In a return block, examine the function live-out regs. + for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), + E = MRI.liveout_end(); I != E; ++I) { + unsigned Reg = *I; + State->UnionGroups(Reg, 0); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + State->UnionGroups(AliasReg, 0); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } + } else { + // In a non-return block, examine the live-in regs of all successors. + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), + SE = BB->succ_end(); SI != SE; ++SI) + for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), + E = (*SI)->livein_end(); I != E; ++I) { + unsigned Reg = *I; + State->UnionGroups(Reg, 0); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + State->UnionGroups(AliasReg, 0); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } + } + + // Mark live-out callee-saved registers. In a return block this is + // all callee-saved registers. In non-return this is any + // callee-saved register that is not saved in the prolog. + const MachineFrameInfo *MFI = MF.getFrameInfo(); + BitVector Pristine = MFI->getPristineRegs(BB); + for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { + unsigned Reg = *I; + if (!IsReturnBlock && !Pristine.test(Reg)) continue; + State->UnionGroups(Reg, 0); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + State->UnionGroups(AliasReg, 0); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } +} + +void AggressiveAntiDepBreaker::FinishBlock() { + delete State; + State = NULL; + delete SavedState; + SavedState = NULL; +} + +void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, + unsigned InsertPosIndex) { + assert(Count < InsertPosIndex && "Instruction index out of expected range!"); + + std::set<unsigned> PassthruRegs; + GetPassthruRegs(MI, PassthruRegs); + PrescanInstruction(MI, Count, PassthruRegs); + ScanInstruction(MI, Count); + + DEBUG(errs() << "Observe: "); + DEBUG(MI->dump()); + DEBUG(errs() << "\tRegs:"); + + unsigned *DefIndices = State->GetDefIndices(); + for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { + // If Reg is current live, then mark that it can't be renamed as + // we don't know the extent of its live-range anymore (now that it + // has been scheduled). If it is not live but was defined in the + // previous schedule region, then set its def index to the most + // conservative location (i.e. the beginning of the previous + // schedule region). + if (State->IsLive(Reg)) { + DEBUG(if (State->GetGroup(Reg) != 0) + errs() << " " << TRI->getName(Reg) << "=g" << + State->GetGroup(Reg) << "->g0(region live-out)"); + State->UnionGroups(Reg, 0); + } else if ((DefIndices[Reg] < InsertPosIndex) && (DefIndices[Reg] >= Count)) { + DefIndices[Reg] = Count; + } + } + DEBUG(errs() << '\n'); + + // We're starting a new schedule region so forget any saved state. + delete SavedState; + SavedState = NULL; +} + +bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr *MI, + MachineOperand& MO) +{ + if (!MO.isReg() || !MO.isImplicit()) + return false; + + unsigned Reg = MO.getReg(); + if (Reg == 0) + return false; + + MachineOperand *Op = NULL; + if (MO.isDef()) + Op = MI->findRegisterUseOperand(Reg, true); + else + Op = MI->findRegisterDefOperand(Reg); + + return((Op != NULL) && Op->isImplicit()); +} + +void AggressiveAntiDepBreaker::GetPassthruRegs(MachineInstr *MI, + std::set<unsigned>& PassthruRegs) { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + if ((MO.isDef() && MI->isRegTiedToUseOperand(i)) || + IsImplicitDefUse(MI, MO)) { + const unsigned Reg = MO.getReg(); + PassthruRegs.insert(Reg); + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) { + PassthruRegs.insert(*Subreg); + } + } + } +} + +/// AntiDepPathStep - Return SUnit that SU has an anti-dependence on. +static void AntiDepPathStep(SUnit *SU, AntiDepBreaker::AntiDepRegVector& Regs, + std::vector<SDep*>& Edges) { + AntiDepBreaker::AntiDepRegSet RegSet; + for (unsigned i = 0, e = Regs.size(); i < e; ++i) + RegSet.insert(Regs[i]); + + for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); + P != PE; ++P) { + if (P->getKind() == SDep::Anti) { + unsigned Reg = P->getReg(); + if (RegSet.count(Reg) != 0) { + Edges.push_back(&*P); + RegSet.erase(Reg); + } + } + } + + assert(RegSet.empty() && "Expected all antidep registers to be found"); +} + +void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx, + const char *tag) { + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); + std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>& + RegRefs = State->GetRegRefs(); + + if (!State->IsLive(Reg)) { + KillIndices[Reg] = KillIdx; + DefIndices[Reg] = ~0u; + RegRefs.erase(Reg); + State->LeaveGroup(Reg); + DEBUG(errs() << "->g" << State->GetGroup(Reg) << tag); + } + // Repeat for subregisters. + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) { + unsigned SubregReg = *Subreg; + if (!State->IsLive(SubregReg)) { + KillIndices[SubregReg] = KillIdx; + DefIndices[SubregReg] = ~0u; + RegRefs.erase(SubregReg); + State->LeaveGroup(SubregReg); + DEBUG(errs() << " " << TRI->getName(SubregReg) << "->g" << + State->GetGroup(SubregReg) << tag); + } + } +} + +void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Count, + std::set<unsigned>& PassthruRegs) { + unsigned *DefIndices = State->GetDefIndices(); + std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>& + RegRefs = State->GetRegRefs(); + + // Handle dead defs by simulating a last-use of the register just + // after the def. A dead def can occur because the def is truely + // dead, or because only a subregister is live at the def. If we + // don't do this the dead def will be incorrectly merged into the + // previous def. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + + DEBUG(errs() << "\tDead Def: " << TRI->getName(Reg)); + HandleLastUse(Reg, Count + 1, ""); + DEBUG(errs() << '\n'); + } + + DEBUG(errs() << "\tDef Groups:"); + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + + DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << State->GetGroup(Reg)); + + // If MI's defs have a special allocation requirement, don't allow + // any def registers to be changed. Also assume all registers + // defined in a call must not be changed (ABI). + if (MI->getDesc().isCall() || MI->getDesc().hasExtraDefRegAllocReq()) { + DEBUG(if (State->GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); + State->UnionGroups(Reg, 0); + } + + // Any aliased that are live at this point are completely or + // partially defined here, so group those aliases with Reg. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + if (State->IsLive(AliasReg)) { + State->UnionGroups(Reg, AliasReg); + DEBUG(errs() << "->g" << State->GetGroup(Reg) << "(via " << + TRI->getName(AliasReg) << ")"); + } + } + + // Note register reference... + const TargetRegisterClass *RC = NULL; + if (i < MI->getDesc().getNumOperands()) + RC = MI->getDesc().OpInfo[i].getRegClass(TRI); + AggressiveAntiDepState::RegisterReference RR = { &MO, RC }; + RegRefs.insert(std::make_pair(Reg, RR)); + } + + DEBUG(errs() << '\n'); + + // Scan the register defs for this instruction and update + // live-ranges. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + // Ignore passthru registers for liveness... + if (PassthruRegs.count(Reg) != 0) continue; + + // Update def for Reg and subregs. + DefIndices[Reg] = Count; + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) { + unsigned SubregReg = *Subreg; + DefIndices[SubregReg] = Count; + } + } +} + +void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI, + unsigned Count) { + DEBUG(errs() << "\tUse Groups:"); + std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>& + RegRefs = State->GetRegRefs(); + + // Scan the register uses for this instruction and update + // live-ranges, groups and RegRefs. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isUse()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + + DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << + State->GetGroup(Reg)); + + // It wasn't previously live but now it is, this is a kill. Forget + // the previous live-range information and start a new live-range + // for the register. + HandleLastUse(Reg, Count, "(last-use)"); + + // If MI's uses have special allocation requirement, don't allow + // any use registers to be changed. Also assume all registers + // used in a call must not be changed (ABI). + if (MI->getDesc().isCall() || MI->getDesc().hasExtraSrcRegAllocReq()) { + DEBUG(if (State->GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); + State->UnionGroups(Reg, 0); + } + + // Note register reference... + const TargetRegisterClass *RC = NULL; + if (i < MI->getDesc().getNumOperands()) + RC = MI->getDesc().OpInfo[i].getRegClass(TRI); + AggressiveAntiDepState::RegisterReference RR = { &MO, RC }; + RegRefs.insert(std::make_pair(Reg, RR)); + } + + DEBUG(errs() << '\n'); + + // Form a group of all defs and uses of a KILL instruction to ensure + // that all registers are renamed as a group. + if (MI->getOpcode() == TargetInstrInfo::KILL) { + DEBUG(errs() << "\tKill Group:"); + + unsigned FirstReg = 0; + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + + if (FirstReg != 0) { + DEBUG(errs() << "=" << TRI->getName(Reg)); + State->UnionGroups(FirstReg, Reg); + } else { + DEBUG(errs() << " " << TRI->getName(Reg)); + FirstReg = Reg; + } + } + + DEBUG(errs() << "->g" << State->GetGroup(FirstReg) << '\n'); + } +} + +BitVector AggressiveAntiDepBreaker::GetRenameRegisters(unsigned Reg) { + BitVector BV(TRI->getNumRegs(), false); + bool first = true; + + // Check all references that need rewriting for Reg. For each, use + // the corresponding register class to narrow the set of registers + // that are appropriate for renaming. + std::pair<std::multimap<unsigned, + AggressiveAntiDepState::RegisterReference>::iterator, + std::multimap<unsigned, + AggressiveAntiDepState::RegisterReference>::iterator> + Range = State->GetRegRefs().equal_range(Reg); + for (std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>::iterator + Q = Range.first, QE = Range.second; Q != QE; ++Q) { + const TargetRegisterClass *RC = Q->second.RC; + if (RC == NULL) continue; + + BitVector RCBV = TRI->getAllocatableSet(MF, RC); + if (first) { + BV |= RCBV; + first = false; + } else { + BV &= RCBV; + } + + DEBUG(errs() << " " << RC->getName()); + } + + return BV; +} + +bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters( + unsigned AntiDepGroupIndex, + std::map<unsigned, unsigned> &RenameMap) { + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); + std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>& + RegRefs = State->GetRegRefs(); + + // Collect all registers in the same group as AntiDepReg. These all + // need to be renamed together if we are to break the + // anti-dependence. + std::vector<unsigned> Regs; + State->GetGroupRegs(AntiDepGroupIndex, Regs); + assert(Regs.size() > 0 && "Empty register group!"); + if (Regs.size() == 0) + return false; + + // Find the "superest" register in the group. At the same time, + // collect the BitVector of registers that can be used to rename + // each register. + DEBUG(errs() << "\tRename Candidates for Group g" << AntiDepGroupIndex << ":\n"); + std::map<unsigned, BitVector> RenameRegisterMap; + unsigned SuperReg = 0; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + unsigned Reg = Regs[i]; + if ((SuperReg == 0) || TRI->isSuperRegister(SuperReg, Reg)) + SuperReg = Reg; + + // If Reg has any references, then collect possible rename regs + if (RegRefs.count(Reg) > 0) { + DEBUG(errs() << "\t\t" << TRI->getName(Reg) << ":"); + + BitVector BV = GetRenameRegisters(Reg); + RenameRegisterMap.insert(std::pair<unsigned, BitVector>(Reg, BV)); + + DEBUG(errs() << " ::"); + DEBUG(for (int r = BV.find_first(); r != -1; r = BV.find_next(r)) + errs() << " " << TRI->getName(r)); + DEBUG(errs() << "\n"); + } + } + + // All group registers should be a subreg of SuperReg. + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + unsigned Reg = Regs[i]; + if (Reg == SuperReg) continue; + bool IsSub = TRI->isSubRegister(SuperReg, Reg); + assert(IsSub && "Expecting group subregister"); + if (!IsSub) + return false; + } + + // FIXME: for now just handle single register in group case... + // FIXME: check only regs that have references... + if (Regs.size() > 1) + return false; + + // Check each possible rename register for SuperReg. If that register + // is available, and the corresponding registers are available for + // the other group subregisters, then we can use those registers to + // rename. + DEBUG(errs() << "\tFind Register:"); + BitVector SuperBV = RenameRegisterMap[SuperReg]; + for (int r = SuperBV.find_first(); r != -1; r = SuperBV.find_next(r)) { + const unsigned Reg = (unsigned)r; + // Don't replace a register with itself. + if (Reg == SuperReg) continue; + + DEBUG(errs() << " " << TRI->getName(Reg)); + + // If Reg is dead and Reg's most recent def is not before + // SuperRegs's kill, it's safe to replace SuperReg with + // Reg. We must also check all subregisters of Reg. + if (State->IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) { + DEBUG(errs() << "(live)"); + continue; + } else { + bool found = false; + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) { + unsigned SubregReg = *Subreg; + if (State->IsLive(SubregReg) || (KillIndices[SuperReg] > DefIndices[SubregReg])) { + DEBUG(errs() << "(subreg " << TRI->getName(SubregReg) << " live)"); + found = true; + break; + } + } + if (found) + continue; + } + + if (Reg != 0) { + DEBUG(errs() << '\n'); + RenameMap.insert(std::pair<unsigned, unsigned>(SuperReg, Reg)); + return true; + } + } + + DEBUG(errs() << '\n'); + + // No registers are free and available! + return false; +} + +/// BreakAntiDependencies - Identifiy anti-dependencies within the +/// ScheduleDAG and break them by renaming registers. +/// +unsigned AggressiveAntiDepBreaker::BreakAntiDependencies( + std::vector<SUnit>& SUnits, + CandidateMap& Candidates, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex) { + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); + std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>& + RegRefs = State->GetRegRefs(); + + // Nothing to do if no candidates. + if (Candidates.empty()) { + DEBUG(errs() << "\n===== No anti-dependency candidates\n"); + return 0; + } + + // The code below assumes that there is at least one instruction, + // so just duck out immediately if the block is empty. + if (SUnits.empty()) return 0; + + // Manage saved state to enable multiple passes... + if (AntiDepTrials > 1) { + if (SavedState == NULL) { + SavedState = new AggressiveAntiDepState(*State); + } else { + delete State; + State = new AggressiveAntiDepState(*SavedState); + } + } + + // ...need a map from MI to SUnit. + std::map<MachineInstr *, SUnit *> MISUnitMap; + + DEBUG(errs() << "\n===== Attempting to break " << Candidates.size() << + " anti-dependencies\n"); + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + SUnit *SU = &SUnits[i]; + MISUnitMap.insert(std::pair<MachineInstr *, SUnit *>(SU->getInstr(), SU)); + } + +#ifndef NDEBUG + { + DEBUG(errs() << "Available regs:"); + for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { + if (!State->IsLive(Reg)) + DEBUG(errs() << " " << TRI->getName(Reg)); + } + DEBUG(errs() << '\n'); + } +#endif + + // Attempt to break anti-dependence edges. Walk the instructions + // from the bottom up, tracking information about liveness as we go + // to help determine which registers are available. + unsigned Broken = 0; + unsigned Count = InsertPosIndex - 1; + for (MachineBasicBlock::iterator I = End, E = Begin; + I != E; --Count) { + MachineInstr *MI = --I; + + DEBUG(errs() << "Anti: "); + DEBUG(MI->dump()); + + std::set<unsigned> PassthruRegs; + GetPassthruRegs(MI, PassthruRegs); + + // Process the defs in MI... + PrescanInstruction(MI, Count, PassthruRegs); + + std::vector<SDep*> Edges; + SUnit *PathSU = MISUnitMap[MI]; + AntiDepBreaker::CandidateMap::iterator + citer = Candidates.find(PathSU); + if (citer != Candidates.end()) + AntiDepPathStep(PathSU, citer->second, Edges); + + // Ignore KILL instructions (they form a group in ScanInstruction + // but don't cause any anti-dependence breaking themselves) + if (MI->getOpcode() != TargetInstrInfo::KILL) { + // Attempt to break each anti-dependency... + for (unsigned i = 0, e = Edges.size(); i != e; ++i) { + SDep *Edge = Edges[i]; + SUnit *NextSU = Edge->getSUnit(); + + if (Edge->getKind() != SDep::Anti) continue; + + unsigned AntiDepReg = Edge->getReg(); + DEBUG(errs() << "\tAntidep reg: " << TRI->getName(AntiDepReg)); + assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); + + if (!AllocatableSet.test(AntiDepReg)) { + // Don't break anti-dependencies on non-allocatable registers. + DEBUG(errs() << " (non-allocatable)\n"); + continue; + } else if (PassthruRegs.count(AntiDepReg) != 0) { + // If the anti-dep register liveness "passes-thru", then + // don't try to change it. It will be changed along with + // the use if required to break an earlier antidep. + DEBUG(errs() << " (passthru)\n"); + continue; + } else { + // No anti-dep breaking for implicit deps + MachineOperand *AntiDepOp = MI->findRegisterDefOperand(AntiDepReg); + assert(AntiDepOp != NULL && "Can't find index for defined register operand"); + if ((AntiDepOp == NULL) || AntiDepOp->isImplicit()) { + DEBUG(errs() << " (implicit)\n"); + continue; + } + + // If the SUnit has other dependencies on the SUnit that + // it anti-depends on, don't bother breaking the + // anti-dependency since those edges would prevent such + // units from being scheduled past each other + // regardless. + for (SUnit::pred_iterator P = PathSU->Preds.begin(), + PE = PathSU->Preds.end(); P != PE; ++P) { + if ((P->getSUnit() == NextSU) && (P->getKind() != SDep::Anti)) { + DEBUG(errs() << " (real dependency)\n"); + AntiDepReg = 0; + break; + } + } + + if (AntiDepReg == 0) continue; + } + + assert(AntiDepReg != 0); + if (AntiDepReg == 0) continue; + + // Determine AntiDepReg's register group. + const unsigned GroupIndex = State->GetGroup(AntiDepReg); + if (GroupIndex == 0) { + DEBUG(errs() << " (zero group)\n"); + continue; + } + + DEBUG(errs() << '\n'); + + // Look for a suitable register to use to break the anti-dependence. + std::map<unsigned, unsigned> RenameMap; + if (FindSuitableFreeRegisters(GroupIndex, RenameMap)) { + DEBUG(errs() << "\tBreaking anti-dependence edge on " + << TRI->getName(AntiDepReg) << ":"); + + // Handle each group register... + for (std::map<unsigned, unsigned>::iterator + S = RenameMap.begin(), E = RenameMap.end(); S != E; ++S) { + unsigned CurrReg = S->first; + unsigned NewReg = S->second; + + DEBUG(errs() << " " << TRI->getName(CurrReg) << "->" << + TRI->getName(NewReg) << "(" << + RegRefs.count(CurrReg) << " refs)"); + + // Update the references to the old register CurrReg to + // refer to the new register NewReg. + std::pair<std::multimap<unsigned, + AggressiveAntiDepState::RegisterReference>::iterator, + std::multimap<unsigned, + AggressiveAntiDepState::RegisterReference>::iterator> + Range = RegRefs.equal_range(CurrReg); + for (std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>::iterator + Q = Range.first, QE = Range.second; Q != QE; ++Q) { + Q->second.Operand->setReg(NewReg); + } + + // We just went back in time and modified history; the + // liveness information for CurrReg is now inconsistent. Set + // the state as if it were dead. + State->UnionGroups(NewReg, 0); + RegRefs.erase(NewReg); + DefIndices[NewReg] = DefIndices[CurrReg]; + KillIndices[NewReg] = KillIndices[CurrReg]; + + State->UnionGroups(CurrReg, 0); + RegRefs.erase(CurrReg); + DefIndices[CurrReg] = KillIndices[CurrReg]; + KillIndices[CurrReg] = ~0u; + assert(((KillIndices[CurrReg] == ~0u) != + (DefIndices[CurrReg] == ~0u)) && + "Kill and Def maps aren't consistent for AntiDepReg!"); + } + + ++Broken; + DEBUG(errs() << '\n'); + } + } + } + + ScanInstruction(MI, Count); + } + + return Broken; +} diff --git a/lib/CodeGen/AggressiveAntiDepBreaker.h b/lib/CodeGen/AggressiveAntiDepBreaker.h new file mode 100644 index 0000000..5d9b40b --- /dev/null +++ b/lib/CodeGen/AggressiveAntiDepBreaker.h @@ -0,0 +1,176 @@ +//=- llvm/CodeGen/AggressiveAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the AggressiveAntiDepBreaker class, which +// implements register anti-dependence breaking during post-RA +// scheduling. It attempts to break all anti-dependencies within a +// block. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H +#define LLVM_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H + +#include "AntiDepBreaker.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SmallSet.h" + +namespace llvm { + /// Class AggressiveAntiDepState + /// Contains all the state necessary for anti-dep breaking. We place + /// into a separate class so be can conveniently save/restore it to + /// enable multi-pass anti-dep breaking. + class AggressiveAntiDepState { + public: + /// RegisterReference - Information about a register reference + /// within a liverange + typedef struct { + /// Operand - The registers operand + MachineOperand *Operand; + /// RC - The register class + const TargetRegisterClass *RC; + } RegisterReference; + + private: + /// GroupNodes - Implements a disjoint-union data structure to + /// form register groups. A node is represented by an index into + /// the vector. A node can "point to" itself to indicate that it + /// is the parent of a group, or point to another node to indicate + /// that it is a member of the same group as that node. + std::vector<unsigned> GroupNodes; + + /// GroupNodeIndices - For each register, the index of the GroupNode + /// currently representing the group that the register belongs to. + /// Register 0 is always represented by the 0 group, a group + /// composed of registers that are not eligible for anti-aliasing. + unsigned GroupNodeIndices[TargetRegisterInfo::FirstVirtualRegister]; + + /// RegRefs - Map registers to all their references within a live range. + std::multimap<unsigned, RegisterReference> RegRefs; + + /// KillIndices - The index of the most recent kill (proceding bottom-up), + /// or ~0u if the register is not live. + unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; + + /// DefIndices - The index of the most recent complete def (proceding bottom + /// up), or ~0u if the register is live. + unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; + + public: + AggressiveAntiDepState(MachineBasicBlock *BB); + + /// GetKillIndices - Return the kill indices. + unsigned *GetKillIndices() { return KillIndices; } + + /// GetDefIndices - Return the define indices. + unsigned *GetDefIndices() { return DefIndices; } + + /// GetRegRefs - Return the RegRefs map. + std::multimap<unsigned, RegisterReference>& GetRegRefs() { return RegRefs; } + + // GetGroup - Get the group for a register. The returned value is + // the index of the GroupNode representing the group. + unsigned GetGroup(unsigned Reg); + + // GetGroupRegs - Return a vector of the registers belonging to a + // group. + void GetGroupRegs(unsigned Group, std::vector<unsigned> &Regs); + + // UnionGroups - Union Reg1's and Reg2's groups to form a new + // group. Return the index of the GroupNode representing the + // group. + unsigned UnionGroups(unsigned Reg1, unsigned Reg2); + + // LeaveGroup - Remove a register from its current group and place + // it alone in its own group. Return the index of the GroupNode + // representing the registers new group. + unsigned LeaveGroup(unsigned Reg); + + /// IsLive - Return true if Reg is live + bool IsLive(unsigned Reg); + }; + + + /// Class AggressiveAntiDepBreaker + class AggressiveAntiDepBreaker : public AntiDepBreaker { + MachineFunction& MF; + MachineRegisterInfo &MRI; + const TargetRegisterInfo *TRI; + + /// AllocatableSet - The set of allocatable registers. + /// We'll be ignoring anti-dependencies on non-allocatable registers, + /// because they may not be safe to break. + const BitVector AllocatableSet; + + /// State - The state used to identify and rename anti-dependence + /// registers. + AggressiveAntiDepState *State; + + /// SavedState - The state for the start of an anti-dep + /// region. Used to restore the state at the beginning of each + /// pass + AggressiveAntiDepState *SavedState; + + public: + AggressiveAntiDepBreaker(MachineFunction& MFi); + ~AggressiveAntiDepBreaker(); + + /// GetMaxTrials - As anti-dependencies are broken, additional + /// dependencies may be exposed, so multiple passes are required. + unsigned GetMaxTrials(); + + /// NeedCandidates - Candidates required. + bool NeedCandidates() { return true; } + + /// Start - Initialize anti-dep breaking for a new basic block. + void StartBlock(MachineBasicBlock *BB); + + /// BreakAntiDependencies - Identifiy anti-dependencies along the critical path + /// of the ScheduleDAG and break them by renaming registers. + /// + unsigned BreakAntiDependencies(std::vector<SUnit>& SUnits, + CandidateMap& Candidates, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex); + + /// Observe - Update liveness information to account for the current + /// instruction, which will not be scheduled. + /// + void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex); + + /// Finish - Finish anti-dep breaking for a basic block. + void FinishBlock(); + + private: + /// IsImplicitDefUse - Return true if MO represents a register + /// that is both implicitly used and defined in MI + bool IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO); + + /// GetPassthruRegs - If MI implicitly def/uses a register, then + /// return that register and all subregisters. + void GetPassthruRegs(MachineInstr *MI, std::set<unsigned>& PassthruRegs); + + void HandleLastUse(unsigned Reg, unsigned KillIdx, const char *tag); + void PrescanInstruction(MachineInstr *MI, unsigned Count, + std::set<unsigned>& PassthruRegs); + void ScanInstruction(MachineInstr *MI, unsigned Count); + BitVector GetRenameRegisters(unsigned Reg); + bool FindSuitableFreeRegisters(unsigned AntiDepGroupIndex, + std::map<unsigned, unsigned> &RenameMap); + }; +} + +#endif diff --git a/lib/CodeGen/AntiDepBreaker.h b/lib/CodeGen/AntiDepBreaker.h new file mode 100644 index 0000000..2775087 --- /dev/null +++ b/lib/CodeGen/AntiDepBreaker.h @@ -0,0 +1,73 @@ +//=- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the AntiDepBreaker class, which implements +// anti-dependence breaking heuristics for post-register-allocation scheduling. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_ANTIDEPBREAKER_H +#define LLVM_CODEGEN_ANTIDEPBREAKER_H + +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallVector.h" + +namespace llvm { + +/// AntiDepBreaker - This class works into conjunction with the +/// post-RA scheduler to rename registers to break register +/// anti-dependencies. +class AntiDepBreaker { +public: + typedef SmallSet<unsigned, 4> AntiDepRegSet; + typedef SmallVector<unsigned, 4> AntiDepRegVector; + typedef std::map<SUnit *, AntiDepRegVector> CandidateMap; + + virtual ~AntiDepBreaker(); + + /// GetMaxTrials - Return the maximum number of anti-dependence + /// breaking attempts that will be made for a block. + virtual unsigned GetMaxTrials() =0; + + /// NeedCandidates - Return true if the schedule must provide + /// candidates with BreakAntiDependencies(). + virtual bool NeedCandidates() =0; + + /// Start - Initialize anti-dep breaking for a new basic block. + virtual void StartBlock(MachineBasicBlock *BB) =0; + + /// BreakAntiDependencies - Identifiy anti-dependencies within a + /// basic-block region and break them by renaming registers. Return + /// the number of anti-dependencies broken. + /// + virtual unsigned BreakAntiDependencies(std::vector<SUnit>& SUnits, + CandidateMap& Candidates, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex) =0; + + /// Observe - Update liveness information to account for the current + /// instruction, which will not be scheduled. + /// + virtual void Observe(MachineInstr *MI, unsigned Count, + unsigned InsertPosIndex) =0; + + /// Finish - Finish anti-dep breaking for a basic block. + virtual void FinishBlock() =0; +}; + +} + +#endif diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 8bc5ef9..58f3aa5 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -919,6 +919,8 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { default: llvm_unreachable("Unsupported operator!"); } + } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) { + GetBlockAddressSymbol(BA)->print(O, MAI); } else { llvm_unreachable("Unknown constant value!"); } @@ -1366,6 +1368,7 @@ void AsmPrinter::processDebugLoc(const MachineInstr *MI, unsigned L = DW->RecordSourceLine(CurDLT.Line, CurDLT.Col, CurDLT.Scope); printLabel(L); + O << '\n'; #ifdef ATTACH_DEBUG_INFO_TO_AN_INSN DW->SetDbgScopeBeginLabels(MI, L); #endif @@ -1613,6 +1616,24 @@ bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, return true; } +MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const { + return GetBlockAddressSymbol(BA->getFunction(), BA->getBasicBlock()); +} + +MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F, + const BasicBlock *BB) const { + assert(BB->hasName() && + "Address of anonymous basic block not supported yet!"); + + // FIXME: This isn't guaranteed to produce a unique name even if the + // block and function have a name. + std::string Mangled = + Mang->getMangledName(F, Mang->makeNameProper(BB->getName()).c_str(), + /*ForcePrivate=*/true); + + return OutContext.GetOrCreateSymbol(StringRef(Mangled)); +} + MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const { SmallString<60> Name; raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BB" @@ -1626,9 +1647,27 @@ MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const { /// MachineBasicBlock, an alignment (if present) and a comment describing /// it if appropriate. void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { + // Emit an alignment directive for this block, if needed. if (unsigned Align = MBB->getAlignment()) EmitAlignment(Log2_32(Align)); + // If the block has its address taken, emit a special label to satisfy + // references to the block. This is done so that we don't need to + // remember the number of this label, and so that we can make + // forward references to labels without knowing what their numbers + // will be. + if (MBB->hasAddressTaken()) { + GetBlockAddressSymbol(MBB->getBasicBlock()->getParent(), + MBB->getBasicBlock())->print(O, MAI); + O << ':'; + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " Address Taken"; + } + O << '\n'; + } + + // Print the main label for the block. if (MBB->pred_empty() || MBB->isOnlyReachableByFallthrough()) { if (VerboseAsm) O << MAI->getCommentString() << " BB#" << MBB->getNumber() << ':'; @@ -1639,6 +1678,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { O << '\n'; } + // Print some comments to accompany the label. if (VerboseAsm) { if (const BasicBlock *BB = MBB->getBasicBlock()) if (BB->hasName()) { diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index d50e5e3..23752c4 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -124,7 +124,7 @@ public: //===----------------------------------------------------------------------===// /// DbgVariable - This class is used to track local variable information. /// -class VISIBILITY_HIDDEN DbgVariable { +class DbgVariable { DIVariable Var; // Variable Descriptor. unsigned FrameIndex; // Variable frame index. bool InlinedFnVar; // Variable for an inlined function. @@ -142,7 +142,7 @@ public: /// DbgScope - This class is used to track scope information. /// class DbgConcreteScope; -class VISIBILITY_HIDDEN DbgScope { +class DbgScope { DbgScope *Parent; // Parent to this scope. DIDescriptor Desc; // Debug info descriptor for scope. // FIXME use WeakVH for Desc. @@ -1249,6 +1249,9 @@ CompileUnit &DwarfDebug::FindCompileUnit(DICompileUnit Unit) const { DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) { // Get the descriptor. const DIVariable &VD = DV->getVariable(); + const char *Name = VD.getName(); + if (!Name) + return NULL; // Translate tag to proper Dwarf tag. The result variable is dropped for // now. @@ -1267,7 +1270,6 @@ DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) { // Define variable debug information entry. DIE *VariableDie = new DIE(Tag); - const char *Name = VD.getName(); AddString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); // Add source line info if available. @@ -1304,15 +1306,16 @@ DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) { /// DbgScope *DwarfDebug::getDbgScope(MDNode *N, const MachineInstr *MI, MDNode *InlinedAt) { - DbgScope *&Slot = DbgScopeMap[N]; - if (Slot) return Slot; + ValueMap<MDNode *, DbgScope *>::iterator VI = DbgScopeMap.find(N); + if (VI != DbgScopeMap.end()) + return VI->second; DbgScope *Parent = NULL; if (InlinedAt) { DILocation IL(InlinedAt); assert (!IL.isNull() && "Invalid InlindAt location!"); - DenseMap<MDNode *, DbgScope *>::iterator DSI = + ValueMap<MDNode *, DbgScope *>::iterator DSI = DbgScopeMap.find(IL.getScope().getNode()); assert (DSI != DbgScopeMap.end() && "Unable to find InlineAt scope!"); Parent = DSI->second; @@ -1334,17 +1337,18 @@ DbgScope *DwarfDebug::getDbgScope(MDNode *N, const MachineInstr *MI, assert (0 && "Unexpected scope info"); } - Slot = new DbgScope(Parent, DIDescriptor(N), InlinedAt); - Slot->setFirstInsn(MI); + DbgScope *NScope = new DbgScope(Parent, DIDescriptor(N), InlinedAt); + NScope->setFirstInsn(MI); if (Parent) - Parent->AddScope(Slot); + Parent->AddScope(NScope); else // First function is top level function. if (!FunctionDbgScope) - FunctionDbgScope = Slot; + FunctionDbgScope = NScope; - return Slot; + DbgScopeMap.insert(std::make_pair(N, NScope)); + return NScope; } @@ -1812,7 +1816,7 @@ void DwarfDebug::CollectVariableInfo() { if (DV.isNull()) continue; unsigned VSlot = VI->second; DbgScope *Scope = NULL; - DenseMap<MDNode *, DbgScope *>::iterator DSI = + ValueMap<MDNode *, DbgScope *>::iterator DSI = DbgScopeMap.find(DV.getContext().getNode()); if (DSI != DbgScopeMap.end()) Scope = DSI->second; @@ -1884,8 +1888,10 @@ bool DwarfDebug::ExtractScopeInformation(MachineFunction *MF) { // If a scope's last instruction is not set then use its child scope's // last instruction as this scope's last instrunction. - for (DenseMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(), + for (ValueMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(), DE = DbgScopeMap.end(); DI != DE; ++DI) { + DbgScope *S = DI->second; + if (!S) continue; assert (DI->second->getFirstInsn() && "Invalid first instruction!"); DI->second->FixInstructionMarkers(); assert (DI->second->getLastInsn() && "Invalid last instruction!"); @@ -1895,10 +1901,10 @@ bool DwarfDebug::ExtractScopeInformation(MachineFunction *MF) { // and end of a scope respectively. Create an inverse map that list scopes // starts (and ends) with an instruction. One instruction may start (or end) // multiple scopes. - for (DenseMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(), + for (ValueMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(), DE = DbgScopeMap.end(); DI != DE; ++DI) { DbgScope *S = DI->second; - assert (S && "DbgScope is missing!"); + if (!S) continue; const MachineInstr *MI = S->getFirstInsn(); assert (MI && "DbgScope does not have first instruction!"); @@ -2172,7 +2178,7 @@ void DwarfDebug::RecordVariable(MDNode *N, unsigned FrameIndex) { if (!SP.isNull()) { // SP is inserted into DbgAbstractScopeMap when inlined function // start was recorded by RecordInlineFnStart. - DenseMap<MDNode *, DbgScope *>::iterator + ValueMap<MDNode *, DbgScope *>::iterator I = DbgAbstractScopeMap.find(SP.getNode()); if (I != DbgAbstractScopeMap.end()) { InlinedVar = true; @@ -2249,7 +2255,7 @@ unsigned DwarfDebug::RecordInlinedFnStart(DISubprogram &SP, DICompileUnit CU, LexicalScopeStack.back()->AddConcreteInst(ConcreteScope); // Keep track of the concrete scope that's inlined into this function. - DenseMap<MDNode *, SmallVector<DbgScope *, 8> >::iterator + ValueMap<MDNode *, SmallVector<DbgScope *, 8> >::iterator SI = DbgConcreteScopeMap.find(Node); if (SI == DbgConcreteScopeMap.end()) @@ -2258,7 +2264,7 @@ unsigned DwarfDebug::RecordInlinedFnStart(DISubprogram &SP, DICompileUnit CU, SI->second.push_back(ConcreteScope); // Track the start label for this inlined function. - DenseMap<MDNode *, SmallVector<unsigned, 4> >::iterator + ValueMap<MDNode *, SmallVector<unsigned, 4> >::iterator I = InlineInfo.find(Node); if (I == InlineInfo.end()) @@ -2281,7 +2287,7 @@ unsigned DwarfDebug::RecordInlinedFnEnd(DISubprogram &SP) { DebugTimer->startTimer(); MDNode *Node = SP.getNode(); - DenseMap<MDNode *, SmallVector<DbgScope *, 8> >::iterator + ValueMap<MDNode *, SmallVector<DbgScope *, 8> >::iterator I = DbgConcreteScopeMap.find(Node); if (I == DbgConcreteScopeMap.end()) { @@ -2989,7 +2995,7 @@ void DwarfDebug::EmitDebugInlineInfo() { Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version"); Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)"); - for (DenseMap<MDNode *, SmallVector<unsigned, 4> >::iterator + for (ValueMap<MDNode *, SmallVector<unsigned, 4> >::iterator I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) { MDNode *Node = I->first; SmallVector<unsigned, 4> &Labels = I->second; diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 7f71104..ddb0a15 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -20,7 +20,7 @@ #include "llvm/CodeGen/MachineLocation.h" #include "llvm/Analysis/DebugInfo.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/ValueMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringMap.h" @@ -139,7 +139,7 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf { DbgScope *FunctionDbgScope; /// DbgScopeMap - Tracks the scopes in the current function. - DenseMap<MDNode *, DbgScope *> DbgScopeMap; + ValueMap<MDNode *, DbgScope *> DbgScopeMap; /// ScopedGVs - Tracks global variables that are not at file scope. /// For example void f() { static int b = 42; } @@ -156,16 +156,16 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf { /// DbgAbstractScopeMap - Tracks abstract instance scopes in the current /// function. - DenseMap<MDNode *, DbgScope *> DbgAbstractScopeMap; + ValueMap<MDNode *, DbgScope *> DbgAbstractScopeMap; /// DbgConcreteScopeMap - Tracks concrete instance scopes in the current /// function. - DenseMap<MDNode *, + ValueMap<MDNode *, SmallVector<DbgScope *, 8> > DbgConcreteScopeMap; /// InlineInfo - Keep track of inlined functions and their location. This /// information is used to populate debug_inlined section. - DenseMap<MDNode *, SmallVector<unsigned, 4> > InlineInfo; + ValueMap<MDNode *, SmallVector<unsigned, 4> > InlineInfo; /// AbstractInstanceRootMap - Map of abstract instance roots of inlined /// functions. These are subroutine entries that contain a DW_AT_inline diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp index 06b92b7..9286ad5 100644 --- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp @@ -20,14 +20,13 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { - class VISIBILITY_HIDDEN OcamlGCMetadataPrinter : public GCMetadataPrinter { + class OcamlGCMetadataPrinter : public GCMetadataPrinter { public: void beginAssembly(raw_ostream &OS, AsmPrinter &AP, const MCAsmInfo &MAI); diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index 66c5aa5..baea964 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -18,6 +18,7 @@ #define DEBUG_TYPE "branchfolding" #include "BranchFolding.h" +#include "llvm/Function.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -444,6 +445,36 @@ static bool MergeCompare(const std::pair<unsigned,MachineBasicBlock*> &p, } } +/// ProfitableToMerge - Check if two machine basic blocks have a common tail +/// and decide if it would be profitable to merge those tails. Return the +/// length of the common tail and iterators to the first common instruction +/// in each block. +static bool ProfitableToMerge(MachineBasicBlock *MBB1, + MachineBasicBlock *MBB2, + unsigned minCommonTailLength, + unsigned &CommonTailLen, + MachineBasicBlock::iterator &I1, + MachineBasicBlock::iterator &I2) { + CommonTailLen = ComputeCommonTailLength(MBB1, MBB2, I1, I2); + MachineFunction *MF = MBB1->getParent(); + + if (CommonTailLen >= minCommonTailLength) + return true; + + if (CommonTailLen == 0) + return false; + + // If we are optimizing for code size, 1 instruction in common is enough if + // we don't have to split a block. At worst we will be replacing a + // fallthrough into the common tail with a branch, which at worst breaks + // even with falling through into the duplicated common tail. + if (MF->getFunction()->hasFnAttr(Attribute::OptimizeForSize) && + (I1 == MBB1->begin() || I2 == MBB2->begin())) + return true; + + return false; +} + /// ComputeSameTails - Look through all the blocks in MergePotentials that have /// hash CurHash (guaranteed to match the last element). Build the vector /// SameTails of all those that have the (same) largest number of instructions @@ -465,22 +496,9 @@ unsigned BranchFolder::ComputeSameTails(unsigned CurHash, CurMPIter!=B && CurMPIter->first==CurHash; --CurMPIter) { for (MPIterator I = prior(CurMPIter); I->first==CurHash ; --I) { - unsigned CommonTailLen = ComputeCommonTailLength( - CurMPIter->second, - I->second, - TrialBBI1, TrialBBI2); - // If we will have to split a block, there should be at least - // minCommonTailLength instructions in common; if not, at worst - // we will be replacing a fallthrough into the common tail with a - // branch, which at worst breaks even with falling through into - // the duplicated common tail, so 1 instruction in common is enough. - // We will always pick a block we do not have to split as the common - // tail if there is one. - // (Empty blocks will get forwarded and need not be considered.) - if (CommonTailLen >= minCommonTailLength || - (CommonTailLen > 0 && - (TrialBBI1==CurMPIter->second->begin() || - TrialBBI2==I->second->begin()))) { + unsigned CommonTailLen; + if (ProfitableToMerge(CurMPIter->second, I->second, minCommonTailLength, + CommonTailLen, TrialBBI1, TrialBBI2)) { if (CommonTailLen > maxCommonTailLength) { SameTails.clear(); maxCommonTailLength = CommonTailLen; @@ -863,8 +881,9 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { // If this block is empty, make everyone use its fall-through, not the block // explicitly. Landing pads should not do this since the landing-pad table - // points to this block. - if (MBB->empty() && !MBB->isLandingPad()) { + // points to this block. Blocks with their addresses taken shouldn't be + // optimized away. + if (MBB->empty() && !MBB->isLandingPad() && !MBB->hasAddressTaken()) { // Dead block? Leave for cleanup later. if (MBB->pred_empty()) return MadeChange; @@ -1031,7 +1050,8 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { // If this branch is the only thing in its block, see if we can forward // other blocks across it. if (CurTBB && CurCond.empty() && CurFBB == 0 && - MBB->begin()->getDesc().isBranch() && CurTBB != MBB) { + MBB->begin()->getDesc().isBranch() && CurTBB != MBB && + !MBB->hasAddressTaken()) { // This block may contain just an unconditional branch. Because there can // be 'non-branch terminators' in the block, try removing the branch and // then seeing if the block is empty. diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index 713c30c..9583edc 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/lib/CodeGen/CMakeLists.txt @@ -1,6 +1,8 @@ add_llvm_library(LLVMCodeGen + AggressiveAntiDepBreaker.cpp BranchFolding.cpp CodePlacementOpt.cpp + CriticalAntiDepBreaker.cpp DeadMachineInstructionElim.cpp DwarfEHPrepare.cpp ELFCodeEmitter.cpp @@ -40,6 +42,7 @@ add_llvm_library(LLVMCodeGen Passes.cpp PostRASchedulerList.cpp PreAllocSplitting.cpp + ProcessImplicitDefs.cpp PrologEpilogInserter.cpp PseudoSourceValue.cpp RegAllocLinearScan.cpp @@ -55,6 +58,7 @@ add_llvm_library(LLVMCodeGen ShrinkWrapping.cpp SimpleRegisterCoalescing.cpp SjLjEHPrepare.cpp + SlotIndexes.cpp Spiller.cpp StackProtector.cpp StackSlotColoring.cpp diff --git a/lib/CodeGen/CriticalAntiDepBreaker.cpp b/lib/CodeGen/CriticalAntiDepBreaker.cpp new file mode 100644 index 0000000..984e013 --- /dev/null +++ b/lib/CodeGen/CriticalAntiDepBreaker.cpp @@ -0,0 +1,540 @@ +//===----- CriticalAntiDepBreaker.cpp - Anti-dep breaker -------- ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the CriticalAntiDepBreaker class, which +// implements register anti-dependence breaking along a blocks +// critical path during post-RA scheduler. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "post-RA-sched" +#include "CriticalAntiDepBreaker.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +CriticalAntiDepBreaker:: +CriticalAntiDepBreaker(MachineFunction& MFi) : + AntiDepBreaker(), MF(MFi), + MRI(MF.getRegInfo()), + TRI(MF.getTarget().getRegisterInfo()), + AllocatableSet(TRI->getAllocatableSet(MF)) +{ +} + +CriticalAntiDepBreaker::~CriticalAntiDepBreaker() { +} + +void CriticalAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { + // Clear out the register class data. + std::fill(Classes, array_endof(Classes), + static_cast<const TargetRegisterClass *>(0)); + + // Initialize the indices to indicate that no registers are live. + std::fill(KillIndices, array_endof(KillIndices), ~0u); + std::fill(DefIndices, array_endof(DefIndices), BB->size()); + + // Clear "do not change" set. + KeepRegs.clear(); + + bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); + + // Determine the live-out physregs for this block. + if (IsReturnBlock) { + // In a return block, examine the function live-out regs. + for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), + E = MRI.liveout_end(); I != E; ++I) { + unsigned Reg = *I; + Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } + } else { + // In a non-return block, examine the live-in regs of all successors. + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), + SE = BB->succ_end(); SI != SE; ++SI) + for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), + E = (*SI)->livein_end(); I != E; ++I) { + unsigned Reg = *I; + Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } + } + + // Mark live-out callee-saved registers. In a return block this is + // all callee-saved registers. In non-return this is any + // callee-saved register that is not saved in the prolog. + const MachineFrameInfo *MFI = MF.getFrameInfo(); + BitVector Pristine = MFI->getPristineRegs(BB); + for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { + unsigned Reg = *I; + if (!IsReturnBlock && !Pristine.test(Reg)) continue; + Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } +} + +void CriticalAntiDepBreaker::FinishBlock() { + RegRefs.clear(); + KeepRegs.clear(); +} + +void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, + unsigned InsertPosIndex) { + assert(Count < InsertPosIndex && "Instruction index out of expected range!"); + + // Any register which was defined within the previous scheduling region + // may have been rescheduled and its lifetime may overlap with registers + // in ways not reflected in our current liveness state. For each such + // register, adjust the liveness state to be conservatively correct. + for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) + if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) { + assert(KillIndices[Reg] == ~0u && "Clobbered register is live!"); + // Mark this register to be non-renamable. + Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); + // Move the def index to the end of the previous region, to reflect + // that the def could theoretically have been scheduled at the end. + DefIndices[Reg] = InsertPosIndex; + } + + PrescanInstruction(MI); + ScanInstruction(MI, Count); +} + +/// CriticalPathStep - Return the next SUnit after SU on the bottom-up +/// critical path. +static SDep *CriticalPathStep(SUnit *SU) { + SDep *Next = 0; + unsigned NextDepth = 0; + // Find the predecessor edge with the greatest depth. + for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); + P != PE; ++P) { + SUnit *PredSU = P->getSUnit(); + unsigned PredLatency = P->getLatency(); + unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; + // In the case of a latency tie, prefer an anti-dependency edge over + // other types of edges. + if (NextDepth < PredTotalLatency || + (NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) { + NextDepth = PredTotalLatency; + Next = &*P; + } + } + return Next; +} + +void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) { + // Scan the register operands for this instruction and update + // Classes and RegRefs. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + const TargetRegisterClass *NewRC = 0; + + if (i < MI->getDesc().getNumOperands()) + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); + + // For now, only allow the register to be changed if its register + // class is consistent across all uses. + if (!Classes[Reg] && NewRC) + Classes[Reg] = NewRC; + else if (!NewRC || Classes[Reg] != NewRC) + Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); + + // Now check for aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + // If an alias of the reg is used during the live range, give up. + // Note that this allows us to skip checking if AntiDepReg + // overlaps with any of the aliases, among other things. + unsigned AliasReg = *Alias; + if (Classes[AliasReg]) { + Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1); + Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); + } + } + + // If we're still willing to consider this register, note the reference. + if (Classes[Reg] != reinterpret_cast<TargetRegisterClass *>(-1)) + RegRefs.insert(std::make_pair(Reg, &MO)); + + // It's not safe to change register allocation for source operands of + // that have special allocation requirements. + if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { + if (KeepRegs.insert(Reg)) { + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) + KeepRegs.insert(*Subreg); + } + } + } +} + +void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, + unsigned Count) { + // Update liveness. + // Proceding upwards, registers that are defed but not used in this + // instruction are now dead. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + if (!MO.isDef()) continue; + // Ignore two-addr defs. + if (MI->isRegTiedToUseOperand(i)) continue; + + DefIndices[Reg] = Count; + KillIndices[Reg] = ~0u; + assert(((KillIndices[Reg] == ~0u) != + (DefIndices[Reg] == ~0u)) && + "Kill and Def maps aren't consistent for Reg!"); + KeepRegs.erase(Reg); + Classes[Reg] = 0; + RegRefs.erase(Reg); + // Repeat, for all subregs. + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) { + unsigned SubregReg = *Subreg; + DefIndices[SubregReg] = Count; + KillIndices[SubregReg] = ~0u; + KeepRegs.erase(SubregReg); + Classes[SubregReg] = 0; + RegRefs.erase(SubregReg); + } + // Conservatively mark super-registers as unusable. + for (const unsigned *Super = TRI->getSuperRegisters(Reg); + *Super; ++Super) { + unsigned SuperReg = *Super; + Classes[SuperReg] = reinterpret_cast<TargetRegisterClass *>(-1); + } + } + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + if (!MO.isUse()) continue; + + const TargetRegisterClass *NewRC = 0; + if (i < MI->getDesc().getNumOperands()) + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); + + // For now, only allow the register to be changed if its register + // class is consistent across all uses. + if (!Classes[Reg] && NewRC) + Classes[Reg] = NewRC; + else if (!NewRC || Classes[Reg] != NewRC) + Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); + + RegRefs.insert(std::make_pair(Reg, &MO)); + + // It wasn't previously live but now it is, this is a kill. + if (KillIndices[Reg] == ~0u) { + KillIndices[Reg] = Count; + DefIndices[Reg] = ~0u; + assert(((KillIndices[Reg] == ~0u) != + (DefIndices[Reg] == ~0u)) && + "Kill and Def maps aren't consistent for Reg!"); + } + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + if (KillIndices[AliasReg] == ~0u) { + KillIndices[AliasReg] = Count; + DefIndices[AliasReg] = ~0u; + } + } + } +} + +unsigned +CriticalAntiDepBreaker::findSuitableFreeRegister(unsigned AntiDepReg, + unsigned LastNewReg, + const TargetRegisterClass *RC) { + for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF), + RE = RC->allocation_order_end(MF); R != RE; ++R) { + unsigned NewReg = *R; + // Don't replace a register with itself. + if (NewReg == AntiDepReg) continue; + // Don't replace a register with one that was recently used to repair + // an anti-dependence with this AntiDepReg, because that would + // re-introduce that anti-dependence. + if (NewReg == LastNewReg) continue; + // If NewReg is dead and NewReg's most recent def is not before + // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. + assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) && + "Kill and Def maps aren't consistent for AntiDepReg!"); + assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) && + "Kill and Def maps aren't consistent for NewReg!"); + if (KillIndices[NewReg] != ~0u || + Classes[NewReg] == reinterpret_cast<TargetRegisterClass *>(-1) || + KillIndices[AntiDepReg] > DefIndices[NewReg]) + continue; + return NewReg; + } + + // No registers are free and available! + return 0; +} + +unsigned CriticalAntiDepBreaker:: +BreakAntiDependencies(std::vector<SUnit>& SUnits, + CandidateMap& Candidates, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex) { + // The code below assumes that there is at least one instruction, + // so just duck out immediately if the block is empty. + if (SUnits.empty()) return 0; + + // Find the node at the bottom of the critical path. + SUnit *Max = 0; + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + SUnit *SU = &SUnits[i]; + if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency) + Max = SU; + } + +#ifndef NDEBUG + { + DEBUG(errs() << "Critical path has total latency " + << (Max->getDepth() + Max->Latency) << "\n"); + DEBUG(errs() << "Available regs:"); + for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { + if (KillIndices[Reg] == ~0u) + DEBUG(errs() << " " << TRI->getName(Reg)); + } + DEBUG(errs() << '\n'); + } +#endif + + // Track progress along the critical path through the SUnit graph as we walk + // the instructions. + SUnit *CriticalPathSU = Max; + MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); + + // Consider this pattern: + // A = ... + // ... = A + // A = ... + // ... = A + // A = ... + // ... = A + // A = ... + // ... = A + // There are three anti-dependencies here, and without special care, + // we'd break all of them using the same register: + // A = ... + // ... = A + // B = ... + // ... = B + // B = ... + // ... = B + // B = ... + // ... = B + // because at each anti-dependence, B is the first register that + // isn't A which is free. This re-introduces anti-dependencies + // at all but one of the original anti-dependencies that we were + // trying to break. To avoid this, keep track of the most recent + // register that each register was replaced with, avoid + // using it to repair an anti-dependence on the same register. + // This lets us produce this: + // A = ... + // ... = A + // B = ... + // ... = B + // C = ... + // ... = C + // B = ... + // ... = B + // This still has an anti-dependence on B, but at least it isn't on the + // original critical path. + // + // TODO: If we tracked more than one register here, we could potentially + // fix that remaining critical edge too. This is a little more involved, + // because unlike the most recent register, less recent registers should + // still be considered, though only if no other registers are available. + unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; + + // Attempt to break anti-dependence edges on the critical path. Walk the + // instructions from the bottom up, tracking information about liveness + // as we go to help determine which registers are available. + unsigned Broken = 0; + unsigned Count = InsertPosIndex - 1; + for (MachineBasicBlock::iterator I = End, E = Begin; + I != E; --Count) { + MachineInstr *MI = --I; + + // Check if this instruction has a dependence on the critical path that + // is an anti-dependence that we may be able to break. If it is, set + // AntiDepReg to the non-zero register associated with the anti-dependence. + // + // We limit our attention to the critical path as a heuristic to avoid + // breaking anti-dependence edges that aren't going to significantly + // impact the overall schedule. There are a limited number of registers + // and we want to save them for the important edges. + // + // TODO: Instructions with multiple defs could have multiple + // anti-dependencies. The current code here only knows how to break one + // edge per instruction. Note that we'd have to be able to break all of + // the anti-dependencies in an instruction in order to be effective. + unsigned AntiDepReg = 0; + if (MI == CriticalPathMI) { + if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { + SUnit *NextSU = Edge->getSUnit(); + + // Only consider anti-dependence edges. + if (Edge->getKind() == SDep::Anti) { + AntiDepReg = Edge->getReg(); + assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); + if (!AllocatableSet.test(AntiDepReg)) + // Don't break anti-dependencies on non-allocatable registers. + AntiDepReg = 0; + else if (KeepRegs.count(AntiDepReg)) + // Don't break anti-dependencies if an use down below requires + // this exact register. + AntiDepReg = 0; + else { + // If the SUnit has other dependencies on the SUnit that it + // anti-depends on, don't bother breaking the anti-dependency + // since those edges would prevent such units from being + // scheduled past each other regardless. + // + // Also, if there are dependencies on other SUnits with the + // same register as the anti-dependency, don't attempt to + // break it. + for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(), + PE = CriticalPathSU->Preds.end(); P != PE; ++P) + if (P->getSUnit() == NextSU ? + (P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) : + (P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) { + AntiDepReg = 0; + break; + } + } + } + CriticalPathSU = NextSU; + CriticalPathMI = CriticalPathSU->getInstr(); + } else { + // We've reached the end of the critical path. + CriticalPathSU = 0; + CriticalPathMI = 0; + } + } + + PrescanInstruction(MI); + + if (MI->getDesc().hasExtraDefRegAllocReq()) + // If this instruction's defs have special allocation requirement, don't + // break this anti-dependency. + AntiDepReg = 0; + else if (AntiDepReg) { + // If this instruction has a use of AntiDepReg, breaking it + // is invalid. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + if (MO.isUse() && AntiDepReg == Reg) { + AntiDepReg = 0; + break; + } + } + } + + // Determine AntiDepReg's register class, if it is live and is + // consistently used within a single class. + const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; + assert((AntiDepReg == 0 || RC != NULL) && + "Register should be live if it's causing an anti-dependence!"); + if (RC == reinterpret_cast<TargetRegisterClass *>(-1)) + AntiDepReg = 0; + + // Look for a suitable register to use to break the anti-depenence. + // + // TODO: Instead of picking the first free register, consider which might + // be the best. + if (AntiDepReg != 0) { + if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, + LastNewReg[AntiDepReg], + RC)) { + DEBUG(errs() << "Breaking anti-dependence edge on " + << TRI->getName(AntiDepReg) + << " with " << RegRefs.count(AntiDepReg) << " references" + << " using " << TRI->getName(NewReg) << "!\n"); + + // Update the references to the old register to refer to the new + // register. + std::pair<std::multimap<unsigned, MachineOperand *>::iterator, + std::multimap<unsigned, MachineOperand *>::iterator> + Range = RegRefs.equal_range(AntiDepReg); + for (std::multimap<unsigned, MachineOperand *>::iterator + Q = Range.first, QE = Range.second; Q != QE; ++Q) + Q->second->setReg(NewReg); + + // We just went back in time and modified history; the + // liveness information for the anti-depenence reg is now + // inconsistent. Set the state as if it were dead. + Classes[NewReg] = Classes[AntiDepReg]; + DefIndices[NewReg] = DefIndices[AntiDepReg]; + KillIndices[NewReg] = KillIndices[AntiDepReg]; + assert(((KillIndices[NewReg] == ~0u) != + (DefIndices[NewReg] == ~0u)) && + "Kill and Def maps aren't consistent for NewReg!"); + + Classes[AntiDepReg] = 0; + DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; + KillIndices[AntiDepReg] = ~0u; + assert(((KillIndices[AntiDepReg] == ~0u) != + (DefIndices[AntiDepReg] == ~0u)) && + "Kill and Def maps aren't consistent for AntiDepReg!"); + + RegRefs.erase(AntiDepReg); + LastNewReg[AntiDepReg] = NewReg; + ++Broken; + } + } + + ScanInstruction(MI, Count); + } + + return Broken; +} diff --git a/lib/CodeGen/CriticalAntiDepBreaker.h b/lib/CodeGen/CriticalAntiDepBreaker.h new file mode 100644 index 0000000..5664d85 --- /dev/null +++ b/lib/CodeGen/CriticalAntiDepBreaker.h @@ -0,0 +1,103 @@ +//=- llvm/CodeGen/CriticalAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the CriticalAntiDepBreaker class, which +// implements register anti-dependence breaking along a blocks +// critical path during post-RA scheduler. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H +#define LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H + +#include "AntiDepBreaker.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SmallSet.h" + +namespace llvm { + class CriticalAntiDepBreaker : public AntiDepBreaker { + MachineFunction& MF; + MachineRegisterInfo &MRI; + const TargetRegisterInfo *TRI; + + /// AllocatableSet - The set of allocatable registers. + /// We'll be ignoring anti-dependencies on non-allocatable registers, + /// because they may not be safe to break. + const BitVector AllocatableSet; + + /// Classes - For live regs that are only used in one register class in a + /// live range, the register class. If the register is not live, the + /// corresponding value is null. If the register is live but used in + /// multiple register classes, the corresponding value is -1 casted to a + /// pointer. + const TargetRegisterClass * + Classes[TargetRegisterInfo::FirstVirtualRegister]; + + /// RegRegs - Map registers to all their references within a live range. + std::multimap<unsigned, MachineOperand *> RegRefs; + + /// KillIndices - The index of the most recent kill (proceding bottom-up), + /// or ~0u if the register is not live. + unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; + + /// DefIndices - The index of the most recent complete def (proceding bottom + /// up), or ~0u if the register is live. + unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; + + /// KeepRegs - A set of registers which are live and cannot be changed to + /// break anti-dependencies. + SmallSet<unsigned, 4> KeepRegs; + + public: + CriticalAntiDepBreaker(MachineFunction& MFi); + ~CriticalAntiDepBreaker(); + + /// GetMaxTrials - Critical path anti-dependence breaking requires + /// only a single pass + unsigned GetMaxTrials() { return 1; } + + /// NeedCandidates - Candidates not needed. + bool NeedCandidates() { return false; } + + /// Start - Initialize anti-dep breaking for a new basic block. + void StartBlock(MachineBasicBlock *BB); + + /// BreakAntiDependencies - Identifiy anti-dependencies along the critical path + /// of the ScheduleDAG and break them by renaming registers. + /// + unsigned BreakAntiDependencies(std::vector<SUnit>& SUnits, + CandidateMap& Candidates, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex); + + /// Observe - Update liveness information to account for the current + /// instruction, which will not be scheduled. + /// + void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex); + + /// Finish - Finish anti-dep breaking for a basic block. + void FinishBlock(); + + private: + void PrescanInstruction(MachineInstr *MI); + void ScanInstruction(MachineInstr *MI, unsigned Count); + unsigned findSuitableFreeRegister(unsigned AntiDepReg, + unsigned LastNewReg, + const TargetRegisterClass *); + }; +} + +#endif diff --git a/lib/CodeGen/DeadMachineInstructionElim.cpp b/lib/CodeGen/DeadMachineInstructionElim.cpp index 078ed3d..07a5d38 100644 --- a/lib/CodeGen/DeadMachineInstructionElim.cpp +++ b/lib/CodeGen/DeadMachineInstructionElim.cpp @@ -15,7 +15,6 @@ #include "llvm/Pass.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" @@ -23,8 +22,7 @@ using namespace llvm; namespace { - class VISIBILITY_HIDDEN DeadMachineInstructionElim : - public MachineFunctionPass { + class DeadMachineInstructionElim : public MachineFunctionPass { virtual bool runOnMachineFunction(MachineFunction &MF); const TargetRegisterInfo *TRI; diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp index 72b3f92..7fc62a9 100644 --- a/lib/CodeGen/DwarfEHPrepare.cpp +++ b/lib/CodeGen/DwarfEHPrepare.cpp @@ -21,7 +21,6 @@ #include "llvm/IntrinsicInst.h" #include "llvm/Module.h" #include "llvm/Pass.h" -#include "llvm/Support/Compiler.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" @@ -33,7 +32,7 @@ STATISTIC(NumExceptionValuesMoved, "Number of eh.exception calls moved"); STATISTIC(NumStackTempsIntroduced, "Number of stack temporaries introduced"); namespace { - class VISIBILITY_HIDDEN DwarfEHPrepare : public FunctionPass { + class DwarfEHPrepare : public FunctionPass { const TargetLowering *TLI; bool CompileFast; diff --git a/lib/CodeGen/ELF.h b/lib/CodeGen/ELF.h index b466e89..e303ebb 100644 --- a/lib/CodeGen/ELF.h +++ b/lib/CodeGen/ELF.h @@ -22,7 +22,7 @@ #include "llvm/CodeGen/BinaryObject.h" #include "llvm/CodeGen/MachineRelocation.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/System/DataTypes.h" namespace llvm { class GlobalValue; diff --git a/lib/CodeGen/ExactHazardRecognizer.cpp b/lib/CodeGen/ExactHazardRecognizer.cpp index f35d196..36925b1 100644 --- a/lib/CodeGen/ExactHazardRecognizer.cpp +++ b/lib/CodeGen/ExactHazardRecognizer.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "exact-hazards" +#define DEBUG_TYPE "post-RA-sched" #include "ExactHazardRecognizer.h" #include "llvm/CodeGen/ScheduleHazardRecognizer.h" #include "llvm/Support/Debug.h" diff --git a/lib/CodeGen/GCMetadata.cpp b/lib/CodeGen/GCMetadata.cpp index a57296c..4d25dcc 100644 --- a/lib/CodeGen/GCMetadata.cpp +++ b/lib/CodeGen/GCMetadata.cpp @@ -17,14 +17,13 @@ #include "llvm/Pass.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Function.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { - class VISIBILITY_HIDDEN Printer : public FunctionPass { + class Printer : public FunctionPass { static char ID; raw_ostream &OS; @@ -39,7 +38,7 @@ namespace { bool runOnFunction(Function &F); }; - class VISIBILITY_HIDDEN Deleter : public FunctionPass { + class Deleter : public FunctionPass { static char ID; public: diff --git a/lib/CodeGen/GCStrategy.cpp b/lib/CodeGen/GCStrategy.cpp index 6d0de41..6e0bde6 100644 --- a/lib/CodeGen/GCStrategy.cpp +++ b/lib/CodeGen/GCStrategy.cpp @@ -27,7 +27,6 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -39,7 +38,7 @@ namespace { /// llvm.gcwrite intrinsics, replacing them with simple loads and stores as /// directed by the GCStrategy. It also performs automatic root initialization /// and custom intrinsic lowering. - class VISIBILITY_HIDDEN LowerIntrinsics : public FunctionPass { + class LowerIntrinsics : public FunctionPass { static bool NeedsDefaultLoweringPass(const GCStrategy &C); static bool NeedsCustomLoweringPass(const GCStrategy &C); static bool CouldBecomeSafePoint(Instruction *I); @@ -63,7 +62,7 @@ namespace { /// function representation to identify safe points for the garbage collector /// in the machine code. It inserts labels at safe points and populates a /// GCMetadata record for each function. - class VISIBILITY_HIDDEN MachineCodeAnalysis : public MachineFunctionPass { + class MachineCodeAnalysis : public MachineFunctionPass { const TargetMachine *TM; GCFunctionInfo *FI; MachineModuleInfo *MMI; diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp index 7b613ff..45f08b1 100644 --- a/lib/CodeGen/IfConversion.cpp +++ b/lib/CodeGen/IfConversion.cpp @@ -59,7 +59,7 @@ STATISTIC(NumIfConvBBs, "Number of if-converted blocks"); STATISTIC(NumDupBBs, "Number of duplicated blocks"); namespace { - class VISIBILITY_HIDDEN IfConverter : public MachineFunctionPass { + class IfConverter : public MachineFunctionPass { enum IfcvtKind { ICNotClassfied, // BB data valid, but not classified. ICSimpleFalse, // Same as ICSimple, but on the false path. diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index e58a9ca..6300a52 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -39,8 +39,6 @@ static cl::opt<bool> PrintEmittedAsm("print-emitted-asm", cl::Hidden, cl::desc("Dump emitter generated instructions as assembly")); static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden, cl::desc("Dump garbage collector data")); -static cl::opt<bool> HoistConstants("hoist-constants", cl::Hidden, - cl::desc("Hoist constants out of loops")); static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden, cl::desc("Verify generated machine code"), cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL)); @@ -70,18 +68,6 @@ LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, if (addCommonCodeGenPasses(PM, OptLevel)) return FileModel::Error; - // Fold redundant debug labels. - PM.add(createDebugLabelFoldingPass()); - - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(errs())); - - if (addPreEmitPass(PM, OptLevel) && PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(errs())); - - if (OptLevel != CodeGenOpt::None) - PM.add(createCodePlacementOptPass()); - switch (FileType) { default: break; @@ -173,9 +159,6 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM, if (addCommonCodeGenPasses(PM, OptLevel)) return true; - if (addPreEmitPass(PM, OptLevel) && PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(errs())); - addCodeEmitter(PM, OptLevel, MCE); if (PrintEmittedAsm) addAssemblyEmitter(PM, OptLevel, true, ferrs()); @@ -198,9 +181,6 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM, if (addCommonCodeGenPasses(PM, OptLevel)) return true; - if (addPreEmitPass(PM, OptLevel) && PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(errs())); - addCodeEmitter(PM, OptLevel, JCE); if (PrintEmittedAsm) addAssemblyEmitter(PM, OptLevel, true, ferrs()); @@ -211,9 +191,10 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM, } static void printAndVerify(PassManagerBase &PM, + const char *Banner, bool allowDoubleDefs = false) { if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(errs())); + PM.add(createMachineFunctionPrinterPass(errs(), Banner)); if (VerifyMachineCode) PM.add(createMachineVerifierPass(allowDoubleDefs)); @@ -255,11 +236,8 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // Make sure that no unreachable blocks are instruction selected. PM.add(createUnreachableBlockEliminationPass()); - if (OptLevel != CodeGenOpt::None) { - if (HoistConstants) - PM.add(createCodeGenLICMPass()); + if (OptLevel != CodeGenOpt::None) PM.add(createCodeGenPreparePass(getTargetLowering())); - } PM.add(createStackProtectorPass(getTargetLowering())); @@ -283,61 +261,76 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, return true; // Print the instruction selected machine code... - printAndVerify(PM, /* allowDoubleDefs= */ true); + printAndVerify(PM, "After Instruction Selection", + /* allowDoubleDefs= */ true); if (OptLevel != CodeGenOpt::None) { PM.add(createMachineLICMPass()); PM.add(createMachineSinkingPass()); - printAndVerify(PM, /* allowDoubleDefs= */ true); + printAndVerify(PM, "After MachineLICM and MachineSinking", + /* allowDoubleDefs= */ true); } // Run pre-ra passes. if (addPreRegAlloc(PM, OptLevel)) - printAndVerify(PM, /* allowDoubleDefs= */ true); + printAndVerify(PM, "After PreRegAlloc passes", + /* allowDoubleDefs= */ true); // Perform register allocation. PM.add(createRegisterAllocator()); + printAndVerify(PM, "After Register Allocation"); // Perform stack slot coloring. - if (OptLevel != CodeGenOpt::None) + if (OptLevel != CodeGenOpt::None) { // FIXME: Re-enable coloring with register when it's capable of adding // kill markers. PM.add(createStackSlotColoringPass(false)); - - printAndVerify(PM); // Print the register-allocated code + printAndVerify(PM, "After StackSlotColoring"); + } // Run post-ra passes. if (addPostRegAlloc(PM, OptLevel)) - printAndVerify(PM); + printAndVerify(PM, "After PostRegAlloc passes"); PM.add(createLowerSubregsPass()); - printAndVerify(PM); + printAndVerify(PM, "After LowerSubregs"); // Insert prolog/epilog code. Eliminate abstract frame index references... PM.add(createPrologEpilogCodeInserter()); - printAndVerify(PM); + printAndVerify(PM, "After PrologEpilogCodeInserter"); // Run pre-sched2 passes. if (addPreSched2(PM, OptLevel)) - printAndVerify(PM); + printAndVerify(PM, "After PreSched2 passes"); // Second pass scheduler. if (OptLevel != CodeGenOpt::None) { PM.add(createPostRAScheduler(OptLevel)); - printAndVerify(PM); + printAndVerify(PM, "After PostRAScheduler"); } // Branch folding must be run after regalloc and prolog/epilog insertion. if (OptLevel != CodeGenOpt::None) { PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); - printAndVerify(PM); + printAndVerify(PM, "After BranchFolding"); } PM.add(createGCMachineCodeAnalysisPass()); - printAndVerify(PM); if (PrintGCInfo) PM.add(createGCInfoPrinter(errs())); + // Fold redundant debug labels. + PM.add(createDebugLabelFoldingPass()); + printAndVerify(PM, "After DebugLabelFolding"); + + if (addPreEmitPass(PM, OptLevel)) + printAndVerify(PM, "After PreEmit passes"); + + if (OptLevel != CodeGenOpt::None) { + PM.add(createCodePlacementOptPass()); + printAndVerify(PM, "After CodePlacementOpt"); + } + return false; } diff --git a/lib/CodeGen/LatencyPriorityQueue.cpp b/lib/CodeGen/LatencyPriorityQueue.cpp index 2e7b89c..794ecf7 100644 --- a/lib/CodeGen/LatencyPriorityQueue.cpp +++ b/lib/CodeGen/LatencyPriorityQueue.cpp @@ -55,6 +55,7 @@ SUnit *LatencyPriorityQueue::getSingleUnscheduledPred(SUnit *SU) { SUnit *OnlyAvailablePred = 0; for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; SUnit &Pred = *I->getSUnit(); if (!Pred.isScheduled) { // We found an available, but not scheduled, predecessor. If it's the @@ -73,9 +74,11 @@ void LatencyPriorityQueue::push_impl(SUnit *SU) { // this node is the sole unscheduled node for. unsigned NumNodesBlocking = 0; for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) + I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; if (getSingleUnscheduledPred(I->getSUnit()) == SU) ++NumNodesBlocking; + } NumNodesSolelyBlocking[SU->NodeNum] = NumNodesBlocking; Queue.push(SU); @@ -88,8 +91,10 @@ void LatencyPriorityQueue::push_impl(SUnit *SU) { // the node available. void LatencyPriorityQueue::ScheduledNode(SUnit *SU) { for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) + I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; AdjustPriorityOfUnscheduledPreds(I->getSUnit()); + } } /// AdjustPriorityOfUnscheduledPreds - One of the predecessors of SU was just diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index a02a4a6..8d632cb 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -19,6 +19,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/LiveInterval.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" @@ -28,11 +29,6 @@ #include <algorithm> using namespace llvm; -// Print a LiveIndex to a raw_ostream. -void LiveIndex::print(raw_ostream &os) const { - os << (index & ~PHI_BIT); -} - // An example for liveAt(): // // this = [1,4), liveAt(0) will return false. The instruction defining this @@ -40,7 +36,7 @@ void LiveIndex::print(raw_ostream &os) const { // variable it represents. This is because slot 1 is used (def slot) and spans // up to slot 3 (store slot). // -bool LiveInterval::liveAt(LiveIndex I) const { +bool LiveInterval::liveAt(SlotIndex I) const { Ranges::const_iterator r = std::upper_bound(ranges.begin(), ranges.end(), I); if (r == ranges.begin()) @@ -53,7 +49,7 @@ bool LiveInterval::liveAt(LiveIndex I) const { // liveBeforeAndAt - Check if the interval is live at the index and the index // just before it. If index is liveAt, check if it starts a new live range. // If it does, then check if the previous live range ends at index-1. -bool LiveInterval::liveBeforeAndAt(LiveIndex I) const { +bool LiveInterval::liveBeforeAndAt(SlotIndex I) const { Ranges::const_iterator r = std::upper_bound(ranges.begin(), ranges.end(), I); if (r == ranges.begin()) @@ -131,7 +127,7 @@ bool LiveInterval::overlapsFrom(const LiveInterval& other, /// overlaps - Return true if the live interval overlaps a range specified /// by [Start, End). -bool LiveInterval::overlaps(LiveIndex Start, LiveIndex End) const { +bool LiveInterval::overlaps(SlotIndex Start, SlotIndex End) const { assert(Start < End && "Invalid range"); const_iterator I = begin(); const_iterator E = end(); @@ -149,10 +145,10 @@ bool LiveInterval::overlaps(LiveIndex Start, LiveIndex End) const { /// specified by I to end at the specified endpoint. To do this, we should /// merge and eliminate all ranges that this will overlap with. The iterator is /// not invalidated. -void LiveInterval::extendIntervalEndTo(Ranges::iterator I, LiveIndex NewEnd) { +void LiveInterval::extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd) { assert(I != ranges.end() && "Not a valid interval!"); VNInfo *ValNo = I->valno; - LiveIndex OldEnd = I->end; + SlotIndex OldEnd = I->end; // Search for the first interval that we can't merge with. Ranges::iterator MergeTo = next(I); @@ -167,7 +163,7 @@ void LiveInterval::extendIntervalEndTo(Ranges::iterator I, LiveIndex NewEnd) { ranges.erase(next(I), MergeTo); // Update kill info. - ValNo->removeKills(OldEnd, I->end.prevSlot_()); + ValNo->removeKills(OldEnd, I->end.getPrevSlot()); // If the newly formed range now touches the range after it and if they have // the same value number, merge the two ranges into one range. @@ -183,7 +179,7 @@ void LiveInterval::extendIntervalEndTo(Ranges::iterator I, LiveIndex NewEnd) { /// specified by I to start at the specified endpoint. To do this, we should /// merge and eliminate all ranges that this will overlap with. LiveInterval::Ranges::iterator -LiveInterval::extendIntervalStartTo(Ranges::iterator I, LiveIndex NewStart) { +LiveInterval::extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStart) { assert(I != ranges.end() && "Not a valid interval!"); VNInfo *ValNo = I->valno; @@ -216,7 +212,7 @@ LiveInterval::extendIntervalStartTo(Ranges::iterator I, LiveIndex NewStart) { LiveInterval::iterator LiveInterval::addRangeFrom(LiveRange LR, iterator From) { - LiveIndex Start = LR.start, End = LR.end; + SlotIndex Start = LR.start, End = LR.end; iterator it = std::upper_bound(From, ranges.end(), Start); // If the inserted interval starts in the middle or right at the end of @@ -268,7 +264,7 @@ LiveInterval::addRangeFrom(LiveRange LR, iterator From) { /// isInOneLiveRange - Return true if the range specified is entirely in /// a single LiveRange of the live interval. -bool LiveInterval::isInOneLiveRange(LiveIndex Start, LiveIndex End) { +bool LiveInterval::isInOneLiveRange(SlotIndex Start, SlotIndex End) { Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start); if (I == ranges.begin()) return false; @@ -279,7 +275,7 @@ bool LiveInterval::isInOneLiveRange(LiveIndex Start, LiveIndex End) { /// removeRange - Remove the specified range from this interval. Note that /// the range must be in a single LiveRange in its entirety. -void LiveInterval::removeRange(LiveIndex Start, LiveIndex End, +void LiveInterval::removeRange(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo) { // Find the LiveRange containing this span. Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start); @@ -331,7 +327,7 @@ void LiveInterval::removeRange(LiveIndex Start, LiveIndex End, } // Otherwise, we are splitting the LiveRange into two pieces. - LiveIndex OldEnd = I->end; + SlotIndex OldEnd = I->end; I->end = Start; // Trim the old interval. // Insert the new one. @@ -362,36 +358,11 @@ void LiveInterval::removeValNo(VNInfo *ValNo) { ValNo->setIsUnused(true); } } - -/// scaleNumbering - Renumber VNI and ranges to provide gaps for new -/// instructions. - -void LiveInterval::scaleNumbering(unsigned factor) { - // Scale ranges. - for (iterator RI = begin(), RE = end(); RI != RE; ++RI) { - RI->start = RI->start.scale(factor); - RI->end = RI->end.scale(factor); - } - - // Scale VNI info. - for (vni_iterator VNI = vni_begin(), VNIE = vni_end(); VNI != VNIE; ++VNI) { - VNInfo *vni = *VNI; - - if (vni->isDefAccurate()) - vni->def = vni->def.scale(factor); - - for (unsigned i = 0; i < vni->kills.size(); ++i) { - if (!vni->kills[i].isPHIIndex()) - vni->kills[i] = vni->kills[i].scale(factor); - } - } -} - /// getLiveRangeContaining - Return the live range that contains the /// specified index, or null if there is none. LiveInterval::const_iterator -LiveInterval::FindLiveRangeContaining(LiveIndex Idx) const { +LiveInterval::FindLiveRangeContaining(SlotIndex Idx) const { const_iterator It = std::upper_bound(begin(), end(), Idx); if (It != ranges.begin()) { --It; @@ -403,7 +374,7 @@ LiveInterval::FindLiveRangeContaining(LiveIndex Idx) const { } LiveInterval::iterator -LiveInterval::FindLiveRangeContaining(LiveIndex Idx) { +LiveInterval::FindLiveRangeContaining(SlotIndex Idx) { iterator It = std::upper_bound(begin(), end(), Idx); if (It != begin()) { --It; @@ -416,7 +387,7 @@ LiveInterval::FindLiveRangeContaining(LiveIndex Idx) { /// findDefinedVNInfo - Find the VNInfo defined by the specified /// index (register interval). -VNInfo *LiveInterval::findDefinedVNInfoForRegInt(LiveIndex Idx) const { +VNInfo *LiveInterval::findDefinedVNInfoForRegInt(SlotIndex Idx) const { for (LiveInterval::const_vni_iterator i = vni_begin(), e = vni_end(); i != e; ++i) { if ((*i)->def == Idx) @@ -440,7 +411,8 @@ VNInfo *LiveInterval::findDefinedVNInfoForStackInt(unsigned reg) const { /// join - Join two live intervals (this, and other) together. This applies /// mappings to the value numbers in the LHS/RHS intervals as specified. If /// the intervals are not joinable, this aborts. -void LiveInterval::join(LiveInterval &Other, const int *LHSValNoAssignments, +void LiveInterval::join(LiveInterval &Other, + const int *LHSValNoAssignments, const int *RHSValNoAssignments, SmallVector<VNInfo*, 16> &NewVNInfo, MachineRegisterInfo *MRI) { @@ -554,14 +526,15 @@ void LiveInterval::MergeRangesInAsValue(const LiveInterval &RHS, /// The LiveRanges in RHS are allowed to overlap with LiveRanges in the /// current interval, it will replace the value numbers of the overlaped /// live ranges with the specified value number. -void LiveInterval::MergeValueInAsValue(const LiveInterval &RHS, - const VNInfo *RHSValNo, VNInfo *LHSValNo) { +void LiveInterval::MergeValueInAsValue( + const LiveInterval &RHS, + const VNInfo *RHSValNo, VNInfo *LHSValNo) { SmallVector<VNInfo*, 4> ReplacedValNos; iterator IP = begin(); for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { if (I->valno != RHSValNo) continue; - LiveIndex Start = I->start, End = I->end; + SlotIndex Start = I->start, End = I->end; IP = std::upper_bound(IP, end(), Start); // If the start of this range overlaps with an existing liverange, trim it. if (IP != begin() && IP[-1].end > Start) { @@ -621,7 +594,8 @@ void LiveInterval::MergeValueInAsValue(const LiveInterval &RHS, /// MergeInClobberRanges - For any live ranges that are not defined in the /// current interval, but are defined in the Clobbers interval, mark them /// used with an unknown definition value. -void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers, +void LiveInterval::MergeInClobberRanges(LiveIntervals &li_, + const LiveInterval &Clobbers, BumpPtrAllocator &VNInfoAllocator) { if (Clobbers.empty()) return; @@ -638,20 +612,20 @@ void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers, ClobberValNo = UnusedValNo; else { UnusedValNo = ClobberValNo = - getNextValue(LiveIndex(), 0, false, VNInfoAllocator); + getNextValue(li_.getInvalidIndex(), 0, false, VNInfoAllocator); ValNoMaps.insert(std::make_pair(I->valno, ClobberValNo)); } bool Done = false; - LiveIndex Start = I->start, End = I->end; + SlotIndex Start = I->start, End = I->end; // If a clobber range starts before an existing range and ends after // it, the clobber range will need to be split into multiple ranges. // Loop until the entire clobber range is handled. while (!Done) { Done = true; IP = std::upper_bound(IP, end(), Start); - LiveIndex SubRangeStart = Start; - LiveIndex SubRangeEnd = End; + SlotIndex SubRangeStart = Start; + SlotIndex SubRangeEnd = End; // If the start of this range overlaps with an existing liverange, trim it. if (IP != begin() && IP[-1].end > SubRangeStart) { @@ -687,13 +661,14 @@ void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers, } } -void LiveInterval::MergeInClobberRange(LiveIndex Start, - LiveIndex End, +void LiveInterval::MergeInClobberRange(LiveIntervals &li_, + SlotIndex Start, + SlotIndex End, BumpPtrAllocator &VNInfoAllocator) { // Find a value # to use for the clobber ranges. If there is already a value# // for unknown values, use it. VNInfo *ClobberValNo = - getNextValue(LiveIndex(), 0, false, VNInfoAllocator); + getNextValue(li_.getInvalidIndex(), 0, false, VNInfoAllocator); iterator IP = begin(); IP = std::upper_bound(IP, end(), Start); @@ -881,8 +856,6 @@ void LiveInterval::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const { OS << "-("; for (unsigned j = 0; j != ee; ++j) { OS << vni->kills[j]; - if (vni->kills[j].isPHIIndex()) - OS << "*"; if (j != ee-1) OS << " "; } diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 79f46f3..2a93a35 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -28,6 +28,7 @@ #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/ProcessImplicitDefs.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" @@ -80,6 +81,10 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const { } AU.addRequiredID(TwoAddressInstructionPassID); + AU.addPreserved<ProcessImplicitDefs>(); + AU.addRequired<ProcessImplicitDefs>(); + AU.addPreserved<SlotIndexes>(); + AU.addRequiredTransitive<SlotIndexes>(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -89,12 +94,7 @@ void LiveIntervals::releaseMemory() { E = r2iMap_.end(); I != E; ++I) delete I->second; - MBB2IdxMap.clear(); - Idx2MBBMap.clear(); - mi2iMap_.clear(); - i2miMap_.clear(); r2iMap_.clear(); - terminatorGaps.clear(); phiJoinCopies.clear(); // Release VNInfo memroy regions after all VNInfo objects are dtor'd. @@ -106,422 +106,6 @@ void LiveIntervals::releaseMemory() { } } -static bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg, - unsigned OpIdx, const TargetInstrInfo *tii_){ - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; - if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - Reg == SrcReg) - return true; - - if (OpIdx == 2 && MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) - return true; - if (OpIdx == 1 && MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) - return true; - return false; -} - -/// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure -/// there is one implicit_def for each use. Add isUndef marker to -/// implicit_def defs and their uses. -void LiveIntervals::processImplicitDefs() { - SmallSet<unsigned, 8> ImpDefRegs; - SmallVector<MachineInstr*, 8> ImpDefMIs; - MachineBasicBlock *Entry = mf_->begin(); - SmallPtrSet<MachineBasicBlock*,16> Visited; - for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> > - DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited); - DFI != E; ++DFI) { - MachineBasicBlock *MBB = *DFI; - for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); - I != E; ) { - MachineInstr *MI = &*I; - ++I; - if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) { - unsigned Reg = MI->getOperand(0).getReg(); - ImpDefRegs.insert(Reg); - if (TargetRegisterInfo::isPhysicalRegister(Reg)) { - for (const unsigned *SS = tri_->getSubRegisters(Reg); *SS; ++SS) - ImpDefRegs.insert(*SS); - } - ImpDefMIs.push_back(MI); - continue; - } - - if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { - MachineOperand &MO = MI->getOperand(2); - if (ImpDefRegs.count(MO.getReg())) { - // %reg1032<def> = INSERT_SUBREG %reg1032, undef, 2 - // This is an identity copy, eliminate it now. - if (MO.isKill()) { - LiveVariables::VarInfo& vi = lv_->getVarInfo(MO.getReg()); - vi.removeKill(MI); - } - MI->eraseFromParent(); - continue; - } - } - - bool ChangedToImpDef = false; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand& MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isUse() || MO.isUndef()) - continue; - unsigned Reg = MO.getReg(); - if (!Reg) - continue; - if (!ImpDefRegs.count(Reg)) - continue; - // Use is a copy, just turn it into an implicit_def. - if (CanTurnIntoImplicitDef(MI, Reg, i, tii_)) { - bool isKill = MO.isKill(); - MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF)); - for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j) - MI->RemoveOperand(j); - if (isKill) { - ImpDefRegs.erase(Reg); - LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg); - vi.removeKill(MI); - } - ChangedToImpDef = true; - break; - } - - MO.setIsUndef(); - if (MO.isKill() || MI->isRegTiedToDefOperand(i)) { - // Make sure other uses of - for (unsigned j = i+1; j != e; ++j) { - MachineOperand &MOJ = MI->getOperand(j); - if (MOJ.isReg() && MOJ.isUse() && MOJ.getReg() == Reg) - MOJ.setIsUndef(); - } - ImpDefRegs.erase(Reg); - } - } - - if (ChangedToImpDef) { - // Backtrack to process this new implicit_def. - --I; - } else { - for (unsigned i = 0; i != MI->getNumOperands(); ++i) { - MachineOperand& MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isDef()) - continue; - ImpDefRegs.erase(MO.getReg()); - } - } - } - - // Any outstanding liveout implicit_def's? - for (unsigned i = 0, e = ImpDefMIs.size(); i != e; ++i) { - MachineInstr *MI = ImpDefMIs[i]; - unsigned Reg = MI->getOperand(0).getReg(); - if (TargetRegisterInfo::isPhysicalRegister(Reg) || - !ImpDefRegs.count(Reg)) { - // Delete all "local" implicit_def's. That include those which define - // physical registers since they cannot be liveout. - MI->eraseFromParent(); - continue; - } - - // If there are multiple defs of the same register and at least one - // is not an implicit_def, do not insert implicit_def's before the - // uses. - bool Skip = false; - for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg), - DE = mri_->def_end(); DI != DE; ++DI) { - if (DI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) { - Skip = true; - break; - } - } - if (Skip) - continue; - - // The only implicit_def which we want to keep are those that are live - // out of its block. - MI->eraseFromParent(); - - for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg), - UE = mri_->use_end(); UI != UE; ) { - MachineOperand &RMO = UI.getOperand(); - MachineInstr *RMI = &*UI; - ++UI; - MachineBasicBlock *RMBB = RMI->getParent(); - if (RMBB == MBB) - continue; - - // Turn a copy use into an implicit_def. - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; - if (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - Reg == SrcReg) { - RMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF)); - for (int j = RMI->getNumOperands() - 1, ee = 0; j > ee; --j) - RMI->RemoveOperand(j); - continue; - } - - const TargetRegisterClass* RC = mri_->getRegClass(Reg); - unsigned NewVReg = mri_->createVirtualRegister(RC); - RMO.setReg(NewVReg); - RMO.setIsUndef(); - RMO.setIsKill(); - } - } - ImpDefRegs.clear(); - ImpDefMIs.clear(); - } -} - - -void LiveIntervals::computeNumbering() { - Index2MiMap OldI2MI = i2miMap_; - std::vector<IdxMBBPair> OldI2MBB = Idx2MBBMap; - - Idx2MBBMap.clear(); - MBB2IdxMap.clear(); - mi2iMap_.clear(); - i2miMap_.clear(); - terminatorGaps.clear(); - phiJoinCopies.clear(); - - FunctionSize = 0; - - // Number MachineInstrs and MachineBasicBlocks. - // Initialize MBB indexes to a sentinal. - MBB2IdxMap.resize(mf_->getNumBlockIDs(), - std::make_pair(LiveIndex(),LiveIndex())); - - LiveIndex MIIndex; - for (MachineFunction::iterator MBB = mf_->begin(), E = mf_->end(); - MBB != E; ++MBB) { - LiveIndex StartIdx = MIIndex; - - // Insert an empty slot at the beginning of each block. - MIIndex = getNextIndex(MIIndex); - i2miMap_.push_back(0); - - for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); - I != E; ++I) { - - if (I == MBB->getFirstTerminator()) { - // Leave a gap for before terminators, this is where we will point - // PHI kills. - LiveIndex tGap(true, MIIndex); - bool inserted = - terminatorGaps.insert(std::make_pair(&*MBB, tGap)).second; - assert(inserted && - "Multiple 'first' terminators encountered during numbering."); - inserted = inserted; // Avoid compiler warning if assertions turned off. - i2miMap_.push_back(0); - - MIIndex = getNextIndex(MIIndex); - } - - bool inserted = mi2iMap_.insert(std::make_pair(I, MIIndex)).second; - assert(inserted && "multiple MachineInstr -> index mappings"); - inserted = true; - i2miMap_.push_back(I); - MIIndex = getNextIndex(MIIndex); - FunctionSize++; - - // Insert max(1, numdefs) empty slots after every instruction. - unsigned Slots = I->getDesc().getNumDefs(); - if (Slots == 0) - Slots = 1; - while (Slots--) { - MIIndex = getNextIndex(MIIndex); - i2miMap_.push_back(0); - } - - } - - if (MBB->getFirstTerminator() == MBB->end()) { - // Leave a gap for before terminators, this is where we will point - // PHI kills. - LiveIndex tGap(true, MIIndex); - bool inserted = - terminatorGaps.insert(std::make_pair(&*MBB, tGap)).second; - assert(inserted && - "Multiple 'first' terminators encountered during numbering."); - inserted = inserted; // Avoid compiler warning if assertions turned off. - i2miMap_.push_back(0); - - MIIndex = getNextIndex(MIIndex); - } - - // Set the MBB2IdxMap entry for this MBB. - MBB2IdxMap[MBB->getNumber()] = std::make_pair(StartIdx, getPrevSlot(MIIndex)); - Idx2MBBMap.push_back(std::make_pair(StartIdx, MBB)); - } - - std::sort(Idx2MBBMap.begin(), Idx2MBBMap.end(), Idx2MBBCompare()); - - if (!OldI2MI.empty()) - for (iterator OI = begin(), OE = end(); OI != OE; ++OI) { - for (LiveInterval::iterator LI = OI->second->begin(), - LE = OI->second->end(); LI != LE; ++LI) { - - // Remap the start index of the live range to the corresponding new - // number, or our best guess at what it _should_ correspond to if the - // original instruction has been erased. This is either the following - // instruction or its predecessor. - unsigned index = LI->start.getVecIndex(); - LiveIndex::Slot offset = LI->start.getSlot(); - if (LI->start.isLoad()) { - std::vector<IdxMBBPair>::const_iterator I = - std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), LI->start); - // Take the pair containing the index - std::vector<IdxMBBPair>::const_iterator J = - (I == OldI2MBB.end() && OldI2MBB.size()>0) ? (I-1): I; - - LI->start = getMBBStartIdx(J->second); - } else { - LI->start = LiveIndex( - LiveIndex(mi2iMap_[OldI2MI[index]]), - (LiveIndex::Slot)offset); - } - - // Remap the ending index in the same way that we remapped the start, - // except for the final step where we always map to the immediately - // following instruction. - index = (getPrevSlot(LI->end)).getVecIndex(); - offset = LI->end.getSlot(); - if (LI->end.isLoad()) { - // VReg dies at end of block. - std::vector<IdxMBBPair>::const_iterator I = - std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), LI->end); - --I; - - LI->end = getNextSlot(getMBBEndIdx(I->second)); - } else { - unsigned idx = index; - while (index < OldI2MI.size() && !OldI2MI[index]) ++index; - - if (index != OldI2MI.size()) - LI->end = - LiveIndex(mi2iMap_[OldI2MI[index]], - (idx == index ? offset : LiveIndex::LOAD)); - else - LI->end = - LiveIndex(LiveIndex::NUM * i2miMap_.size()); - } - } - - for (LiveInterval::vni_iterator VNI = OI->second->vni_begin(), - VNE = OI->second->vni_end(); VNI != VNE; ++VNI) { - VNInfo* vni = *VNI; - - // Remap the VNInfo def index, which works the same as the - // start indices above. VN's with special sentinel defs - // don't need to be remapped. - if (vni->isDefAccurate() && !vni->isUnused()) { - unsigned index = vni->def.getVecIndex(); - LiveIndex::Slot offset = vni->def.getSlot(); - if (vni->def.isLoad()) { - std::vector<IdxMBBPair>::const_iterator I = - std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), vni->def); - // Take the pair containing the index - std::vector<IdxMBBPair>::const_iterator J = - (I == OldI2MBB.end() && OldI2MBB.size()>0) ? (I-1): I; - - vni->def = getMBBStartIdx(J->second); - } else { - vni->def = LiveIndex(mi2iMap_[OldI2MI[index]], offset); - } - } - - // Remap the VNInfo kill indices, which works the same as - // the end indices above. - for (size_t i = 0; i < vni->kills.size(); ++i) { - unsigned index = getPrevSlot(vni->kills[i]).getVecIndex(); - LiveIndex::Slot offset = vni->kills[i].getSlot(); - - if (vni->kills[i].isLoad()) { - assert("Value killed at a load slot."); - /*std::vector<IdxMBBPair>::const_iterator I = - std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), vni->kills[i]); - --I; - - vni->kills[i] = getMBBEndIdx(I->second);*/ - } else { - if (vni->kills[i].isPHIIndex()) { - std::vector<IdxMBBPair>::const_iterator I = - std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), vni->kills[i]); - --I; - vni->kills[i] = terminatorGaps[I->second]; - } else { - assert(OldI2MI[index] != 0 && - "Kill refers to instruction not present in index maps."); - vni->kills[i] = LiveIndex(mi2iMap_[OldI2MI[index]], offset); - } - - /* - unsigned idx = index; - while (index < OldI2MI.size() && !OldI2MI[index]) ++index; - - if (index != OldI2MI.size()) - vni->kills[i] = mi2iMap_[OldI2MI[index]] + - (idx == index ? offset : 0); - else - vni->kills[i] = InstrSlots::NUM * i2miMap_.size(); - */ - } - } - } - } -} - -void LiveIntervals::scaleNumbering(int factor) { - // Need to - // * scale MBB begin and end points - // * scale all ranges. - // * Update VNI structures. - // * Scale instruction numberings - - // Scale the MBB indices. - Idx2MBBMap.clear(); - for (MachineFunction::iterator MBB = mf_->begin(), MBBE = mf_->end(); - MBB != MBBE; ++MBB) { - std::pair<LiveIndex, LiveIndex> &mbbIndices = MBB2IdxMap[MBB->getNumber()]; - mbbIndices.first = mbbIndices.first.scale(factor); - mbbIndices.second = mbbIndices.second.scale(factor); - Idx2MBBMap.push_back(std::make_pair(mbbIndices.first, MBB)); - } - std::sort(Idx2MBBMap.begin(), Idx2MBBMap.end(), Idx2MBBCompare()); - - // Scale terminator gaps. - for (DenseMap<MachineBasicBlock*, LiveIndex>::iterator - TGI = terminatorGaps.begin(), TGE = terminatorGaps.end(); - TGI != TGE; ++TGI) { - terminatorGaps[TGI->first] = TGI->second.scale(factor); - } - - // Scale the intervals. - for (iterator LI = begin(), LE = end(); LI != LE; ++LI) { - LI->second->scaleNumbering(factor); - } - - // Scale MachineInstrs. - Mi2IndexMap oldmi2iMap = mi2iMap_; - LiveIndex highestSlot; - for (Mi2IndexMap::iterator MI = oldmi2iMap.begin(), ME = oldmi2iMap.end(); - MI != ME; ++MI) { - LiveIndex newSlot = MI->second.scale(factor); - mi2iMap_[MI->first] = newSlot; - highestSlot = std::max(highestSlot, newSlot); - } - - unsigned highestVIndex = highestSlot.getVecIndex(); - i2miMap_.clear(); - i2miMap_.resize(highestVIndex + 1); - for (Mi2IndexMap::iterator MI = mi2iMap_.begin(), ME = mi2iMap_.end(); - MI != ME; ++MI) { - i2miMap_[MI->second.getVecIndex()] = const_cast<MachineInstr *>(MI->first); - } - -} - - /// runOnMachineFunction - Register allocate the whole function /// bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { @@ -532,10 +116,9 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { tii_ = tm_->getInstrInfo(); aa_ = &getAnalysis<AliasAnalysis>(); lv_ = &getAnalysis<LiveVariables>(); + indexes_ = &getAnalysis<SlotIndexes>(); allocatableRegs_ = tri_->getAllocatableSet(fn); - processImplicitDefs(); - computeNumbering(); computeIntervals(); performEarlyCoalescing(); @@ -579,12 +162,13 @@ bool LiveIntervals::conflictsWithPhysRegDef(const LiveInterval &li, VirtRegMap &vrm, unsigned reg) { for (LiveInterval::Ranges::const_iterator I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) { - for (LiveIndex index = getBaseIndex(I->start), - end = getNextIndex(getBaseIndex(getPrevSlot(I->end))); index != end; - index = getNextIndex(index)) { + for (SlotIndex index = I->start.getBaseIndex(), + end = I->end.getPrevSlot().getBaseIndex().getNextIndex(); + index != end; + index = index.getNextIndex()) { // skip deleted instructions while (index != end && !getInstructionFromIndex(index)) - index = getNextIndex(index); + index = index.getNextIndex(); if (index == end) break; MachineInstr *MI = getInstructionFromIndex(index); @@ -620,16 +204,17 @@ bool LiveIntervals::conflictsWithPhysRegRef(LiveInterval &li, SmallPtrSet<MachineInstr*,32> &JoinedCopies) { for (LiveInterval::Ranges::const_iterator I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) { - for (LiveIndex index = getBaseIndex(I->start), - end = getNextIndex(getBaseIndex(getPrevSlot(I->end))); index != end; - index = getNextIndex(index)) { + for (SlotIndex index = I->start.getBaseIndex(), + end = I->end.getPrevSlot().getBaseIndex().getNextIndex(); + index != end; + index = index.getNextIndex()) { // Skip deleted instructions. MachineInstr *MI = 0; while (index != end) { MI = getInstructionFromIndex(index); if (MI) break; - index = getNextIndex(index); + index = index.getNextIndex(); } if (index == end) break; @@ -664,7 +249,7 @@ static void printRegName(unsigned reg, const TargetRegisterInfo* tri_) { void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, MachineBasicBlock::iterator mi, - LiveIndex MIIdx, + SlotIndex MIIdx, MachineOperand& MO, unsigned MOIdx, LiveInterval &interval) { @@ -680,11 +265,11 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg); if (interval.empty()) { // Get the Idx of the defining instructions. - LiveIndex defIndex = getDefIndex(MIIdx); + SlotIndex defIndex = MIIdx.getDefIndex(); // Earlyclobbers move back one, so that they overlap the live range // of inputs. if (MO.isEarlyClobber()) - defIndex = getUseIndex(MIIdx); + defIndex = MIIdx.getUseIndex(); VNInfo *ValNo; MachineInstr *CopyMI = NULL; unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; @@ -704,16 +289,11 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // will be a single kill, in MBB, which comes after the definition. if (vi.Kills.size() == 1 && vi.Kills[0]->getParent() == mbb) { // FIXME: what about dead vars? - LiveIndex killIdx; + SlotIndex killIdx; if (vi.Kills[0] != mi) - killIdx = getNextSlot(getUseIndex(getInstructionIndex(vi.Kills[0]))); - else if (MO.isEarlyClobber()) - // Earlyclobbers that die in this instruction move up one extra, to - // compensate for having the starting point moved back one. This - // gets them to overlap the live range of other outputs. - killIdx = getNextSlot(getNextSlot(defIndex)); + killIdx = getInstructionIndex(vi.Kills[0]).getDefIndex(); else - killIdx = getNextSlot(defIndex); + killIdx = defIndex.getStoreIndex(); // If the kill happens after the definition, we have an intra-block // live range. @@ -732,7 +312,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // of the defining block, potentially live across some blocks, then is // live into some number of blocks, but gets killed. Start by adding a // range that goes from this definition to the end of the defining block. - LiveRange NewLR(defIndex, getNextSlot(getMBBEndIdx(mbb)), ValNo); + LiveRange NewLR(defIndex, getMBBEndIdx(mbb).getNextIndex().getLoadIndex(), + ValNo); DEBUG(errs() << " +" << NewLR); interval.addRange(NewLR); @@ -741,9 +322,10 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // live interval. for (SparseBitVector<>::iterator I = vi.AliveBlocks.begin(), E = vi.AliveBlocks.end(); I != E; ++I) { - LiveRange LR(getMBBStartIdx(*I), - getNextSlot(getMBBEndIdx(*I)), // MBB ends at -1. - ValNo); + LiveRange LR( + getMBBStartIdx(mf_->getBlockNumbered(*I)), + getMBBEndIdx(mf_->getBlockNumbered(*I)).getNextIndex().getLoadIndex(), + ValNo); interval.addRange(LR); DEBUG(errs() << " +" << LR); } @@ -752,8 +334,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // block to the 'use' slot of the killing instruction. for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) { MachineInstr *Kill = vi.Kills[i]; - LiveIndex killIdx = - getNextSlot(getUseIndex(getInstructionIndex(Kill))); + SlotIndex killIdx = + getInstructionIndex(Kill).getDefIndex(); LiveRange LR(getMBBStartIdx(Kill->getParent()), killIdx, ValNo); interval.addRange(LR); ValNo->addKill(killIdx); @@ -772,13 +354,13 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // need to take the LiveRegion that defines this register and split it // into two values. assert(interval.containsOneValue()); - LiveIndex DefIndex = getDefIndex(interval.getValNumInfo(0)->def); - LiveIndex RedefIndex = getDefIndex(MIIdx); + SlotIndex DefIndex = interval.getValNumInfo(0)->def.getDefIndex(); + SlotIndex RedefIndex = MIIdx.getDefIndex(); if (MO.isEarlyClobber()) - RedefIndex = getUseIndex(MIIdx); + RedefIndex = MIIdx.getUseIndex(); const LiveRange *OldLR = - interval.getLiveRangeContaining(getPrevSlot(RedefIndex)); + interval.getLiveRangeContaining(RedefIndex.getUseIndex()); VNInfo *OldValNo = OldLR->valno; // Delete the initial value, which should be short and continuous, @@ -811,10 +393,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // If this redefinition is dead, we need to add a dummy unit live // range covering the def slot. if (MO.isDead()) - interval.addRange( - LiveRange(RedefIndex, MO.isEarlyClobber() ? - getNextSlot(getNextSlot(RedefIndex)) : - getNextSlot(RedefIndex), OldValNo)); + interval.addRange(LiveRange(RedefIndex, RedefIndex.getStoreIndex(), + OldValNo)); DEBUG({ errs() << " RESULT: "; @@ -829,9 +409,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, VNInfo *VNI = interval.getValNumInfo(0); MachineInstr *Killer = vi.Kills[0]; phiJoinCopies.push_back(Killer); - LiveIndex Start = getMBBStartIdx(Killer->getParent()); - LiveIndex End = - getNextSlot(getUseIndex(getInstructionIndex(Killer))); + SlotIndex Start = getMBBStartIdx(Killer->getParent()); + SlotIndex End = getInstructionIndex(Killer).getDefIndex(); DEBUG({ errs() << " Removing [" << Start << "," << End << "] from: "; interval.print(errs(), tri_); @@ -841,7 +420,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, assert(interval.ranges.size() == 1 && "Newly discovered PHI interval has >1 ranges."); MachineBasicBlock *killMBB = getMBBFromIndex(interval.endIndex()); - VNI->addKill(terminatorGaps[killMBB]); + VNI->addKill(indexes_->getTerminatorGap(killMBB)); VNI->setHasPHIKill(true); DEBUG({ errs() << " RESULT: "; @@ -851,8 +430,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // Replace the interval with one of a NEW value number. Note that this // value number isn't actually defined by an instruction, weird huh? :) LiveRange LR(Start, End, - interval.getNextValue(LiveIndex(mbb->getNumber()), - 0, false, VNInfoAllocator)); + interval.getNextValue(SlotIndex(getMBBStartIdx(mbb), true), + 0, false, VNInfoAllocator)); LR.valno->setIsPHIDef(true); DEBUG(errs() << " replace range with " << LR); interval.addRange(LR); @@ -866,9 +445,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // In the case of PHI elimination, each variable definition is only // live until the end of the block. We've already taken care of the // rest of the live range. - LiveIndex defIndex = getDefIndex(MIIdx); + SlotIndex defIndex = MIIdx.getDefIndex(); if (MO.isEarlyClobber()) - defIndex = getUseIndex(MIIdx); + defIndex = MIIdx.getUseIndex(); VNInfo *ValNo; MachineInstr *CopyMI = NULL; @@ -880,10 +459,10 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, CopyMI = mi; ValNo = interval.getNextValue(defIndex, CopyMI, true, VNInfoAllocator); - LiveIndex killIndex = getNextSlot(getMBBEndIdx(mbb)); + SlotIndex killIndex = getMBBEndIdx(mbb).getNextIndex().getLoadIndex(); LiveRange LR(defIndex, killIndex, ValNo); interval.addRange(LR); - ValNo->addKill(terminatorGaps[mbb]); + ValNo->addKill(indexes_->getTerminatorGap(mbb)); ValNo->setHasPHIKill(true); DEBUG(errs() << " +" << LR); } @@ -894,7 +473,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB, MachineBasicBlock::iterator mi, - LiveIndex MIIdx, + SlotIndex MIIdx, MachineOperand& MO, LiveInterval &interval, MachineInstr *CopyMI) { @@ -905,12 +484,12 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB, printRegName(interval.reg, tri_); }); - LiveIndex baseIndex = MIIdx; - LiveIndex start = getDefIndex(baseIndex); + SlotIndex baseIndex = MIIdx; + SlotIndex start = baseIndex.getDefIndex(); // Earlyclobbers move back one. if (MO.isEarlyClobber()) - start = getUseIndex(MIIdx); - LiveIndex end = start; + start = MIIdx.getUseIndex(); + SlotIndex end = start; // If it is not used after definition, it is considered dead at // the instruction defining it. Hence its interval is: @@ -919,53 +498,51 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB, // advance below compensates. if (MO.isDead()) { DEBUG(errs() << " dead"); - if (MO.isEarlyClobber()) - end = getNextSlot(getNextSlot(start)); - else - end = getNextSlot(start); + end = start.getStoreIndex(); goto exit; } // If it is not dead on definition, it must be killed by a // subsequent instruction. Hence its interval is: // [defSlot(def), useSlot(kill)+1) - baseIndex = getNextIndex(baseIndex); + baseIndex = baseIndex.getNextIndex(); while (++mi != MBB->end()) { - while (baseIndex.getVecIndex() < i2miMap_.size() && - getInstructionFromIndex(baseIndex) == 0) - baseIndex = getNextIndex(baseIndex); + + if (getInstructionFromIndex(baseIndex) == 0) + baseIndex = indexes_->getNextNonNullIndex(baseIndex); + if (mi->killsRegister(interval.reg, tri_)) { DEBUG(errs() << " killed"); - end = getNextSlot(getUseIndex(baseIndex)); + end = baseIndex.getDefIndex(); goto exit; } else { int DefIdx = mi->findRegisterDefOperandIdx(interval.reg, false, tri_); if (DefIdx != -1) { if (mi->isRegTiedToUseOperand(DefIdx)) { // Two-address instruction. - end = getDefIndex(baseIndex); - if (mi->getOperand(DefIdx).isEarlyClobber()) - end = getUseIndex(baseIndex); + end = baseIndex.getDefIndex(); + assert(!mi->getOperand(DefIdx).isEarlyClobber() && + "Two address instruction is an early clobber?"); } else { // Another instruction redefines the register before it is ever read. // Then the register is essentially dead at the instruction that defines // it. Hence its interval is: // [defSlot(def), defSlot(def)+1) DEBUG(errs() << " dead"); - end = getNextSlot(start); + end = start.getStoreIndex(); } goto exit; } } - baseIndex = getNextIndex(baseIndex); + baseIndex = baseIndex.getNextIndex(); } // The only case we should have a dead physreg here without a killing or // instruction where we know it's dead is if it is live-in to the function // and never used. Another possible case is the implicit use of the // physical register has been deleted by two-address pass. - end = getNextSlot(start); + end = start.getStoreIndex(); exit: assert(start < end && "did not find end of interval?"); @@ -985,7 +562,7 @@ exit: void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB, MachineBasicBlock::iterator MI, - LiveIndex MIIdx, + SlotIndex MIIdx, MachineOperand& MO, unsigned MOIdx) { if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) @@ -1012,7 +589,7 @@ void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB, } void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB, - LiveIndex MIIdx, + SlotIndex MIIdx, LiveInterval &interval, bool isAlias) { DEBUG({ errs() << "\t\tlivein register: "; @@ -1022,18 +599,18 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB, // Look for kills, if it reaches a def before it's killed, then it shouldn't // be considered a livein. MachineBasicBlock::iterator mi = MBB->begin(); - LiveIndex baseIndex = MIIdx; - LiveIndex start = baseIndex; - while (baseIndex.getVecIndex() < i2miMap_.size() && - getInstructionFromIndex(baseIndex) == 0) - baseIndex = getNextIndex(baseIndex); - LiveIndex end = baseIndex; + SlotIndex baseIndex = MIIdx; + SlotIndex start = baseIndex; + if (getInstructionFromIndex(baseIndex) == 0) + baseIndex = indexes_->getNextNonNullIndex(baseIndex); + + SlotIndex end = baseIndex; bool SeenDefUse = false; while (mi != MBB->end()) { if (mi->killsRegister(interval.reg, tri_)) { DEBUG(errs() << " killed"); - end = getNextSlot(getUseIndex(baseIndex)); + end = baseIndex.getDefIndex(); SeenDefUse = true; break; } else if (mi->modifiesRegister(interval.reg, tri_)) { @@ -1042,17 +619,14 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB, // it. Hence its interval is: // [defSlot(def), defSlot(def)+1) DEBUG(errs() << " dead"); - end = getNextSlot(getDefIndex(start)); + end = start.getStoreIndex(); SeenDefUse = true; break; } - baseIndex = getNextIndex(baseIndex); ++mi; if (mi != MBB->end()) { - while (baseIndex.getVecIndex() < i2miMap_.size() && - getInstructionFromIndex(baseIndex) == 0) - baseIndex = getNextIndex(baseIndex); + baseIndex = indexes_->getNextNonNullIndex(baseIndex); } } @@ -1060,7 +634,7 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB, if (!SeenDefUse) { if (isAlias) { DEBUG(errs() << " dead"); - end = getNextSlot(getDefIndex(MIIdx)); + end = MIIdx.getStoreIndex(); } else { DEBUG(errs() << " live through"); end = baseIndex; @@ -1068,7 +642,7 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB, } VNInfo *vni = - interval.getNextValue(LiveIndex(MBB->getNumber()), + interval.getNextValue(SlotIndex(getMBBStartIdx(MBB), true), 0, false, VNInfoAllocator); vni->setIsPHIDef(true); LiveRange LR(start, end, vni); @@ -1139,11 +713,11 @@ void LiveIntervals::performEarlyCoalescing() { MachineInstr *PHICopy = OtherCopies[i]; DEBUG(errs() << "Moving: " << *PHICopy); - LiveIndex MIIndex = getInstructionIndex(PHICopy); - LiveIndex DefIndex = getDefIndex(MIIndex); + SlotIndex MIIndex = getInstructionIndex(PHICopy); + SlotIndex DefIndex = MIIndex.getDefIndex(); LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex); - LiveIndex StartIndex = SLR->start; - LiveIndex EndIndex = SLR->end; + SlotIndex StartIndex = SLR->start; + SlotIndex EndIndex = SLR->end; // Delete val# defined by the now identity copy and add the range from // beginning of the mbb to the end of the range. @@ -1169,11 +743,11 @@ void LiveIntervals::performEarlyCoalescing() { MachineInstr *PHICopy = IdentCopies[i]; DEBUG(errs() << "Coalescing: " << *PHICopy); - LiveIndex MIIndex = getInstructionIndex(PHICopy); - LiveIndex DefIndex = getDefIndex(MIIndex); + SlotIndex MIIndex = getInstructionIndex(PHICopy); + SlotIndex DefIndex = MIIndex.getDefIndex(); LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex); - LiveIndex StartIndex = SLR->start; - LiveIndex EndIndex = SLR->end; + SlotIndex StartIndex = SLR->start; + SlotIndex EndIndex = SLR->end; // Delete val# defined by the now identity copy and add the range from // beginning of the mbb to the end of the range. @@ -1186,9 +760,9 @@ void LiveIntervals::performEarlyCoalescing() { } // Remove the phi join and update the phi block liveness. - LiveIndex MIIndex = getInstructionIndex(Join); - LiveIndex UseIndex = getUseIndex(MIIndex); - LiveIndex DefIndex = getDefIndex(MIIndex); + SlotIndex MIIndex = getInstructionIndex(Join); + SlotIndex UseIndex = MIIndex.getUseIndex(); + SlotIndex DefIndex = MIIndex.getDefIndex(); LiveRange *SLR = SrcInt.getLiveRangeContaining(UseIndex); LiveRange *DLR = DstInt.getLiveRangeContaining(DefIndex); DLR->valno->setCopy(0); @@ -1218,7 +792,7 @@ void LiveIntervals::computeIntervals() { MBBI != E; ++MBBI) { MachineBasicBlock *MBB = MBBI; // Track the index of the current machine instr. - LiveIndex MIIndex = getMBBStartIdx(MBB); + SlotIndex MIIndex = getMBBStartIdx(MBB); DEBUG(errs() << ((Value*)MBB->getBasicBlock())->getName() << ":\n"); MachineBasicBlock::iterator MI = MBB->begin(), miEnd = MBB->end(); @@ -1235,9 +809,8 @@ void LiveIntervals::computeIntervals() { } // Skip over empty initial indices. - while (MIIndex.getVecIndex() < i2miMap_.size() && - getInstructionFromIndex(MIIndex) == 0) - MIIndex = getNextIndex(MIIndex); + if (getInstructionFromIndex(MIIndex) == 0) + MIIndex = indexes_->getNextNonNullIndex(MIIndex); for (; MI != miEnd; ++MI) { DEBUG(errs() << MIIndex << "\t" << *MI); @@ -1254,19 +827,9 @@ void LiveIntervals::computeIntervals() { else if (MO.isUndef()) UndefUses.push_back(MO.getReg()); } - - // Skip over the empty slots after each instruction. - unsigned Slots = MI->getDesc().getNumDefs(); - if (Slots == 0) - Slots = 1; - - while (Slots--) - MIIndex = getNextIndex(MIIndex); - // Skip over empty indices. - while (MIIndex.getVecIndex() < i2miMap_.size() && - getInstructionFromIndex(MIIndex) == 0) - MIIndex = getNextIndex(MIIndex); + // Move to the next instr slot. + MIIndex = indexes_->getNextNonNullIndex(MIIndex); } } @@ -1279,45 +842,6 @@ void LiveIntervals::computeIntervals() { } } -bool LiveIntervals::findLiveInMBBs( - LiveIndex Start, LiveIndex End, - SmallVectorImpl<MachineBasicBlock*> &MBBs) const { - std::vector<IdxMBBPair>::const_iterator I = - std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), Start); - - bool ResVal = false; - while (I != Idx2MBBMap.end()) { - if (I->first >= End) - break; - MBBs.push_back(I->second); - ResVal = true; - ++I; - } - return ResVal; -} - -bool LiveIntervals::findReachableMBBs( - LiveIndex Start, LiveIndex End, - SmallVectorImpl<MachineBasicBlock*> &MBBs) const { - std::vector<IdxMBBPair>::const_iterator I = - std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), Start); - - bool ResVal = false; - while (I != Idx2MBBMap.end()) { - if (I->first > End) - break; - MachineBasicBlock *MBB = I->second; - if (getMBBEndIdx(MBB) > End) - break; - for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), - SE = MBB->succ_end(); SI != SE; ++SI) - MBBs.push_back(*SI); - ResVal = true; - ++I; - } - return ResVal; -} - LiveInterval* LiveIntervals::createInterval(unsigned reg) { float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ? HUGE_VALF : 0.0F; return new LiveInterval(reg, Weight); @@ -1389,8 +913,8 @@ unsigned LiveIntervals::getReMatImplicitUse(const LiveInterval &li, /// isValNoAvailableAt - Return true if the val# of the specified interval /// which reaches the given instruction also reaches the specified use index. bool LiveIntervals::isValNoAvailableAt(const LiveInterval &li, MachineInstr *MI, - LiveIndex UseIdx) const { - LiveIndex Index = getInstructionIndex(MI); + SlotIndex UseIdx) const { + SlotIndex Index = getInstructionIndex(MI); VNInfo *ValNo = li.FindLiveRangeContaining(Index)->valno; LiveInterval::const_iterator UI = li.FindLiveRangeContaining(UseIdx); return UI != li.end() && UI->valno == ValNo; @@ -1417,7 +941,7 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li, for (MachineRegisterInfo::use_iterator ri = mri_->use_begin(li.reg), re = mri_->use_end(); ri != re; ++ri) { MachineInstr *UseMI = &*ri; - LiveIndex UseIdx = getInstructionIndex(UseMI); + SlotIndex UseIdx = getInstructionIndex(UseMI); if (li.FindLiveRangeContaining(UseIdx)->valno != ValNo) continue; if (!isValNoAvailableAt(ImpLi, MI, UseIdx)) @@ -1502,7 +1026,7 @@ static bool FilterFoldedOps(MachineInstr *MI, /// returns true. bool LiveIntervals::tryFoldMemoryOperand(MachineInstr* &MI, VirtRegMap &vrm, MachineInstr *DefMI, - LiveIndex InstrIdx, + SlotIndex InstrIdx, SmallVector<unsigned, 2> &Ops, bool isSS, int Slot, unsigned Reg) { // If it is an implicit def instruction, just delete it. @@ -1540,9 +1064,7 @@ bool LiveIntervals::tryFoldMemoryOperand(MachineInstr* &MI, vrm.transferSpillPts(MI, fmi); vrm.transferRestorePts(MI, fmi); vrm.transferEmergencySpills(MI, fmi); - mi2iMap_.erase(MI); - i2miMap_[InstrIdx.getVecIndex()] = fmi; - mi2iMap_[fmi] = InstrIdx; + ReplaceMachineInstrInMaps(MI, fmi); MI = MBB.insert(MBB.erase(MI), fmi); ++numFolds; return true; @@ -1570,19 +1092,21 @@ bool LiveIntervals::canFoldMemoryOperand(MachineInstr *MI, } bool LiveIntervals::intervalIsInOneMBB(const LiveInterval &li) const { - SmallPtrSet<MachineBasicBlock*, 4> MBBs; - for (LiveInterval::Ranges::const_iterator - I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) { - std::vector<IdxMBBPair>::const_iterator II = - std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), I->start); - if (II == Idx2MBBMap.end()) - continue; - if (I->end > II->first) // crossing a MBB. - return false; - MBBs.insert(II->second); - if (MBBs.size() > 1) + LiveInterval::Ranges::const_iterator itr = li.ranges.begin(); + + MachineBasicBlock *mbb = indexes_->getMBBCoveringRange(itr->start, itr->end); + + if (mbb == 0) + return false; + + for (++itr; itr != li.ranges.end(); ++itr) { + MachineBasicBlock *mbb2 = + indexes_->getMBBCoveringRange(itr->start, itr->end); + + if (mbb2 != mbb) return false; } + return true; } @@ -1614,7 +1138,7 @@ void LiveIntervals::rewriteImplicitOps(const LiveInterval &li, /// for addIntervalsForSpills to rewrite uses / defs for the given live range. bool LiveIntervals:: rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI, - bool TrySplit, LiveIndex index, LiveIndex end, + bool TrySplit, SlotIndex index, SlotIndex end, MachineInstr *MI, MachineInstr *ReMatOrigDefMI, MachineInstr *ReMatDefMI, unsigned Slot, int LdSlot, @@ -1791,14 +1315,13 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI, if (HasUse) { if (CreatedNewVReg) { - LiveRange LR(getLoadIndex(index), getNextSlot(getUseIndex(index)), - nI.getNextValue(LiveIndex(), 0, false, - VNInfoAllocator)); + LiveRange LR(index.getLoadIndex(), index.getDefIndex(), + nI.getNextValue(SlotIndex(), 0, false, VNInfoAllocator)); DEBUG(errs() << " +" << LR); nI.addRange(LR); } else { // Extend the split live interval to this def / use. - LiveIndex End = getNextSlot(getUseIndex(index)); + SlotIndex End = index.getDefIndex(); LiveRange LR(nI.ranges[nI.ranges.size()-1].end, End, nI.getValNumInfo(nI.getNumValNums()-1)); DEBUG(errs() << " +" << LR); @@ -1806,9 +1329,8 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI, } } if (HasDef) { - LiveRange LR(getDefIndex(index), getStoreIndex(index), - nI.getNextValue(LiveIndex(), 0, false, - VNInfoAllocator)); + LiveRange LR(index.getDefIndex(), index.getStoreIndex(), + nI.getNextValue(SlotIndex(), 0, false, VNInfoAllocator)); DEBUG(errs() << " +" << LR); nI.addRange(LR); } @@ -1824,13 +1346,13 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI, bool LiveIntervals::anyKillInMBBAfterIdx(const LiveInterval &li, const VNInfo *VNI, MachineBasicBlock *MBB, - LiveIndex Idx) const { - LiveIndex End = getMBBEndIdx(MBB); + SlotIndex Idx) const { + SlotIndex End = getMBBEndIdx(MBB); for (unsigned j = 0, ee = VNI->kills.size(); j != ee; ++j) { - if (VNI->kills[j].isPHIIndex()) + if (VNI->kills[j].isPHI()) continue; - LiveIndex KillIdx = VNI->kills[j]; + SlotIndex KillIdx = VNI->kills[j]; if (KillIdx > Idx && KillIdx < End) return true; } @@ -1841,11 +1363,11 @@ bool LiveIntervals::anyKillInMBBAfterIdx(const LiveInterval &li, /// during spilling. namespace { struct RewriteInfo { - LiveIndex Index; + SlotIndex Index; MachineInstr *MI; bool HasUse; bool HasDef; - RewriteInfo(LiveIndex i, MachineInstr *mi, bool u, bool d) + RewriteInfo(SlotIndex i, MachineInstr *mi, bool u, bool d) : Index(i), MI(mi), HasUse(u), HasDef(d) {} }; @@ -1874,8 +1396,8 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit, std::vector<LiveInterval*> &NewLIs) { bool AllCanFold = true; unsigned NewVReg = 0; - LiveIndex start = getBaseIndex(I->start); - LiveIndex end = getNextIndex(getBaseIndex(getPrevSlot(I->end))); + SlotIndex start = I->start.getBaseIndex(); + SlotIndex end = I->end.getPrevSlot().getBaseIndex().getNextIndex(); // First collect all the def / use in this live range that will be rewritten. // Make sure they are sorted according to instruction index. @@ -1886,7 +1408,7 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit, MachineOperand &O = ri.getOperand(); ++ri; assert(!O.isImplicit() && "Spilling register that's used as implicit use?"); - LiveIndex index = getInstructionIndex(MI); + SlotIndex index = getInstructionIndex(MI); if (index < start || index >= end) continue; @@ -1910,7 +1432,7 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit, for (unsigned i = 0, e = RewriteMIs.size(); i != e; ) { RewriteInfo &rwi = RewriteMIs[i]; ++i; - LiveIndex index = rwi.Index; + SlotIndex index = rwi.Index; bool MIHasUse = rwi.HasUse; bool MIHasDef = rwi.HasDef; MachineInstr *MI = rwi.MI; @@ -1993,12 +1515,12 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit, if (MI != ReMatOrigDefMI || !CanDelete) { bool HasKill = false; if (!HasUse) - HasKill = anyKillInMBBAfterIdx(li, I->valno, MBB, getDefIndex(index)); + HasKill = anyKillInMBBAfterIdx(li, I->valno, MBB, index.getDefIndex()); else { // If this is a two-address code, then this index starts a new VNInfo. - const VNInfo *VNI = li.findDefinedVNInfoForRegInt(getDefIndex(index)); + const VNInfo *VNI = li.findDefinedVNInfoForRegInt(index.getDefIndex()); if (VNI) - HasKill = anyKillInMBBAfterIdx(li, VNI, MBB, getDefIndex(index)); + HasKill = anyKillInMBBAfterIdx(li, VNI, MBB, index.getDefIndex()); } DenseMap<unsigned, std::vector<SRInfo> >::iterator SII = SpillIdxes.find(MBBId); @@ -2071,7 +1593,7 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit, } } -bool LiveIntervals::alsoFoldARestore(int Id, LiveIndex index, +bool LiveIntervals::alsoFoldARestore(int Id, SlotIndex index, unsigned vr, BitVector &RestoreMBBs, DenseMap<unsigned,std::vector<SRInfo> > &RestoreIdxes) { if (!RestoreMBBs[Id]) @@ -2085,7 +1607,7 @@ bool LiveIntervals::alsoFoldARestore(int Id, LiveIndex index, return false; } -void LiveIntervals::eraseRestoreInfo(int Id, LiveIndex index, +void LiveIntervals::eraseRestoreInfo(int Id, SlotIndex index, unsigned vr, BitVector &RestoreMBBs, DenseMap<unsigned,std::vector<SRInfo> > &RestoreIdxes) { if (!RestoreMBBs[Id]) @@ -2093,7 +1615,7 @@ void LiveIntervals::eraseRestoreInfo(int Id, LiveIndex index, std::vector<SRInfo> &Restores = RestoreIdxes[Id]; for (unsigned i = 0, e = Restores.size(); i != e; ++i) if (Restores[i].index == index && Restores[i].vreg) - Restores[i].index = LiveIndex(); + Restores[i].index = SlotIndex(); } /// handleSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being @@ -2192,18 +1714,18 @@ addIntervalsForSpillsFast(const LiveInterval &li, } // Fill in the new live interval. - LiveIndex index = getInstructionIndex(MI); + SlotIndex index = getInstructionIndex(MI); if (HasUse) { - LiveRange LR(getLoadIndex(index), getUseIndex(index), - nI.getNextValue(LiveIndex(), 0, false, + LiveRange LR(index.getLoadIndex(), index.getUseIndex(), + nI.getNextValue(SlotIndex(), 0, false, getVNInfoAllocator())); DEBUG(errs() << " +" << LR); nI.addRange(LR); vrm.addRestorePoint(NewVReg, MI); } if (HasDef) { - LiveRange LR(getDefIndex(index), getStoreIndex(index), - nI.getNextValue(LiveIndex(), 0, false, + LiveRange LR(index.getDefIndex(), index.getStoreIndex(), + nI.getNextValue(SlotIndex(), 0, false, getVNInfoAllocator())); DEBUG(errs() << " +" << LR); nI.addRange(LR); @@ -2267,8 +1789,8 @@ addIntervalsForSpills(const LiveInterval &li, if (vrm.getPreSplitReg(li.reg)) { vrm.setIsSplitFromReg(li.reg, 0); // Unset the split kill marker on the last use. - LiveIndex KillIdx = vrm.getKillPoint(li.reg); - if (KillIdx != LiveIndex()) { + SlotIndex KillIdx = vrm.getKillPoint(li.reg); + if (KillIdx != SlotIndex()) { MachineInstr *KillMI = getInstructionFromIndex(KillIdx); assert(KillMI && "Last use disappeared?"); int KillOp = KillMI->findRegisterUseOperandIdx(li.reg, true); @@ -2394,7 +1916,7 @@ addIntervalsForSpills(const LiveInterval &li, while (Id != -1) { std::vector<SRInfo> &spills = SpillIdxes[Id]; for (unsigned i = 0, e = spills.size(); i != e; ++i) { - LiveIndex index = spills[i].index; + SlotIndex index = spills[i].index; unsigned VReg = spills[i].vreg; LiveInterval &nI = getOrCreateInterval(VReg); bool isReMat = vrm.isReMaterialized(VReg); @@ -2432,16 +1954,16 @@ addIntervalsForSpills(const LiveInterval &li, if (FoundUse) { // Also folded uses, do not issue a load. eraseRestoreInfo(Id, index, VReg, RestoreMBBs, RestoreIdxes); - nI.removeRange(getLoadIndex(index), getNextSlot(getUseIndex(index))); + nI.removeRange(index.getLoadIndex(), index.getDefIndex()); } - nI.removeRange(getDefIndex(index), getStoreIndex(index)); + nI.removeRange(index.getDefIndex(), index.getStoreIndex()); } } // Otherwise tell the spiller to issue a spill. if (!Folded) { LiveRange *LR = &nI.ranges[nI.ranges.size()-1]; - bool isKill = LR->end == getStoreIndex(index); + bool isKill = LR->end == index.getStoreIndex(); if (!MI->registerDefIsDead(nI.reg)) // No need to spill a dead def. vrm.addSpillPoint(VReg, isKill, MI); @@ -2457,8 +1979,8 @@ addIntervalsForSpills(const LiveInterval &li, while (Id != -1) { std::vector<SRInfo> &restores = RestoreIdxes[Id]; for (unsigned i = 0, e = restores.size(); i != e; ++i) { - LiveIndex index = restores[i].index; - if (index == LiveIndex()) + SlotIndex index = restores[i].index; + if (index == SlotIndex()) continue; unsigned VReg = restores[i].vreg; LiveInterval &nI = getOrCreateInterval(VReg); @@ -2513,7 +2035,7 @@ addIntervalsForSpills(const LiveInterval &li, // If folding is not possible / failed, then tell the spiller to issue a // load / rematerialization for us. if (Folded) - nI.removeRange(getLoadIndex(index), getNextSlot(getUseIndex(index))); + nI.removeRange(index.getLoadIndex(), index.getDefIndex()); else vrm.addRestorePoint(VReg, MI); } @@ -2526,10 +2048,10 @@ addIntervalsForSpills(const LiveInterval &li, for (unsigned i = 0, e = NewLIs.size(); i != e; ++i) { LiveInterval *LI = NewLIs[i]; if (!LI->empty()) { - LI->weight /= InstrSlots::NUM * getApproximateInstructionCount(*LI); + LI->weight /= SlotIndex::NUM * getApproximateInstructionCount(*LI); if (!AddedKill.count(LI)) { LiveRange *LR = &LI->ranges[LI->ranges.size()-1]; - LiveIndex LastUseIdx = getBaseIndex(LR->end); + SlotIndex LastUseIdx = LR->end.getBaseIndex(); MachineInstr *LastUse = getInstructionFromIndex(LastUseIdx); int UseIdx = LastUse->findRegisterUseOperandIdx(LI->reg, false); assert(UseIdx != -1); @@ -2580,7 +2102,7 @@ unsigned LiveIntervals::getNumConflictsWithPhysReg(const LiveInterval &li, E = mri_->reg_end(); I != E; ++I) { MachineOperand &O = I.getOperand(); MachineInstr *MI = O.getParent(); - LiveIndex Index = getInstructionIndex(MI); + SlotIndex Index = getInstructionIndex(MI); if (pli.liveAt(Index)) ++NumConflicts; } @@ -2623,15 +2145,15 @@ bool LiveIntervals::spillPhysRegAroundRegDefsUses(const LiveInterval &li, if (SeenMIs.count(MI)) continue; SeenMIs.insert(MI); - LiveIndex Index = getInstructionIndex(MI); + SlotIndex Index = getInstructionIndex(MI); for (unsigned i = 0, e = PRegs.size(); i != e; ++i) { unsigned PReg = PRegs[i]; LiveInterval &pli = getInterval(PReg); if (!pli.liveAt(Index)) continue; vrm.addEmergencySpill(PReg, MI); - LiveIndex StartIdx = getLoadIndex(Index); - LiveIndex EndIdx = getNextSlot(getStoreIndex(Index)); + SlotIndex StartIdx = Index.getLoadIndex(); + SlotIndex EndIdx = Index.getNextIndex().getBaseIndex(); if (pli.isInOneLiveRange(StartIdx, EndIdx)) { pli.removeRange(StartIdx, EndIdx); Cut = true; @@ -2651,7 +2173,8 @@ bool LiveIntervals::spillPhysRegAroundRegDefsUses(const LiveInterval &li, continue; LiveInterval &spli = getInterval(*AS); if (spli.liveAt(Index)) - spli.removeRange(getLoadIndex(Index), getNextSlot(getStoreIndex(Index))); + spli.removeRange(Index.getLoadIndex(), + Index.getNextIndex().getBaseIndex()); } } } @@ -2662,13 +2185,13 @@ LiveRange LiveIntervals::addLiveRangeToEndOfBlock(unsigned reg, MachineInstr* startInst) { LiveInterval& Interval = getOrCreateInterval(reg); VNInfo* VN = Interval.getNextValue( - LiveIndex(getInstructionIndex(startInst), LiveIndex::DEF), + SlotIndex(getInstructionIndex(startInst).getDefIndex()), startInst, true, getVNInfoAllocator()); VN->setHasPHIKill(true); - VN->kills.push_back(terminatorGaps[startInst->getParent()]); + VN->kills.push_back(indexes_->getTerminatorGap(startInst->getParent())); LiveRange LR( - LiveIndex(getInstructionIndex(startInst), LiveIndex::DEF), - getNextSlot(getMBBEndIdx(startInst->getParent())), VN); + SlotIndex(getInstructionIndex(startInst).getDefIndex()), + getMBBEndIdx(startInst->getParent()).getNextIndex().getBaseIndex(), VN); Interval.addRange(LR); return LR; diff --git a/lib/CodeGen/LiveStackAnalysis.cpp b/lib/CodeGen/LiveStackAnalysis.cpp index a7bea1f..d2f3775 100644 --- a/lib/CodeGen/LiveStackAnalysis.cpp +++ b/lib/CodeGen/LiveStackAnalysis.cpp @@ -27,15 +27,10 @@ using namespace llvm; char LiveStacks::ID = 0; static RegisterPass<LiveStacks> X("livestacks", "Live Stack Slot Analysis"); -void LiveStacks::scaleNumbering(int factor) { - // Scale the intervals. - for (iterator LI = begin(), LE = end(); LI != LE; ++LI) { - LI->second.scaleNumbering(factor); - } -} - void LiveStacks::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); + AU.addPreserved<SlotIndexes>(); + AU.addRequiredTransitive<SlotIndexes>(); MachineFunctionPass::getAnalysisUsage(AU); } diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp index 8486bb0..30636a8 100644 --- a/lib/CodeGen/LowerSubregs.cpp +++ b/lib/CodeGen/LowerSubregs.cpp @@ -25,13 +25,16 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { - struct VISIBILITY_HIDDEN LowerSubregsInstructionPass - : public MachineFunctionPass { + struct LowerSubregsInstructionPass : public MachineFunctionPass { + private: + const TargetRegisterInfo *TRI; + const TargetInstrInfo *TII; + + public: static char ID; // Pass identification, replacement for typeid LowerSubregsInstructionPass() : MachineFunctionPass(&ID) {} @@ -48,15 +51,16 @@ namespace { /// runOnMachineFunction - pass entry point bool runOnMachineFunction(MachineFunction&); - + + private: bool LowerExtract(MachineInstr *MI); bool LowerInsert(MachineInstr *MI); bool LowerSubregToReg(MachineInstr *MI); void TransferDeadFlag(MachineInstr *MI, unsigned DstReg, - const TargetRegisterInfo &TRI); + const TargetRegisterInfo *TRI); void TransferKillFlag(MachineInstr *MI, unsigned SrcReg, - const TargetRegisterInfo &TRI, + const TargetRegisterInfo *TRI, bool AddIfNotFound = false); }; @@ -73,10 +77,10 @@ FunctionPass *llvm::createLowerSubregsPass() { void LowerSubregsInstructionPass::TransferDeadFlag(MachineInstr *MI, unsigned DstReg, - const TargetRegisterInfo &TRI) { + const TargetRegisterInfo *TRI) { for (MachineBasicBlock::iterator MII = prior(MachineBasicBlock::iterator(MI)); ; --MII) { - if (MII->addRegisterDead(DstReg, &TRI)) + if (MII->addRegisterDead(DstReg, TRI)) break; assert(MII != MI->getParent()->begin() && "copyRegToReg output doesn't reference destination register!"); @@ -89,11 +93,11 @@ LowerSubregsInstructionPass::TransferDeadFlag(MachineInstr *MI, void LowerSubregsInstructionPass::TransferKillFlag(MachineInstr *MI, unsigned SrcReg, - const TargetRegisterInfo &TRI, + const TargetRegisterInfo *TRI, bool AddIfNotFound) { for (MachineBasicBlock::iterator MII = prior(MachineBasicBlock::iterator(MI)); ; --MII) { - if (MII->addRegisterKilled(SrcReg, &TRI, AddIfNotFound)) + if (MII->addRegisterKilled(SrcReg, TRI, AddIfNotFound)) break; assert(MII != MI->getParent()->begin() && "copyRegToReg output doesn't reference source register!"); @@ -102,9 +106,6 @@ LowerSubregsInstructionPass::TransferKillFlag(MachineInstr *MI, bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) { MachineBasicBlock *MBB = MI->getParent(); - MachineFunction &MF = *MBB->getParent(); - const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); - const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); assert(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() && MI->getOperand(1).isReg() && MI->getOperand(1).isUse() && @@ -113,7 +114,7 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) { unsigned DstReg = MI->getOperand(0).getReg(); unsigned SuperReg = MI->getOperand(1).getReg(); unsigned SubIdx = MI->getOperand(2).getImm(); - unsigned SrcReg = TRI.getSubReg(SuperReg, SubIdx); + unsigned SrcReg = TRI->getSubReg(SuperReg, SubIdx); assert(TargetRegisterInfo::isPhysicalRegister(SuperReg) && "Extract supperg source must be a physical register"); @@ -128,7 +129,7 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) { if (MI->getOperand(1).isKill()) { // We must make sure the super-register gets killed. Replace the // instruction with KILL. - MI->setDesc(TII.get(TargetInstrInfo::KILL)); + MI->setDesc(TII->get(TargetInstrInfo::KILL)); MI->RemoveOperand(2); // SubIdx DEBUG(errs() << "subreg: replace by: " << *MI); return true; @@ -137,9 +138,9 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) { DEBUG(errs() << "subreg: eliminated!"); } else { // Insert copy - const TargetRegisterClass *TRCS = TRI.getPhysicalRegisterRegClass(DstReg); - const TargetRegisterClass *TRCD = TRI.getPhysicalRegisterRegClass(SrcReg); - bool Emitted = TII.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRCD, TRCS); + const TargetRegisterClass *TRCS = TRI->getPhysicalRegisterRegClass(DstReg); + const TargetRegisterClass *TRCD = TRI->getPhysicalRegisterRegClass(SrcReg); + bool Emitted = TII->copyRegToReg(*MBB, MI, DstReg, SrcReg, TRCD, TRCS); (void)Emitted; assert(Emitted && "Subreg and Dst must be of compatible register class"); // Transfer the kill/dead flags, if needed. @@ -160,9 +161,6 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) { bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) { MachineBasicBlock *MBB = MI->getParent(); - MachineFunction &MF = *MBB->getParent(); - const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); - const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) && MI->getOperand(1).isImm() && (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) && @@ -174,7 +172,7 @@ bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) { unsigned SubIdx = MI->getOperand(3).getImm(); assert(SubIdx != 0 && "Invalid index for insert_subreg"); - unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx); + unsigned DstSubReg = TRI->getSubReg(DstReg, SubIdx); assert(TargetRegisterInfo::isPhysicalRegister(DstReg) && "Insert destination must be in a physical register"); @@ -193,9 +191,11 @@ bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) { DEBUG(errs() << "subreg: eliminated!"); } else { // Insert sub-register copy - const TargetRegisterClass *TRC0= TRI.getPhysicalRegisterRegClass(DstSubReg); - const TargetRegisterClass *TRC1= TRI.getPhysicalRegisterRegClass(InsReg); - TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1); + const TargetRegisterClass *TRC0= TRI->getPhysicalRegisterRegClass(DstSubReg); + const TargetRegisterClass *TRC1= TRI->getPhysicalRegisterRegClass(InsReg); + bool Emitted = TII->copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1); + (void)Emitted; + assert(Emitted && "Subreg and Dst must be of compatible register class"); // Transfer the kill/dead flags, if needed. if (MI->getOperand(0).isDead()) TransferDeadFlag(MI, DstSubReg, TRI); @@ -209,14 +209,11 @@ bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) { DEBUG(errs() << '\n'); MBB->erase(MI); - return true; + return true; } bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) { MachineBasicBlock *MBB = MI->getParent(); - MachineFunction &MF = *MBB->getParent(); - const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); - const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) && (MI->getOperand(1).isReg() && MI->getOperand(1).isUse()) && (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) && @@ -231,7 +228,7 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) { assert(DstReg == SrcReg && "insert_subreg not a two-address instruction?"); assert(SubIdx != 0 && "Invalid index for insert_subreg"); - unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx); + unsigned DstSubReg = TRI->getSubReg(DstReg, SubIdx); assert(DstSubReg && "invalid subregister index for register"); assert(TargetRegisterInfo::isPhysicalRegister(SrcReg) && "Insert superreg source must be in a physical register"); @@ -245,7 +242,7 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) { // <undef>, we need to make sure it is alive by inserting a KILL if (MI->getOperand(1).isUndef() && !MI->getOperand(0).isDead()) { MachineInstrBuilder MIB = BuildMI(*MBB, MI, MI->getDebugLoc(), - TII.get(TargetInstrInfo::KILL), DstReg); + TII->get(TargetInstrInfo::KILL), DstReg); if (MI->getOperand(2).isUndef()) MIB.addReg(InsReg, RegState::Undef); else @@ -257,15 +254,18 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) { } } else { // Insert sub-register copy - const TargetRegisterClass *TRC0= TRI.getPhysicalRegisterRegClass(DstSubReg); - const TargetRegisterClass *TRC1= TRI.getPhysicalRegisterRegClass(InsReg); + const TargetRegisterClass *TRC0= TRI->getPhysicalRegisterRegClass(DstSubReg); + const TargetRegisterClass *TRC1= TRI->getPhysicalRegisterRegClass(InsReg); if (MI->getOperand(2).isUndef()) // If the source register being inserted is undef, then this becomes a // KILL. BuildMI(*MBB, MI, MI->getDebugLoc(), - TII.get(TargetInstrInfo::KILL), DstSubReg); - else - TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1); + TII->get(TargetInstrInfo::KILL), DstSubReg); + else { + bool Emitted = TII->copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1); + (void)Emitted; + assert(Emitted && "Subreg and Dst must be of compatible register class"); + } MachineBasicBlock::iterator CopyMI = MI; --CopyMI; @@ -303,6 +303,8 @@ bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) { << "********** LOWERING SUBREG INSTRS **********\n" << "********** Function: " << MF.getFunction()->getName() << '\n'); + TRI = MF.getTarget().getRegisterInfo(); + TII = MF.getTarget().getInstrInfo(); bool MadeChange = false; @@ -310,8 +312,8 @@ bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) { mbbi != mbbe; ++mbbi) { for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end(); mi != me;) { - MachineInstr *MI = mi++; - + MachineBasicBlock::iterator nmi = next(mi); + MachineInstr *MI = mi; if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) { MadeChange |= LowerExtract(MI); } else if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { @@ -319,6 +321,7 @@ bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) { } else if (MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) { MadeChange |= LowerSubregToReg(MI); } + mi = nmi; } } diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index b3eb2da..7fbdb12 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -20,11 +20,13 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Assembly/Writer.h" #include <algorithm> using namespace llvm; MachineBasicBlock::MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb) - : BB(bb), Number(-1), xParent(&mf), Alignment(0), IsLandingPad(false) { + : BB(bb), Number(-1), xParent(&mf), Alignment(0), IsLandingPad(false), + AddressTaken(false) { Insts.Parent = this; } @@ -160,11 +162,11 @@ void MachineBasicBlock::dump() const { static inline void OutputReg(raw_ostream &os, unsigned RegNo, const TargetRegisterInfo *TRI = 0) { - if (!RegNo || TargetRegisterInfo::isPhysicalRegister(RegNo)) { + if (RegNo != 0 && TargetRegisterInfo::isPhysicalRegister(RegNo)) { if (TRI) os << " %" << TRI->get(RegNo).Name; else - os << " %mreg(" << RegNo << ")"; + os << " %physreg" << RegNo; } else os << " %reg" << RegNo; } @@ -177,18 +179,23 @@ void MachineBasicBlock::print(raw_ostream &OS) const { return; } - const BasicBlock *LBB = getBasicBlock(); + if (Alignment) { OS << "Alignment " << Alignment << "\n"; } + + OS << "BB#" << getNumber() << ": "; + + const char *Comma = ""; + if (const BasicBlock *LBB = getBasicBlock()) { + OS << Comma << "derived from LLVM BB "; + WriteAsOperand(OS, LBB, /*PrintType=*/false); + Comma = ", "; + } + if (isLandingPad()) { OS << Comma << "EH LANDING PAD"; Comma = ", "; } + if (hasAddressTaken()) { OS << Comma << "ADDRESS TAKEN"; Comma = ", "; } OS << '\n'; - if (LBB) OS << LBB->getName() << ": "; - OS << (const void*)this - << ", LLVM BB @" << (const void*) LBB << ", ID#" << getNumber(); - if (Alignment) OS << ", Alignment " << Alignment; - if (isLandingPad()) OS << ", EH LANDING PAD"; - OS << ":\n"; const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); if (!livein_empty()) { - OS << "Live Ins:"; + OS << " Live Ins:"; for (const_livein_iterator I = livein_begin(),E = livein_end(); I != E; ++I) OutputReg(OS, *I, TRI); OS << '\n'; @@ -197,7 +204,7 @@ void MachineBasicBlock::print(raw_ostream &OS) const { if (!pred_empty()) { OS << " Predecessors according to CFG:"; for (const_pred_iterator PI = pred_begin(), E = pred_end(); PI != E; ++PI) - OS << ' ' << *PI << " (#" << (*PI)->getNumber() << ')'; + OS << " BB#" << (*PI)->getNumber(); OS << '\n'; } @@ -210,7 +217,7 @@ void MachineBasicBlock::print(raw_ostream &OS) const { if (!succ_empty()) { OS << " Successors according to CFG:"; for (const_succ_iterator SI = succ_begin(), E = succ_end(); SI != E; ++SI) - OS << ' ' << *SI << " (#" << (*SI)->getNumber() << ')'; + OS << " BB#" << (*SI)->getNumber(); OS << '\n'; } } diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index b0ec809..5a1d9e6 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -30,13 +30,12 @@ #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetFrameInfo.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/GraphWriter.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { - struct VISIBILITY_HIDDEN Printer : public MachineFunctionPass { + struct Printer : public MachineFunctionPass { static char ID; raw_ostream &OS; @@ -53,7 +52,7 @@ namespace { } bool runOnMachineFunction(MachineFunction &MF) { - OS << Banner; + OS << "# " << Banner << ":\n"; MF.print(OS); return false; } @@ -304,7 +303,7 @@ void MachineFunction::dump() const { } void MachineFunction::print(raw_ostream &OS) const { - OS << "# Machine code for " << Fn->getName() << "():\n"; + OS << "# Machine code for function " << Fn->getName() << ":\n"; // Print Frame Information FrameInfo->print(*this, OS); @@ -318,34 +317,43 @@ void MachineFunction::print(raw_ostream &OS) const { const TargetRegisterInfo *TRI = getTarget().getRegisterInfo(); if (RegInfo && !RegInfo->livein_empty()) { - OS << "Live Ins:"; + OS << "Function Live Ins: "; for (MachineRegisterInfo::livein_iterator I = RegInfo->livein_begin(), E = RegInfo->livein_end(); I != E; ++I) { if (TRI) - OS << " " << TRI->getName(I->first); + OS << "%" << TRI->getName(I->first); else - OS << " Reg #" << I->first; + OS << " %physreg" << I->first; if (I->second) - OS << " in VR#" << I->second << ' '; + OS << " in reg%" << I->second; + + if (next(I) != E) + OS << ", "; } OS << '\n'; } if (RegInfo && !RegInfo->liveout_empty()) { - OS << "Live Outs:"; + OS << "Function Live Outs: "; for (MachineRegisterInfo::liveout_iterator - I = RegInfo->liveout_begin(), E = RegInfo->liveout_end(); I != E; ++I) + I = RegInfo->liveout_begin(), E = RegInfo->liveout_end(); I != E; ++I){ if (TRI) - OS << ' ' << TRI->getName(*I); + OS << '%' << TRI->getName(*I); else - OS << " Reg #" << *I; + OS << "%physreg" << *I; + + if (next(I) != E) + OS << " "; + } OS << '\n'; } - for (const_iterator BB = begin(), E = end(); BB != E; ++BB) + for (const_iterator BB = begin(), E = end(); BB != E; ++BB) { + OS << '\n'; BB->print(OS); + } - OS << "\n# End machine code for " << Fn->getName() << "().\n\n"; + OS << "\n# End machine code for function " << Fn->getName() << ".\n\n"; } namespace llvm { @@ -472,12 +480,16 @@ MachineFrameInfo::getPristineRegs(const MachineBasicBlock *MBB) const { void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{ + if (Objects.empty()) return; + const TargetFrameInfo *FI = MF.getTarget().getFrameInfo(); int ValOffset = (FI ? FI->getOffsetOfLocalArea() : 0); + OS << "Frame Objects:\n"; + for (unsigned i = 0, e = Objects.size(); i != e; ++i) { const StackObject &SO = Objects[i]; - OS << " <fi#" << (int)(i-NumFixedObjects) << ">: "; + OS << " fi#" << (int)(i-NumFixedObjects) << ": "; if (SO.Size == ~0ULL) { OS << "dead\n"; continue; @@ -485,15 +497,14 @@ void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{ if (SO.Size == 0) OS << "variable sized"; else - OS << "size is " << SO.Size << " byte" << (SO.Size != 1 ? "s," : ","); - OS << " alignment is " << SO.Alignment << " byte" - << (SO.Alignment != 1 ? "s," : ","); + OS << "size=" << SO.Size; + OS << ", align=" << SO.Alignment; if (i < NumFixedObjects) - OS << " fixed"; + OS << ", fixed"; if (i < NumFixedObjects || SO.SPOffset != -1) { int64_t Off = SO.SPOffset - ValOffset; - OS << " at location [SP"; + OS << ", at location [SP"; if (Off > 0) OS << "+" << Off; else if (Off < 0) @@ -502,9 +513,6 @@ void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{ } OS << "\n"; } - - if (HasVarSizedObjects) - OS << " Stack frame contains variable sized objects\n"; } void MachineFrameInfo::dump(const MachineFunction &MF) const { @@ -548,12 +556,17 @@ MachineJumpTableInfo::ReplaceMBBInJumpTables(MachineBasicBlock *Old, } void MachineJumpTableInfo::print(raw_ostream &OS) const { - // FIXME: this is lame, maybe we could print out the MBB numbers or something - // like {1, 2, 4, 5, 3, 0} + if (JumpTables.empty()) return; + + OS << "Jump Tables:\n"; + for (unsigned i = 0, e = JumpTables.size(); i != e; ++i) { - OS << " <jt#" << i << "> has " << JumpTables[i].MBBs.size() - << " entries\n"; + OS << " jt#" << i << ": "; + for (unsigned j = 0, f = JumpTables[i].MBBs.size(); j != f; ++j) + OS << " BB#" << JumpTables[i].MBBs[j]->getNumber(); } + + OS << '\n'; } void MachineJumpTableInfo::dump() const { print(errs()); } @@ -582,6 +595,48 @@ MachineConstantPool::~MachineConstantPool() { delete Constants[i].Val.MachineCPVal; } +/// CanShareConstantPoolEntry - Test whether the given two constants +/// can be allocated the same constant pool entry. +static bool CanShareConstantPoolEntry(Constant *A, Constant *B, + const TargetData *TD) { + // Handle the trivial case quickly. + if (A == B) return true; + + // If they have the same type but weren't the same constant, quickly + // reject them. + if (A->getType() == B->getType()) return false; + + // For now, only support constants with the same size. + if (TD->getTypeStoreSize(A->getType()) != TD->getTypeStoreSize(B->getType())) + return false; + + // If a floating-point value and an integer value have the same encoding, + // they can share a constant-pool entry. + if (ConstantFP *AFP = dyn_cast<ConstantFP>(A)) + if (ConstantInt *BI = dyn_cast<ConstantInt>(B)) + return AFP->getValueAPF().bitcastToAPInt() == BI->getValue(); + if (ConstantFP *BFP = dyn_cast<ConstantFP>(B)) + if (ConstantInt *AI = dyn_cast<ConstantInt>(A)) + return BFP->getValueAPF().bitcastToAPInt() == AI->getValue(); + + // Two vectors can share an entry if each pair of corresponding + // elements could. + if (ConstantVector *AV = dyn_cast<ConstantVector>(A)) + if (ConstantVector *BV = dyn_cast<ConstantVector>(B)) { + if (AV->getType()->getNumElements() != BV->getType()->getNumElements()) + return false; + for (unsigned i = 0, e = AV->getType()->getNumElements(); i != e; ++i) + if (!CanShareConstantPoolEntry(AV->getOperand(i), + BV->getOperand(i), TD)) + return false; + return true; + } + + // TODO: Handle other cases. + + return false; +} + /// getConstantPoolIndex - Create a new entry in the constant pool or return /// an existing one. User must specify the log2 of the minimum required /// alignment for the object. @@ -590,14 +645,17 @@ unsigned MachineConstantPool::getConstantPoolIndex(Constant *C, unsigned Alignment) { assert(Alignment && "Alignment must be specified!"); if (Alignment > PoolAlignment) PoolAlignment = Alignment; - + // Check to see if we already have this constant. // // FIXME, this could be made much more efficient for large constant pools. for (unsigned i = 0, e = Constants.size(); i != e; ++i) - if (Constants[i].Val.ConstVal == C && - (Constants[i].getAlignment() & (Alignment - 1)) == 0) + if (!Constants[i].isMachineConstantPoolEntry() && + CanShareConstantPoolEntry(Constants[i].Val.ConstVal, C, TD)) { + if ((unsigned)Constants[i].getAlignment() < Alignment) + Constants[i].Alignment = Alignment; return i; + } Constants.push_back(MachineConstantPoolEntry(C, Alignment)); return Constants.size()-1; @@ -620,13 +678,16 @@ unsigned MachineConstantPool::getConstantPoolIndex(MachineConstantPoolValue *V, } void MachineConstantPool::print(raw_ostream &OS) const { + if (Constants.empty()) return; + + OS << "Constant Pool:\n"; for (unsigned i = 0, e = Constants.size(); i != e; ++i) { - OS << " <cp#" << i << "> is"; + OS << " cp#" << i << ": "; if (Constants[i].isMachineConstantPoolEntry()) Constants[i].Val.MachineCPVal->print(OS); else OS << *(Value*)Constants[i].Val.ConstVal; - OS << " , alignment=" << Constants[i].getAlignment(); + OS << ", align=" << Constants[i].getAlignment(); OS << "\n"; } } diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 1f85e92..5744c8a 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -13,6 +13,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Constants.h" +#include "llvm/Function.h" #include "llvm/InlineAsm.h" #include "llvm/Value.h" #include "llvm/Assembly/Writer.h" @@ -180,6 +181,8 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { case MachineOperand::MO_ExternalSymbol: return !strcmp(getSymbolName(), Other.getSymbolName()) && getOffset() == Other.getOffset(); + case MachineOperand::MO_BlockAddress: + return getBlockAddress() == Other.getBlockAddress(); } } @@ -202,7 +205,7 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { if (TM) OS << "%" << TM->getRegisterInfo()->get(getReg()).Name; else - OS << "%mreg" << getReg(); + OS << "%physreg" << getReg(); } if (getSubReg() != 0) @@ -248,9 +251,7 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { OS << getFPImm()->getValueAPF().convertToDouble(); break; case MachineOperand::MO_MachineBasicBlock: - OS << "mbb<" - << ((Value*)getMBB()->getBasicBlock())->getName() - << "," << (void*)getMBB() << '>'; + OS << "<BB#" << getMBB()->getNumber() << ">"; break; case MachineOperand::MO_FrameIndex: OS << "<fi#" << getIndex() << '>'; @@ -273,6 +274,11 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { if (getOffset()) OS << "+" << getOffset(); OS << '>'; break; + case MachineOperand::MO_BlockAddress: + OS << "<"; + WriteAsOperand(OS, getBlockAddress(), /*PrintType=*/false); + OS << '>'; + break; default: llvm_unreachable("Unrecognized operand type"); } @@ -1054,16 +1060,24 @@ void MachineInstr::dump() const { } void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { - // Specialize printing if op#0 is definition - unsigned StartOp = 0; - if (getNumOperands() && getOperand(0).isReg() && getOperand(0).isDef()) { - getOperand(0).print(OS, TM); - OS << " = "; - ++StartOp; // Don't print this operand again! + unsigned StartOp = 0, e = getNumOperands(); + + // Print explicitly defined operands on the left of an assignment syntax. + for (; StartOp < e && getOperand(StartOp).isReg() && + getOperand(StartOp).isDef() && + !getOperand(StartOp).isImplicit(); + ++StartOp) { + if (StartOp != 0) OS << ", "; + getOperand(StartOp).print(OS, TM); } + if (StartOp != 0) + OS << " = "; + + // Print the opcode name. OS << getDesc().getName(); + // Print the rest of the operands. for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { if (i != StartOp) OS << ","; @@ -1071,8 +1085,11 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { getOperand(i).print(OS, TM); } + bool HaveSemi = false; if (!memoperands_empty()) { - OS << ", Mem:"; + if (!HaveSemi) OS << ";"; HaveSemi = true; + + OS << " mem:"; for (mmo_iterator i = memoperands_begin(), e = memoperands_end(); i != e; ++i) { OS << **i; @@ -1082,14 +1099,16 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { } if (!debugLoc.isUnknown()) { + if (!HaveSemi) OS << ";"; HaveSemi = true; + + // TODO: print InlinedAtLoc information + const MachineFunction *MF = getParent()->getParent(); DebugLocTuple DLT = MF->getDebugLocTuple(debugLoc); DICompileUnit CU(DLT.Scope); if (!CU.isNull()) - OS << " [dbg: " - << CU.getDirectory() << '/' << CU.getFilename() << "," - << DLT.Line << "," - << DLT.Col << "]"; + OS << " dbg:" << CU.getDirectory() << '/' << CU.getFilename() << ":" + << DLT.Line << ":" << DLT.Col; } OS << "\n"; diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp index f92ddb2..1306aa6 100644 --- a/lib/CodeGen/MachineLICM.cpp +++ b/lib/CodeGen/MachineLICM.cpp @@ -24,14 +24,15 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Statistic.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -41,7 +42,7 @@ STATISTIC(NumHoisted, "Number of machine instructions hoisted out of loops"); STATISTIC(NumCSEed, "Number of hoisted machine instructions CSEed"); namespace { - class VISIBILITY_HIDDEN MachineLICM : public MachineFunctionPass { + class MachineLICM : public MachineFunctionPass { const TargetMachine *TM; const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; @@ -55,12 +56,12 @@ namespace { // State that is updated as we process loops bool Changed; // True if a loop is changed. + bool FirstInLoop; // True if it's the first LICM in the loop. MachineLoop *CurLoop; // The current loop we are working on. MachineBasicBlock *CurPreheader; // The preheader for CurLoop. - // For each BB and opcode pair, keep a list of hoisted instructions. - DenseMap<std::pair<unsigned, unsigned>, - std::vector<const MachineInstr*> > CSEMap; + // For each opcode, keep a list of potentail CSE instructions. + DenseMap<unsigned, std::vector<const MachineInstr*> > CSEMap; public: static char ID; // Pass identification, replacement for typeid MachineLICM() : MachineFunctionPass(&ID) {} @@ -104,10 +105,21 @@ namespace { /// void HoistRegion(MachineDomTreeNode *N); + /// ExtractHoistableLoad - Unfold a load from the given machineinstr if + /// the load itself could be hoisted. Return the unfolded and hoistable + /// load, or null if the load couldn't be unfolded or if it wouldn't + /// be hoistable. + MachineInstr *ExtractHoistableLoad(MachineInstr *MI); + /// 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. /// - void Hoist(MachineInstr &MI); + void Hoist(MachineInstr *MI); + + /// InitCSEMap - Initialize the CSE map with instructions that are in the + /// current loop preheader that may become duplicates of instructions that + /// are hoisted out of the loop. + void InitCSEMap(MachineBasicBlock *BB); }; } // end anonymous namespace @@ -133,7 +145,7 @@ static bool LoopIsOuterMostWithPreheader(MachineLoop *CurLoop) { bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { DEBUG(errs() << "******** Machine LICM ********\n"); - Changed = false; + Changed = FirstInLoop = false; TM = &MF.getTarget(); TII = TM->getInstrInfo(); TRI = TM->getRegisterInfo(); @@ -145,8 +157,7 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { DT = &getAnalysis<MachineDominatorTree>(); AA = &getAnalysis<AliasAnalysis>(); - for (MachineLoopInfo::iterator - I = LI->begin(), E = LI->end(); I != E; ++I) { + for (MachineLoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) { CurLoop = *I; // Only visit outer-most preheader-sporting loops. @@ -163,7 +174,11 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { if (!CurPreheader) continue; + // CSEMap is initialized for loop header when the first instruction is + // being hoisted. + FirstInLoop = true; HoistRegion(DT->getNode(CurLoop->getHeader())); + CSEMap.clear(); } return Changed; @@ -184,10 +199,7 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N) { for (MachineBasicBlock::iterator MII = BB->begin(), E = BB->end(); MII != E; ) { MachineBasicBlock::iterator NextMII = MII; ++NextMII; - MachineInstr &MI = *MII; - - Hoist(MI); - + Hoist(&*MII); MII = NextMII; } @@ -368,42 +380,125 @@ static const MachineInstr *LookForDuplicate(const MachineInstr *MI, return 0; } +MachineInstr *MachineLICM::ExtractHoistableLoad(MachineInstr *MI) { + // If not, we may be able to unfold a load and hoist that. + // First test whether the instruction is loading from an amenable + // memory location. + if (!MI->getDesc().mayLoad()) return 0; + if (!MI->hasOneMemOperand()) return 0; + MachineMemOperand *MMO = *MI->memoperands_begin(); + if (MMO->isVolatile()) return 0; + MachineFunction &MF = *MI->getParent()->getParent(); + if (!MMO->getValue()) return 0; + if (const PseudoSourceValue *PSV = + dyn_cast<PseudoSourceValue>(MMO->getValue())) { + if (!PSV->isConstant(MF.getFrameInfo())) return 0; + } else { + if (!AA->pointsToConstantMemory(MMO->getValue())) return 0; + } + // Next determine the register class for a temporary register. + unsigned LoadRegIndex; + unsigned NewOpc = + TII->getOpcodeAfterMemoryUnfold(MI->getOpcode(), + /*UnfoldLoad=*/true, + /*UnfoldStore=*/false, + &LoadRegIndex); + if (NewOpc == 0) return 0; + const TargetInstrDesc &TID = TII->get(NewOpc); + if (TID.getNumDefs() != 1) return 0; + const TargetRegisterClass *RC = TID.OpInfo[LoadRegIndex].getRegClass(TRI); + // Ok, we're unfolding. Create a temporary register and do the unfold. + unsigned Reg = RegInfo->createVirtualRegister(RC); + SmallVector<MachineInstr *, 2> NewMIs; + bool Success = + TII->unfoldMemoryOperand(MF, MI, Reg, + /*UnfoldLoad=*/true, /*UnfoldStore=*/false, + NewMIs); + (void)Success; + assert(Success && + "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold " + "succeeded!"); + assert(NewMIs.size() == 2 && + "Unfolded a load into multiple instructions!"); + MachineBasicBlock *MBB = MI->getParent(); + MBB->insert(MI, NewMIs[0]); + MBB->insert(MI, NewMIs[1]); + // If unfolding produced a load that wasn't loop-invariant or profitable to + // hoist, discard the new instructions and bail. + if (!IsLoopInvariantInst(*NewMIs[0]) || !IsProfitableToHoist(*NewMIs[0])) { + NewMIs[0]->eraseFromParent(); + NewMIs[1]->eraseFromParent(); + return 0; + } + // Otherwise we successfully unfolded a load that we can hoist. + MI->eraseFromParent(); + return NewMIs[0]; +} + +void MachineLICM::InitCSEMap(MachineBasicBlock *BB) { + for (MachineBasicBlock::iterator I = BB->begin(),E = BB->end(); I != E; ++I) { + const MachineInstr *MI = &*I; + // FIXME: For now, only hoist re-materilizable instructions. LICM will + // increase register pressure. We want to make sure it doesn't increase + // spilling. + if (TII->isTriviallyReMaterializable(MI, AA)) { + unsigned Opcode = MI->getOpcode(); + DenseMap<unsigned, std::vector<const MachineInstr*> >::iterator + CI = CSEMap.find(Opcode); + if (CI != CSEMap.end()) + CI->second.push_back(MI); + else { + std::vector<const MachineInstr*> CSEMIs; + CSEMIs.push_back(MI); + CSEMap.insert(std::make_pair(Opcode, CSEMIs)); + } + } + } +} + /// 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; - if (!IsProfitableToHoist(MI)) return; +void MachineLICM::Hoist(MachineInstr *MI) { + // First check whether we should hoist this instruction. + if (!IsLoopInvariantInst(*MI) || !IsProfitableToHoist(*MI)) { + // If not, try unfolding a hoistable load. + MI = ExtractHoistableLoad(MI); + if (!MI) return; + } // Now move the instructions to the predecessor, inserting it before any // terminator instructions. DEBUG({ - errs() << "Hoisting " << MI; + errs() << "Hoisting " << *MI; if (CurPreheader->getBasicBlock()) errs() << " to MachineBasicBlock " << CurPreheader->getBasicBlock()->getName(); - if (MI.getParent()->getBasicBlock()) + if (MI->getParent()->getBasicBlock()) errs() << " from MachineBasicBlock " - << MI.getParent()->getBasicBlock()->getName(); + << MI->getParent()->getBasicBlock()->getName(); errs() << "\n"; }); + // If this is the first instruction being hoisted to the preheader, + // initialize the CSE map with potential common expressions. + InitCSEMap(CurPreheader); + // Look for opportunity to CSE the hoisted instruction. - std::pair<unsigned, unsigned> BBOpcPair = - std::make_pair(CurPreheader->getNumber(), MI.getOpcode()); - DenseMap<std::pair<unsigned, unsigned>, - std::vector<const MachineInstr*> >::iterator CI = CSEMap.find(BBOpcPair); + unsigned Opcode = MI->getOpcode(); + DenseMap<unsigned, std::vector<const MachineInstr*> >::iterator + CI = CSEMap.find(Opcode); bool DoneCSE = false; if (CI != CSEMap.end()) { - const MachineInstr *Dup = LookForDuplicate(&MI, CI->second, RegInfo); + const MachineInstr *Dup = LookForDuplicate(MI, CI->second, RegInfo); if (Dup) { - DEBUG(errs() << "CSEing " << MI << " with " << *Dup); - for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI.getOperand(i); + DEBUG(errs() << "CSEing " << *MI << " with " << *Dup); + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); if (MO.isReg() && MO.isDef()) RegInfo->replaceRegWith(MO.getReg(), Dup->getOperand(i).getReg()); } - MI.eraseFromParent(); + MI->eraseFromParent(); DoneCSE = true; ++NumCSEed; } @@ -411,15 +506,15 @@ void MachineLICM::Hoist(MachineInstr &MI) { // Otherwise, splice the instruction to the preheader. if (!DoneCSE) { - CurPreheader->splice(CurPreheader->getFirstTerminator(), - MI.getParent(), &MI); + CurPreheader->splice(CurPreheader->getFirstTerminator(),MI->getParent(),MI); + // Add to the CSE map. if (CI != CSEMap.end()) - CI->second.push_back(&MI); + CI->second.push_back(MI); else { std::vector<const MachineInstr*> CSEMIs; - CSEMIs.push_back(&MI); - CSEMap.insert(std::make_pair(BBOpcPair, CSEMIs)); + CSEMIs.push_back(MI); + CSEMap.insert(std::make_pair(Opcode, CSEMIs)); } } diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp index a00bebb..e040738 100644 --- a/lib/CodeGen/MachineSink.cpp +++ b/lib/CodeGen/MachineSink.cpp @@ -25,7 +25,6 @@ #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,7 +32,7 @@ using namespace llvm; STATISTIC(NumSunk, "Number of machine instructions sunk"); namespace { - class VISIBILITY_HIDDEN MachineSinking : public MachineFunctionPass { + class MachineSinking : public MachineFunctionPass { const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; MachineRegisterInfo *RegInfo; // Machine register information diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index 18a3ead..99812e0 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -36,14 +36,13 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SetOperations.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { - struct VISIBILITY_HIDDEN MachineVerifier : public MachineFunctionPass { + struct MachineVerifier : public MachineFunctionPass { static char ID; // Pass ID, replacement for typeid MachineVerifier(bool allowDoubleDefs = false) : @@ -244,7 +243,7 @@ void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB) { report(msg, MBB->getParent()); *OS << "- basic block: " << MBB->getBasicBlock()->getNameStr() << " " << (void*)MBB - << " (#" << MBB->getNumber() << ")\n"; + << " (BB#" << MBB->getNumber() << ")\n"; } void MachineVerifier::report(const char *msg, const MachineInstr *MI) { @@ -746,7 +745,7 @@ void MachineVerifier::checkPHIOps(const MachineBasicBlock *MBB) { PrE = MBB->pred_end(); PrI != PrE; ++PrI) { if (!seen.count(*PrI)) { report("Missing PHI operand", BBI); - *OS << "MBB #" << (*PrI)->getNumber() + *OS << "BB#" << (*PrI)->getNumber() << " is a predecessor according to the CFG.\n"; } } @@ -781,7 +780,7 @@ void MachineVerifier::visitMachineFunctionAfter() { report("Live-in physical register is not live-out from predecessor", MFI); *OS << "Register " << TRI->getName(*I) - << " is not live-out from MBB #" << (*PrI)->getNumber() + << " is not live-out from BB#" << (*PrI)->getNumber() << ".\n"; } } diff --git a/lib/CodeGen/OcamlGC.cpp b/lib/CodeGen/OcamlGC.cpp index f7bc9f3..48db200 100644 --- a/lib/CodeGen/OcamlGC.cpp +++ b/lib/CodeGen/OcamlGC.cpp @@ -16,12 +16,11 @@ #include "llvm/CodeGen/GCs.h" #include "llvm/CodeGen/GCStrategy.h" -#include "llvm/Support/Compiler.h" using namespace llvm; namespace { - class VISIBILITY_HIDDEN OcamlGC : public GCStrategy { + class OcamlGC : public GCStrategy { public: OcamlGC(); }; diff --git a/lib/CodeGen/PostRASchedulerList.cpp b/lib/CodeGen/PostRASchedulerList.cpp index 8fdbe9b..d5edb36 100644 --- a/lib/CodeGen/PostRASchedulerList.cpp +++ b/lib/CodeGen/PostRASchedulerList.cpp @@ -19,6 +19,9 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "post-RA-sched" +#include "AntiDepBreaker.h" +#include "AggressiveAntiDepBreaker.h" +#include "CriticalAntiDepBreaker.h" #include "ExactHazardRecognizer.h" #include "SimpleHazardRecognizer.h" #include "ScheduleDAGInstrs.h" @@ -37,10 +40,11 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetSubtarget.h" -#include "llvm/Support/Compiler.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/Statistic.h" #include <map> #include <set> @@ -48,6 +52,7 @@ using namespace llvm; STATISTIC(NumNoops, "Number of noops inserted"); STATISTIC(NumStalls, "Number of pipeline stalls"); +STATISTIC(NumFixedAnti, "Number of fixed anti-dependencies"); // Post-RA scheduling is enabled with // TargetSubtarget.enablePostRAScheduler(). This flag can be used to @@ -56,10 +61,11 @@ static cl::opt<bool> EnablePostRAScheduler("post-RA-scheduler", cl::desc("Enable scheduling after register allocation"), cl::init(false), cl::Hidden); -static cl::opt<bool> +static cl::opt<std::string> EnableAntiDepBreaking("break-anti-dependencies", - cl::desc("Break post-RA scheduling anti-dependencies"), - cl::init(true), cl::Hidden); + cl::desc("Break post-RA scheduling anti-dependencies: " + "\"critical\", \"all\", or \"none\""), + cl::init("none"), cl::Hidden); static cl::opt<bool> EnablePostRAHazardAvoidance("avoid-hazards", cl::desc("Enable exact hazard avoidance"), @@ -75,8 +81,10 @@ DebugMod("postra-sched-debugmod", cl::desc("Debug control MBBs that are scheduled"), cl::init(0), cl::Hidden); +AntiDepBreaker::~AntiDepBreaker() { } + namespace { - class VISIBILITY_HIDDEN PostRAScheduler : public MachineFunctionPass { + class PostRAScheduler : public MachineFunctionPass { AliasAnalysis *AA; CodeGenOpt::Level OptLevel; @@ -103,7 +111,7 @@ namespace { }; char PostRAScheduler::ID = 0; - class VISIBILITY_HIDDEN SchedulePostRATDList : public ScheduleDAGInstrs { + class SchedulePostRATDList : public ScheduleDAGInstrs { /// AvailableQueue - The priority queue to use for the available SUnits. /// LatencyPriorityQueue AvailableQueue; @@ -117,56 +125,30 @@ namespace { /// Topo - A topological ordering for SUnits. ScheduleDAGTopologicalSort Topo; - /// AllocatableSet - The set of allocatable registers. - /// We'll be ignoring anti-dependencies on non-allocatable registers, - /// because they may not be safe to break. - const BitVector AllocatableSet; - /// HazardRec - The hazard recognizer to use. ScheduleHazardRecognizer *HazardRec; + /// AntiDepBreak - Anti-dependence breaking object, or NULL if none + AntiDepBreaker *AntiDepBreak; + /// AA - AliasAnalysis for making memory reference queries. AliasAnalysis *AA; - /// AntiDepMode - Anti-dependence breaking mode - TargetSubtarget::AntiDepBreakMode AntiDepMode; - - /// Classes - For live regs that are only used in one register class in a - /// live range, the register class. If the register is not live, the - /// corresponding value is null. If the register is live but used in - /// multiple register classes, the corresponding value is -1 casted to a - /// pointer. - const TargetRegisterClass * - Classes[TargetRegisterInfo::FirstVirtualRegister]; - - /// RegRegs - Map registers to all their references within a live range. - std::multimap<unsigned, MachineOperand *> RegRefs; - /// KillIndices - The index of the most recent kill (proceding bottom-up), /// or ~0u if the register is not live. unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; - /// DefIndices - The index of the most recent complete def (proceding bottom - /// up), or ~0u if the register is live. - unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; - - /// KeepRegs - A set of registers which are live and cannot be changed to - /// break anti-dependencies. - SmallSet<unsigned, 4> KeepRegs; - public: SchedulePostRATDList(MachineFunction &MF, const MachineLoopInfo &MLI, const MachineDominatorTree &MDT, ScheduleHazardRecognizer *HR, - AliasAnalysis *aa, - TargetSubtarget::AntiDepBreakMode adm) + AntiDepBreaker *ADB, + AliasAnalysis *aa) : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), - AllocatableSet(TRI->getAllocatableSet(MF)), - HazardRec(HR), AA(aa), AntiDepMode(adm) {} + HazardRec(HR), AntiDepBreak(ADB), AA(aa) {} ~SchedulePostRATDList() { - delete HazardRec; } /// StartBlock - Initialize register live-range state for scheduling in @@ -178,11 +160,6 @@ namespace { /// void Schedule(); - /// FixupKills - Fix register kill flags that have been made - /// invalid due to scheduling - /// - void FixupKills(MachineBasicBlock *MBB); - /// Observe - Update liveness information to account for the current /// instruction, which will not be scheduled. /// @@ -192,17 +169,17 @@ namespace { /// void FinishBlock(); + /// FixupKills - Fix register kill flags that have been made + /// invalid due to scheduling + /// + void FixupKills(MachineBasicBlock *MBB); + private: - void PrescanInstruction(MachineInstr *MI); - void ScanInstruction(MachineInstr *MI, unsigned Count); - void ReleaseSucc(SUnit *SU, SDep *SuccEdge); - void ReleaseSuccessors(SUnit *SU); - void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); - void ListScheduleTopDown(); - bool BreakAntiDependencies(); - unsigned findSuitableFreeRegister(unsigned AntiDepReg, - unsigned LastNewReg, - const TargetRegisterClass *); + void ReleaseSucc(SUnit *SU, SDep *SuccEdge, bool IgnoreAntiDep); + void ReleaseSuccessors(SUnit *SU, bool IgnoreAntiDep); + void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle, bool IgnoreAntiDep); + void ListScheduleTopDown( + AntiDepBreaker::CandidateMap *AntiDepCandidates); void StartBlockForKills(MachineBasicBlock *BB); // ToggleKillFlag - Toggle a register operand kill flag. Other @@ -251,8 +228,9 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { // Check for antidep breaking override... if (EnableAntiDepBreaking.getPosition() > 0) { - AntiDepMode = (EnableAntiDepBreaking) ? - TargetSubtarget::ANTIDEP_CRITICAL : TargetSubtarget::ANTIDEP_NONE; + AntiDepMode = (EnableAntiDepBreaking == "all") ? TargetSubtarget::ANTIDEP_ALL : + (EnableAntiDepBreaking == "critical") ? TargetSubtarget::ANTIDEP_CRITICAL : + TargetSubtarget::ANTIDEP_NONE; } DEBUG(errs() << "PostRAScheduler\n"); @@ -263,8 +241,13 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { ScheduleHazardRecognizer *HR = EnablePostRAHazardAvoidance ? (ScheduleHazardRecognizer *)new ExactHazardRecognizer(InstrItins) : (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); + AntiDepBreaker *ADB = + ((AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? + (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn) : + ((AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? + (AntiDepBreaker *)new CriticalAntiDepBreaker(Fn) : NULL)); - SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, AA, AntiDepMode); + SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); // Loop over all of the basic blocks for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); @@ -276,7 +259,7 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { if (bbcnt++ % DebugDiv != DebugMod) continue; errs() << "*** DEBUG scheduling " << Fn.getFunction()->getNameStr() << - ":MBB ID#" << MBB->getNumber() << " ***\n"; + ":BB#" << MBB->getNumber() << " ***\n"; } #endif @@ -312,6 +295,9 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { Scheduler.FixupKills(MBB); } + delete HR; + delete ADB; + return true; } @@ -322,110 +308,72 @@ void SchedulePostRATDList::StartBlock(MachineBasicBlock *BB) { // Call the superclass. ScheduleDAGInstrs::StartBlock(BB); - // Reset the hazard recognizer. + // Reset the hazard recognizer and anti-dep breaker. HazardRec->Reset(); - - // Clear out the register class data. - std::fill(Classes, array_endof(Classes), - static_cast<const TargetRegisterClass *>(0)); - - // Initialize the indices to indicate that no registers are live. - std::fill(KillIndices, array_endof(KillIndices), ~0u); - std::fill(DefIndices, array_endof(DefIndices), BB->size()); - - // Clear "do not change" set. - KeepRegs.clear(); - - bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); - - // Determine the live-out physregs for this block. - if (IsReturnBlock) { - // In a return block, examine the function live-out regs. - for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), - E = MRI.liveout_end(); I != E; ++I) { - unsigned Reg = *I; - Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); - KillIndices[Reg] = BB->size(); - DefIndices[Reg] = ~0u; - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1); - KillIndices[AliasReg] = BB->size(); - DefIndices[AliasReg] = ~0u; - } - } - } else { - // In a non-return block, examine the live-in regs of all successors. - for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), - SE = BB->succ_end(); SI != SE; ++SI) - for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), - E = (*SI)->livein_end(); I != E; ++I) { - unsigned Reg = *I; - Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); - KillIndices[Reg] = BB->size(); - DefIndices[Reg] = ~0u; - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1); - KillIndices[AliasReg] = BB->size(); - DefIndices[AliasReg] = ~0u; - } - } - } - - // Mark live-out callee-saved registers. In a return block this is - // all callee-saved registers. In non-return this is any - // callee-saved register that is not saved in the prolog. - const MachineFrameInfo *MFI = MF.getFrameInfo(); - BitVector Pristine = MFI->getPristineRegs(BB); - for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { - unsigned Reg = *I; - if (!IsReturnBlock && !Pristine.test(Reg)) continue; - Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); - KillIndices[Reg] = BB->size(); - DefIndices[Reg] = ~0u; - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1); - KillIndices[AliasReg] = BB->size(); - DefIndices[AliasReg] = ~0u; - } - } + if (AntiDepBreak != NULL) + AntiDepBreak->StartBlock(BB); } /// Schedule - Schedule the instruction range using list scheduling. /// void SchedulePostRATDList::Schedule() { - DEBUG(errs() << "********** List Scheduling **********\n"); - // Build the scheduling graph. BuildSchedGraph(AA); - if (AntiDepMode != TargetSubtarget::ANTIDEP_NONE) { - if (BreakAntiDependencies()) { + if (AntiDepBreak != NULL) { + AntiDepBreaker::CandidateMap AntiDepCandidates; + const bool NeedCandidates = AntiDepBreak->NeedCandidates(); + + for (unsigned i = 0, Trials = AntiDepBreak->GetMaxTrials(); + i < Trials; ++i) { + DEBUG(errs() << "\n********** Break Anti-Deps, Trial " << + i << " **********\n"); + + // If candidates are required, then schedule forward ignoring + // anti-dependencies to collect the candidate operands for + // anti-dependence breaking. The candidates will be the def + // operands for the anti-dependencies that if broken would allow + // an improved schedule + if (NeedCandidates) { + DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) + SUnits[su].dumpAll(this)); + + AntiDepCandidates.clear(); + AvailableQueue.initNodes(SUnits); + ListScheduleTopDown(&AntiDepCandidates); + AvailableQueue.releaseState(); + } + + unsigned Broken = + AntiDepBreak->BreakAntiDependencies(SUnits, AntiDepCandidates, + Begin, InsertPos, InsertPosIndex); + // We made changes. Update the dependency graph. // Theoretically we could update the graph in place: // When a live range is changed to use a different register, remove // the def's anti-dependence *and* output-dependence edges due to // that register, and add new anti-dependence and output-dependence // edges based on the next live range of the register. - SUnits.clear(); - EntrySU = SUnit(); - ExitSU = SUnit(); - BuildSchedGraph(AA); + if ((Broken != 0) || NeedCandidates) { + SUnits.clear(); + Sequence.clear(); + EntrySU = SUnit(); + ExitSU = SUnit(); + BuildSchedGraph(AA); + } + + NumFixedAnti += Broken; + if (Broken == 0) + break; } } + DEBUG(errs() << "********** List Scheduling **********\n"); DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) SUnits[su].dumpAll(this)); AvailableQueue.initNodes(SUnits); - - ListScheduleTopDown(); - + ListScheduleTopDown(NULL); AvailableQueue.releaseState(); } @@ -433,436 +381,20 @@ void SchedulePostRATDList::Schedule() { /// instruction, which will not be scheduled. /// void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) { - assert(Count < InsertPosIndex && "Instruction index out of expected range!"); - - // Any register which was defined within the previous scheduling region - // may have been rescheduled and its lifetime may overlap with registers - // in ways not reflected in our current liveness state. For each such - // register, adjust the liveness state to be conservatively correct. - for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) - if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) { - assert(KillIndices[Reg] == ~0u && "Clobbered register is live!"); - // Mark this register to be non-renamable. - Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); - // Move the def index to the end of the previous region, to reflect - // that the def could theoretically have been scheduled at the end. - DefIndices[Reg] = InsertPosIndex; - } - - PrescanInstruction(MI); - ScanInstruction(MI, Count); + if (AntiDepBreak != NULL) + AntiDepBreak->Observe(MI, Count, InsertPosIndex); } /// FinishBlock - Clean up register live-range state. /// void SchedulePostRATDList::FinishBlock() { - RegRefs.clear(); + if (AntiDepBreak != NULL) + AntiDepBreak->FinishBlock(); // Call the superclass. ScheduleDAGInstrs::FinishBlock(); } -/// CriticalPathStep - Return the next SUnit after SU on the bottom-up -/// critical path. -static SDep *CriticalPathStep(SUnit *SU) { - SDep *Next = 0; - unsigned NextDepth = 0; - // Find the predecessor edge with the greatest depth. - for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); - P != PE; ++P) { - SUnit *PredSU = P->getSUnit(); - unsigned PredLatency = P->getLatency(); - unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; - // In the case of a latency tie, prefer an anti-dependency edge over - // other types of edges. - if (NextDepth < PredTotalLatency || - (NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) { - NextDepth = PredTotalLatency; - Next = &*P; - } - } - return Next; -} - -void SchedulePostRATDList::PrescanInstruction(MachineInstr *MI) { - // Scan the register operands for this instruction and update - // Classes and RegRefs. - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); - if (Reg == 0) continue; - const TargetRegisterClass *NewRC = 0; - - if (i < MI->getDesc().getNumOperands()) - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); - - // For now, only allow the register to be changed if its register - // class is consistent across all uses. - if (!Classes[Reg] && NewRC) - Classes[Reg] = NewRC; - else if (!NewRC || Classes[Reg] != NewRC) - Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); - - // Now check for aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - // If an alias of the reg is used during the live range, give up. - // Note that this allows us to skip checking if AntiDepReg - // overlaps with any of the aliases, among other things. - unsigned AliasReg = *Alias; - if (Classes[AliasReg]) { - Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1); - Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); - } - } - - // If we're still willing to consider this register, note the reference. - if (Classes[Reg] != reinterpret_cast<TargetRegisterClass *>(-1)) - RegRefs.insert(std::make_pair(Reg, &MO)); - - // It's not safe to change register allocation for source operands of - // that have special allocation requirements. - if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { - if (KeepRegs.insert(Reg)) { - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); - *Subreg; ++Subreg) - KeepRegs.insert(*Subreg); - } - } - } -} - -void SchedulePostRATDList::ScanInstruction(MachineInstr *MI, - unsigned Count) { - // Update liveness. - // Proceding upwards, registers that are defed but not used in this - // instruction are now dead. - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); - if (Reg == 0) continue; - if (!MO.isDef()) continue; - // Ignore two-addr defs. - if (MI->isRegTiedToUseOperand(i)) continue; - - DefIndices[Reg] = Count; - KillIndices[Reg] = ~0u; - assert(((KillIndices[Reg] == ~0u) != - (DefIndices[Reg] == ~0u)) && - "Kill and Def maps aren't consistent for Reg!"); - KeepRegs.erase(Reg); - Classes[Reg] = 0; - RegRefs.erase(Reg); - // Repeat, for all subregs. - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); - *Subreg; ++Subreg) { - unsigned SubregReg = *Subreg; - DefIndices[SubregReg] = Count; - KillIndices[SubregReg] = ~0u; - KeepRegs.erase(SubregReg); - Classes[SubregReg] = 0; - RegRefs.erase(SubregReg); - } - // Conservatively mark super-registers as unusable. - for (const unsigned *Super = TRI->getSuperRegisters(Reg); - *Super; ++Super) { - unsigned SuperReg = *Super; - Classes[SuperReg] = reinterpret_cast<TargetRegisterClass *>(-1); - } - } - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); - if (Reg == 0) continue; - if (!MO.isUse()) continue; - - const TargetRegisterClass *NewRC = 0; - if (i < MI->getDesc().getNumOperands()) - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); - - // For now, only allow the register to be changed if its register - // class is consistent across all uses. - if (!Classes[Reg] && NewRC) - Classes[Reg] = NewRC; - else if (!NewRC || Classes[Reg] != NewRC) - Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1); - - RegRefs.insert(std::make_pair(Reg, &MO)); - - // It wasn't previously live but now it is, this is a kill. - if (KillIndices[Reg] == ~0u) { - KillIndices[Reg] = Count; - DefIndices[Reg] = ~0u; - assert(((KillIndices[Reg] == ~0u) != - (DefIndices[Reg] == ~0u)) && - "Kill and Def maps aren't consistent for Reg!"); - } - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - if (KillIndices[AliasReg] == ~0u) { - KillIndices[AliasReg] = Count; - DefIndices[AliasReg] = ~0u; - } - } - } -} - -unsigned -SchedulePostRATDList::findSuitableFreeRegister(unsigned AntiDepReg, - unsigned LastNewReg, - const TargetRegisterClass *RC) { - for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF), - RE = RC->allocation_order_end(MF); R != RE; ++R) { - unsigned NewReg = *R; - // Don't replace a register with itself. - if (NewReg == AntiDepReg) continue; - // Don't replace a register with one that was recently used to repair - // an anti-dependence with this AntiDepReg, because that would - // re-introduce that anti-dependence. - if (NewReg == LastNewReg) continue; - // If NewReg is dead and NewReg's most recent def is not before - // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. - assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) && - "Kill and Def maps aren't consistent for AntiDepReg!"); - assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) && - "Kill and Def maps aren't consistent for NewReg!"); - if (KillIndices[NewReg] != ~0u || - Classes[NewReg] == reinterpret_cast<TargetRegisterClass *>(-1) || - KillIndices[AntiDepReg] > DefIndices[NewReg]) - continue; - return NewReg; - } - - // No registers are free and available! - return 0; -} - -/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path -/// of the ScheduleDAG and break them by renaming registers. -/// -bool SchedulePostRATDList::BreakAntiDependencies() { - // The code below assumes that there is at least one instruction, - // so just duck out immediately if the block is empty. - if (SUnits.empty()) return false; - - // Find the node at the bottom of the critical path. - SUnit *Max = 0; - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { - SUnit *SU = &SUnits[i]; - if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency) - Max = SU; - } - -#ifndef NDEBUG - { - DEBUG(errs() << "Critical path has total latency " - << (Max->getDepth() + Max->Latency) << "\n"); - DEBUG(errs() << "Available regs:"); - for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { - if (KillIndices[Reg] == ~0u) - DEBUG(errs() << " " << TRI->getName(Reg)); - } - DEBUG(errs() << '\n'); - } -#endif - - // Track progress along the critical path through the SUnit graph as we walk - // the instructions. - SUnit *CriticalPathSU = Max; - MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); - - // Consider this pattern: - // A = ... - // ... = A - // A = ... - // ... = A - // A = ... - // ... = A - // A = ... - // ... = A - // There are three anti-dependencies here, and without special care, - // we'd break all of them using the same register: - // A = ... - // ... = A - // B = ... - // ... = B - // B = ... - // ... = B - // B = ... - // ... = B - // because at each anti-dependence, B is the first register that - // isn't A which is free. This re-introduces anti-dependencies - // at all but one of the original anti-dependencies that we were - // trying to break. To avoid this, keep track of the most recent - // register that each register was replaced with, avoid - // using it to repair an anti-dependence on the same register. - // This lets us produce this: - // A = ... - // ... = A - // B = ... - // ... = B - // C = ... - // ... = C - // B = ... - // ... = B - // This still has an anti-dependence on B, but at least it isn't on the - // original critical path. - // - // TODO: If we tracked more than one register here, we could potentially - // fix that remaining critical edge too. This is a little more involved, - // because unlike the most recent register, less recent registers should - // still be considered, though only if no other registers are available. - unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; - - // Attempt to break anti-dependence edges on the critical path. Walk the - // instructions from the bottom up, tracking information about liveness - // as we go to help determine which registers are available. - bool Changed = false; - unsigned Count = InsertPosIndex - 1; - for (MachineBasicBlock::iterator I = InsertPos, E = Begin; - I != E; --Count) { - MachineInstr *MI = --I; - - // Check if this instruction has a dependence on the critical path that - // is an anti-dependence that we may be able to break. If it is, set - // AntiDepReg to the non-zero register associated with the anti-dependence. - // - // We limit our attention to the critical path as a heuristic to avoid - // breaking anti-dependence edges that aren't going to significantly - // impact the overall schedule. There are a limited number of registers - // and we want to save them for the important edges. - // - // TODO: Instructions with multiple defs could have multiple - // anti-dependencies. The current code here only knows how to break one - // edge per instruction. Note that we'd have to be able to break all of - // the anti-dependencies in an instruction in order to be effective. - unsigned AntiDepReg = 0; - if (MI == CriticalPathMI) { - if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { - SUnit *NextSU = Edge->getSUnit(); - - // Only consider anti-dependence edges. - if (Edge->getKind() == SDep::Anti) { - AntiDepReg = Edge->getReg(); - assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); - if (!AllocatableSet.test(AntiDepReg)) - // Don't break anti-dependencies on non-allocatable registers. - AntiDepReg = 0; - else if (KeepRegs.count(AntiDepReg)) - // Don't break anti-dependencies if an use down below requires - // this exact register. - AntiDepReg = 0; - else { - // If the SUnit has other dependencies on the SUnit that it - // anti-depends on, don't bother breaking the anti-dependency - // since those edges would prevent such units from being - // scheduled past each other regardless. - // - // Also, if there are dependencies on other SUnits with the - // same register as the anti-dependency, don't attempt to - // break it. - for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(), - PE = CriticalPathSU->Preds.end(); P != PE; ++P) - if (P->getSUnit() == NextSU ? - (P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) : - (P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) { - AntiDepReg = 0; - break; - } - } - } - CriticalPathSU = NextSU; - CriticalPathMI = CriticalPathSU->getInstr(); - } else { - // We've reached the end of the critical path. - CriticalPathSU = 0; - CriticalPathMI = 0; - } - } - - PrescanInstruction(MI); - - if (MI->getDesc().hasExtraDefRegAllocReq()) - // If this instruction's defs have special allocation requirement, don't - // break this anti-dependency. - AntiDepReg = 0; - else if (AntiDepReg) { - // If this instruction has a use of AntiDepReg, breaking it - // is invalid. - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); - if (Reg == 0) continue; - if (MO.isUse() && AntiDepReg == Reg) { - AntiDepReg = 0; - break; - } - } - } - - // Determine AntiDepReg's register class, if it is live and is - // consistently used within a single class. - const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; - assert((AntiDepReg == 0 || RC != NULL) && - "Register should be live if it's causing an anti-dependence!"); - if (RC == reinterpret_cast<TargetRegisterClass *>(-1)) - AntiDepReg = 0; - - // Look for a suitable register to use to break the anti-depenence. - // - // TODO: Instead of picking the first free register, consider which might - // be the best. - if (AntiDepReg != 0) { - if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, - LastNewReg[AntiDepReg], - RC)) { - DEBUG(errs() << "Breaking anti-dependence edge on " - << TRI->getName(AntiDepReg) - << " with " << RegRefs.count(AntiDepReg) << " references" - << " using " << TRI->getName(NewReg) << "!\n"); - - // Update the references to the old register to refer to the new - // register. - std::pair<std::multimap<unsigned, MachineOperand *>::iterator, - std::multimap<unsigned, MachineOperand *>::iterator> - Range = RegRefs.equal_range(AntiDepReg); - for (std::multimap<unsigned, MachineOperand *>::iterator - Q = Range.first, QE = Range.second; Q != QE; ++Q) - Q->second->setReg(NewReg); - - // We just went back in time and modified history; the - // liveness information for the anti-depenence reg is now - // inconsistent. Set the state as if it were dead. - Classes[NewReg] = Classes[AntiDepReg]; - DefIndices[NewReg] = DefIndices[AntiDepReg]; - KillIndices[NewReg] = KillIndices[AntiDepReg]; - assert(((KillIndices[NewReg] == ~0u) != - (DefIndices[NewReg] == ~0u)) && - "Kill and Def maps aren't consistent for NewReg!"); - - Classes[AntiDepReg] = 0; - DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; - KillIndices[AntiDepReg] = ~0u; - assert(((KillIndices[AntiDepReg] == ~0u) != - (DefIndices[AntiDepReg] == ~0u)) && - "Kill and Def maps aren't consistent for AntiDepReg!"); - - RegRefs.erase(AntiDepReg); - Changed = true; - LastNewReg[AntiDepReg] = NewReg; - } - } - - ScanInstruction(MI, Count); - } - - return Changed; -} - /// StartBlockForKills - Initialize register live-range state for updating kills /// void SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) { @@ -941,7 +473,7 @@ bool SchedulePostRATDList::ToggleKillFlag(MachineInstr *MI, /// incorrect by instruction reordering. /// void SchedulePostRATDList::FixupKills(MachineBasicBlock *MBB) { - DEBUG(errs() << "Fixup kills for BB ID#" << MBB->getNumber() << '\n'); + DEBUG(errs() << "Fixup kills for BB#" << MBB->getNumber() << '\n'); std::set<unsigned> killedRegs; BitVector ReservedRegs = TRI->getReservedRegs(MF); @@ -1040,7 +572,8 @@ void SchedulePostRATDList::FixupKills(MachineBasicBlock *MBB) { /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to /// the PendingQueue if the count reaches zero. Also update its cycle bound. -void SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) { +void SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge, + bool IgnoreAntiDep) { SUnit *SuccSU = SuccEdge->getSUnit(); #ifndef NDEBUG @@ -1056,7 +589,8 @@ void SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) { // Compute how many cycles it will be before this actually becomes // available. This is the max of the start time of all predecessors plus // their latencies. - SuccSU->setDepthToAtLeast(SU->getDepth() + SuccEdge->getLatency()); + SuccSU->setDepthToAtLeast(SU->getDepth(IgnoreAntiDep) + + SuccEdge->getLatency(), IgnoreAntiDep); // If all the node's predecessors are scheduled, this node is ready // to be scheduled. Ignore the special ExitSU node. @@ -1065,40 +599,73 @@ void SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) { } /// ReleaseSuccessors - Call ReleaseSucc on each of SU's successors. -void SchedulePostRATDList::ReleaseSuccessors(SUnit *SU) { +void SchedulePostRATDList::ReleaseSuccessors(SUnit *SU, bool IgnoreAntiDep) { for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) - ReleaseSucc(SU, &*I); + I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; + ReleaseSucc(SU, &*I, IgnoreAntiDep); + } } /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending /// count of its successors. If a successor pending count is zero, add it to /// the Available queue. -void SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { +void SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle, + bool IgnoreAntiDep) { DEBUG(errs() << "*** Scheduling [" << CurCycle << "]: "); DEBUG(SU->dump(this)); Sequence.push_back(SU); - assert(CurCycle >= SU->getDepth() && "Node scheduled above its depth!"); - SU->setDepthToAtLeast(CurCycle); + assert(CurCycle >= SU->getDepth(IgnoreAntiDep) && + "Node scheduled above its depth!"); + SU->setDepthToAtLeast(CurCycle, IgnoreAntiDep); - ReleaseSuccessors(SU); + ReleaseSuccessors(SU, IgnoreAntiDep); SU->isScheduled = true; AvailableQueue.ScheduledNode(SU); } /// ListScheduleTopDown - The main loop of list scheduling for top-down /// schedulers. -void SchedulePostRATDList::ListScheduleTopDown() { +void SchedulePostRATDList::ListScheduleTopDown( + AntiDepBreaker::CandidateMap *AntiDepCandidates) { unsigned CurCycle = 0; + const bool IgnoreAntiDep = (AntiDepCandidates != NULL); + + // We're scheduling top-down but we're visiting the regions in + // bottom-up order, so we don't know the hazards at the start of a + // region. So assume no hazards (this should usually be ok as most + // blocks are a single region). + HazardRec->Reset(); + + // If ignoring anti-dependencies, the Schedule DAG still has Anti + // dep edges, but we ignore them for scheduling purposes + AvailableQueue.setIgnoreAntiDep(IgnoreAntiDep); // Release any successors of the special Entry node. - ReleaseSuccessors(&EntrySU); + ReleaseSuccessors(&EntrySU, IgnoreAntiDep); - // All leaves to Available queue. + // Add all leaves to Available queue. If ignoring antideps we also + // adjust the predecessor count for each node to not include antidep + // edges. for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { // It is available if it has no predecessors. - if (SUnits[i].Preds.empty()) { + bool available = SUnits[i].Preds.empty(); + // If we are ignoring anti-dependencies then a node that has only + // anti-dep predecessors is available. + if (!available && IgnoreAntiDep) { + available = true; + for (SUnit::const_pred_iterator I = SUnits[i].Preds.begin(), + E = SUnits[i].Preds.end(); I != E; ++I) { + if (I->getKind() != SDep::Anti) { + available = false; + } else { + SUnits[i].NumPredsLeft -= 1; + } + } + } + + if (available) { AvailableQueue.push(&SUnits[i]); SUnits[i].isAvailable = true; } @@ -1117,26 +684,25 @@ void SchedulePostRATDList::ListScheduleTopDown() { // so, add them to the available queue. unsigned MinDepth = ~0u; for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) { - if (PendingQueue[i]->getDepth() <= CurCycle) { + if (PendingQueue[i]->getDepth(IgnoreAntiDep) <= CurCycle) { AvailableQueue.push(PendingQueue[i]); PendingQueue[i]->isAvailable = true; PendingQueue[i] = PendingQueue.back(); PendingQueue.pop_back(); --i; --e; - } else if (PendingQueue[i]->getDepth() < MinDepth) - MinDepth = PendingQueue[i]->getDepth(); + } else if (PendingQueue[i]->getDepth(IgnoreAntiDep) < MinDepth) + MinDepth = PendingQueue[i]->getDepth(IgnoreAntiDep); } DEBUG(errs() << "\n*** Examining Available\n"; LatencyPriorityQueue q = AvailableQueue; while (!q.empty()) { SUnit *su = q.pop(); - errs() << "Height " << su->getHeight() << ": "; + errs() << "Height " << su->getHeight(IgnoreAntiDep) << ": "; su->dump(this); }); SUnit *FoundSUnit = 0; - bool HasNoopHazards = false; while (!AvailableQueue.empty()) { SUnit *CurSUnit = AvailableQueue.pop(); @@ -1160,9 +726,30 @@ void SchedulePostRATDList::ListScheduleTopDown() { NotReady.clear(); } - // If we found a node to schedule, do it now. + // If we found a node to schedule... if (FoundSUnit) { - ScheduleNodeTopDown(FoundSUnit, CurCycle); + // If we are ignoring anti-dependencies and the SUnit we are + // scheduling has an antidep predecessor that has not been + // scheduled, then we will need to break that antidep if we want + // to get this schedule when not ignoring anti-dependencies. + if (IgnoreAntiDep) { + AntiDepBreaker::AntiDepRegVector AntiDepRegs; + for (SUnit::const_pred_iterator I = FoundSUnit->Preds.begin(), + E = FoundSUnit->Preds.end(); I != E; ++I) { + if ((I->getKind() == SDep::Anti) && !I->getSUnit()->isScheduled) + AntiDepRegs.push_back(I->getReg()); + } + + if (AntiDepRegs.size() > 0) { + DEBUG(errs() << "*** AntiDep Candidate: "); + DEBUG(FoundSUnit->dump(this)); + AntiDepCandidates->insert( + AntiDepBreaker::CandidateMap::value_type(FoundSUnit, AntiDepRegs)); + } + } + + // ... schedule the node... + ScheduleNodeTopDown(FoundSUnit, CurCycle, IgnoreAntiDep); HazardRec->EmitInstruction(FoundSUnit); CycleHasInsts = true; diff --git a/lib/CodeGen/PreAllocSplitting.cpp b/lib/CodeGen/PreAllocSplitting.cpp index 726869a..cce5ae8 100644 --- a/lib/CodeGen/PreAllocSplitting.cpp +++ b/lib/CodeGen/PreAllocSplitting.cpp @@ -50,13 +50,14 @@ STATISTIC(NumRenumbers, "Number of intervals renumbered into new registers"); STATISTIC(NumDeadSpills, "Number of dead spills removed"); namespace { - class VISIBILITY_HIDDEN PreAllocSplitting : public MachineFunctionPass { + class PreAllocSplitting : public MachineFunctionPass { MachineFunction *CurrMF; const TargetMachine *TM; const TargetInstrInfo *TII; const TargetRegisterInfo* TRI; MachineFrameInfo *MFI; MachineRegisterInfo *MRI; + SlotIndexes *SIs; LiveIntervals *LIs; LiveStacks *LSs; VirtRegMap *VRM; @@ -68,7 +69,7 @@ namespace { MachineBasicBlock *BarrierMBB; // Barrier - Current barrier index. - LiveIndex BarrierIdx; + SlotIndex BarrierIdx; // CurrLI - Current live interval being split. LiveInterval *CurrLI; @@ -83,16 +84,19 @@ namespace { DenseMap<unsigned, int> IntervalSSMap; // Def2SpillMap - A map from a def instruction index to spill index. - DenseMap<LiveIndex, LiveIndex> Def2SpillMap; + DenseMap<SlotIndex, SlotIndex> Def2SpillMap; public: static char ID; - PreAllocSplitting() : MachineFunctionPass(&ID) {} + PreAllocSplitting() + : MachineFunctionPass(&ID) {} virtual bool runOnMachineFunction(MachineFunction &MF); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addRequired<SlotIndexes>(); + AU.addPreserved<SlotIndexes>(); AU.addRequired<LiveIntervals>(); AU.addPreserved<LiveIntervals>(); AU.addRequired<LiveStacks>(); @@ -129,23 +133,23 @@ namespace { private: MachineBasicBlock::iterator findNextEmptySlot(MachineBasicBlock*, MachineInstr*, - LiveIndex&); + SlotIndex&); MachineBasicBlock::iterator findSpillPoint(MachineBasicBlock*, MachineInstr*, MachineInstr*, - SmallPtrSet<MachineInstr*, 4>&, LiveIndex&); + SmallPtrSet<MachineInstr*, 4>&, SlotIndex&); MachineBasicBlock::iterator - findRestorePoint(MachineBasicBlock*, MachineInstr*, LiveIndex, - SmallPtrSet<MachineInstr*, 4>&, LiveIndex&); + findRestorePoint(MachineBasicBlock*, MachineInstr*, SlotIndex, + SmallPtrSet<MachineInstr*, 4>&, SlotIndex&); int CreateSpillStackSlot(unsigned, const TargetRegisterClass *); bool IsAvailableInStack(MachineBasicBlock*, unsigned, - LiveIndex, LiveIndex, - LiveIndex&, int&) const; + SlotIndex, SlotIndex, + SlotIndex&, int&) const; - void UpdateSpillSlotInterval(VNInfo*, LiveIndex, LiveIndex); + void UpdateSpillSlotInterval(VNInfo*, SlotIndex, SlotIndex); bool SplitRegLiveInterval(LiveInterval*); @@ -157,7 +161,7 @@ namespace { bool Rematerialize(unsigned vreg, VNInfo* ValNo, MachineInstr* DefMI, MachineBasicBlock::iterator RestorePt, - LiveIndex RestoreIdx, + SlotIndex RestoreIdx, SmallPtrSet<MachineInstr*, 4>& RefsInMBB); MachineInstr* FoldSpill(unsigned vreg, const TargetRegisterClass* RC, MachineInstr* DefMI, @@ -209,12 +213,12 @@ const PassInfo *const llvm::PreAllocSplittingID = &X; /// instruction index map. If there isn't one, return end(). MachineBasicBlock::iterator PreAllocSplitting::findNextEmptySlot(MachineBasicBlock *MBB, MachineInstr *MI, - LiveIndex &SpotIndex) { + SlotIndex &SpotIndex) { MachineBasicBlock::iterator MII = MI; if (++MII != MBB->end()) { - LiveIndex Index = + SlotIndex Index = LIs->findGapBeforeInstr(LIs->getInstructionIndex(MII)); - if (Index != LiveIndex()) { + if (Index != SlotIndex()) { SpotIndex = Index; return MII; } @@ -230,7 +234,7 @@ MachineBasicBlock::iterator PreAllocSplitting::findSpillPoint(MachineBasicBlock *MBB, MachineInstr *MI, MachineInstr *DefMI, SmallPtrSet<MachineInstr*, 4> &RefsInMBB, - LiveIndex &SpillIndex) { + SlotIndex &SpillIndex) { MachineBasicBlock::iterator Pt = MBB->begin(); MachineBasicBlock::iterator MII = MI; @@ -243,7 +247,7 @@ PreAllocSplitting::findSpillPoint(MachineBasicBlock *MBB, MachineInstr *MI, if (MII == EndPt || RefsInMBB.count(MII)) return Pt; while (MII != EndPt && !RefsInMBB.count(MII)) { - LiveIndex Index = LIs->getInstructionIndex(MII); + SlotIndex Index = LIs->getInstructionIndex(MII); // We can't insert the spill between the barrier (a call), and its // corresponding call frame setup. @@ -276,9 +280,9 @@ PreAllocSplitting::findSpillPoint(MachineBasicBlock *MBB, MachineInstr *MI, /// found. MachineBasicBlock::iterator PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI, - LiveIndex LastIdx, + SlotIndex LastIdx, SmallPtrSet<MachineInstr*, 4> &RefsInMBB, - LiveIndex &RestoreIndex) { + SlotIndex &RestoreIndex) { // FIXME: Allow spill to be inserted to the beginning of the mbb. Update mbb // begin index accordingly. MachineBasicBlock::iterator Pt = MBB->end(); @@ -299,10 +303,10 @@ PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI, // FIXME: Limit the number of instructions to examine to reduce // compile time? while (MII != EndPt) { - LiveIndex Index = LIs->getInstructionIndex(MII); + SlotIndex Index = LIs->getInstructionIndex(MII); if (Index > LastIdx) break; - LiveIndex Gap = LIs->findGapBeforeInstr(Index); + SlotIndex Gap = LIs->findGapBeforeInstr(Index); // We can't insert a restore between the barrier (a call) and its // corresponding call frame teardown. @@ -311,7 +315,7 @@ PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI, if (MII == EndPt || RefsInMBB.count(MII)) return Pt; ++MII; } while (MII->getOpcode() != TRI->getCallFrameDestroyOpcode()); - } else if (Gap != LiveIndex()) { + } else if (Gap != SlotIndex()) { Pt = MII; RestoreIndex = Gap; } @@ -344,7 +348,7 @@ int PreAllocSplitting::CreateSpillStackSlot(unsigned Reg, if (CurrSLI->hasAtLeastOneValue()) CurrSValNo = CurrSLI->getValNumInfo(0); else - CurrSValNo = CurrSLI->getNextValue(LiveIndex(), 0, false, + CurrSValNo = CurrSLI->getNextValue(SlotIndex(), 0, false, LSs->getVNInfoAllocator()); return SS; } @@ -353,9 +357,9 @@ int PreAllocSplitting::CreateSpillStackSlot(unsigned Reg, /// slot at the specified index. bool PreAllocSplitting::IsAvailableInStack(MachineBasicBlock *DefMBB, - unsigned Reg, LiveIndex DefIndex, - LiveIndex RestoreIndex, - LiveIndex &SpillIndex, + unsigned Reg, SlotIndex DefIndex, + SlotIndex RestoreIndex, + SlotIndex &SpillIndex, int& SS) const { if (!DefMBB) return false; @@ -363,7 +367,7 @@ PreAllocSplitting::IsAvailableInStack(MachineBasicBlock *DefMBB, DenseMap<unsigned, int>::iterator I = IntervalSSMap.find(Reg); if (I == IntervalSSMap.end()) return false; - DenseMap<LiveIndex, LiveIndex>::iterator + DenseMap<SlotIndex, SlotIndex>::iterator II = Def2SpillMap.find(DefIndex); if (II == Def2SpillMap.end()) return false; @@ -384,8 +388,8 @@ PreAllocSplitting::IsAvailableInStack(MachineBasicBlock *DefMBB, /// interval being split, and the spill and restore indicies, update the live /// interval of the spill stack slot. void -PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, LiveIndex SpillIndex, - LiveIndex RestoreIndex) { +PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, SlotIndex SpillIndex, + SlotIndex RestoreIndex) { assert(LIs->getMBBFromIndex(RestoreIndex) == BarrierMBB && "Expect restore in the barrier mbb"); @@ -398,8 +402,8 @@ PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, LiveIndex SpillIndex, } SmallPtrSet<MachineBasicBlock*, 4> Processed; - LiveIndex EndIdx = LIs->getMBBEndIdx(MBB); - LiveRange SLR(SpillIndex, LIs->getNextSlot(EndIdx), CurrSValNo); + SlotIndex EndIdx = LIs->getMBBEndIdx(MBB); + LiveRange SLR(SpillIndex, EndIdx.getNextSlot(), CurrSValNo); CurrSLI->addRange(SLR); Processed.insert(MBB); @@ -418,7 +422,7 @@ PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, LiveIndex SpillIndex, WorkList.pop_back(); if (Processed.count(MBB)) continue; - LiveIndex Idx = LIs->getMBBStartIdx(MBB); + SlotIndex Idx = LIs->getMBBStartIdx(MBB); LR = CurrLI->getLiveRangeContaining(Idx); if (LR && LR->valno == ValNo) { EndIdx = LIs->getMBBEndIdx(MBB); @@ -428,7 +432,7 @@ PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, LiveIndex SpillIndex, CurrSLI->addRange(SLR); } else if (LR->end > EndIdx) { // Live range extends beyond end of mbb, process successors. - LiveRange SLR(Idx, LIs->getNextIndex(EndIdx), CurrSValNo); + LiveRange SLR(Idx, EndIdx.getNextIndex(), CurrSValNo); CurrSLI->addRange(SLR); for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), SE = MBB->succ_end(); SI != SE; ++SI) @@ -491,12 +495,12 @@ PreAllocSplitting::PerformPHIConstruction(MachineBasicBlock::iterator UseI, } // Once we've found it, extend its VNInfo to our instruction. - LiveIndex DefIndex = LIs->getInstructionIndex(Walker); - DefIndex = LIs->getDefIndex(DefIndex); - LiveIndex EndIndex = LIs->getMBBEndIdx(MBB); + SlotIndex DefIndex = LIs->getInstructionIndex(Walker); + DefIndex = DefIndex.getDefIndex(); + SlotIndex EndIndex = LIs->getMBBEndIdx(MBB); RetVNI = NewVNs[Walker]; - LI->addRange(LiveRange(DefIndex, LIs->getNextSlot(EndIndex), RetVNI)); + LI->addRange(LiveRange(DefIndex, EndIndex.getNextSlot(), RetVNI)); } else if (!ContainsDefs && ContainsUses) { SmallPtrSet<MachineInstr*, 2>& BlockUses = Uses[MBB]; @@ -528,12 +532,12 @@ PreAllocSplitting::PerformPHIConstruction(MachineBasicBlock::iterator UseI, IsTopLevel, IsIntraBlock); } - LiveIndex UseIndex = LIs->getInstructionIndex(Walker); - UseIndex = LIs->getUseIndex(UseIndex); - LiveIndex EndIndex; + SlotIndex UseIndex = LIs->getInstructionIndex(Walker); + UseIndex = UseIndex.getUseIndex(); + SlotIndex EndIndex; if (IsIntraBlock) { EndIndex = LIs->getInstructionIndex(UseI); - EndIndex = LIs->getUseIndex(EndIndex); + EndIndex = EndIndex.getUseIndex(); } else EndIndex = LIs->getMBBEndIdx(MBB); @@ -542,7 +546,7 @@ PreAllocSplitting::PerformPHIConstruction(MachineBasicBlock::iterator UseI, RetVNI = PerformPHIConstruction(Walker, MBB, LI, Visited, Defs, Uses, NewVNs, LiveOut, Phis, false, true); - LI->addRange(LiveRange(UseIndex, LIs->getNextSlot(EndIndex), RetVNI)); + LI->addRange(LiveRange(UseIndex, EndIndex.getNextSlot(), RetVNI)); // FIXME: Need to set kills properly for inter-block stuff. if (RetVNI->isKill(UseIndex)) RetVNI->removeKill(UseIndex); @@ -588,13 +592,12 @@ PreAllocSplitting::PerformPHIConstruction(MachineBasicBlock::iterator UseI, IsTopLevel, IsIntraBlock); } - LiveIndex StartIndex = LIs->getInstructionIndex(Walker); - StartIndex = foundDef ? LIs->getDefIndex(StartIndex) : - LIs->getUseIndex(StartIndex); - LiveIndex EndIndex; + SlotIndex StartIndex = LIs->getInstructionIndex(Walker); + StartIndex = foundDef ? StartIndex.getDefIndex() : StartIndex.getUseIndex(); + SlotIndex EndIndex; if (IsIntraBlock) { EndIndex = LIs->getInstructionIndex(UseI); - EndIndex = LIs->getUseIndex(EndIndex); + EndIndex = EndIndex.getUseIndex(); } else EndIndex = LIs->getMBBEndIdx(MBB); @@ -604,7 +607,7 @@ PreAllocSplitting::PerformPHIConstruction(MachineBasicBlock::iterator UseI, RetVNI = PerformPHIConstruction(Walker, MBB, LI, Visited, Defs, Uses, NewVNs, LiveOut, Phis, false, true); - LI->addRange(LiveRange(StartIndex, LIs->getNextSlot(EndIndex), RetVNI)); + LI->addRange(LiveRange(StartIndex, EndIndex.getNextSlot(), RetVNI)); if (foundUse && RetVNI->isKill(StartIndex)) RetVNI->removeKill(StartIndex); @@ -640,9 +643,9 @@ PreAllocSplitting::PerformPHIConstructionFallBack(MachineBasicBlock::iterator Us // assume that we are not intrablock here. if (Phis.count(MBB)) return Phis[MBB]; - LiveIndex StartIndex = LIs->getMBBStartIdx(MBB); + SlotIndex StartIndex = LIs->getMBBStartIdx(MBB); VNInfo *RetVNI = Phis[MBB] = - LI->getNextValue(LiveIndex(), /*FIXME*/ 0, false, + LI->getNextValue(SlotIndex(), /*FIXME*/ 0, false, LIs->getVNInfoAllocator()); if (!IsIntraBlock) LiveOut[MBB] = RetVNI; @@ -685,19 +688,19 @@ PreAllocSplitting::PerformPHIConstructionFallBack(MachineBasicBlock::iterator Us for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator I = IncomingVNs.begin(), E = IncomingVNs.end(); I != E; ++I) { I->second->setHasPHIKill(true); - LiveIndex KillIndex = LIs->getMBBEndIdx(I->first); + SlotIndex KillIndex = LIs->getMBBEndIdx(I->first); if (!I->second->isKill(KillIndex)) I->second->addKill(KillIndex); } } - LiveIndex EndIndex; + SlotIndex EndIndex; if (IsIntraBlock) { EndIndex = LIs->getInstructionIndex(UseI); - EndIndex = LIs->getUseIndex(EndIndex); + EndIndex = EndIndex.getUseIndex(); } else EndIndex = LIs->getMBBEndIdx(MBB); - LI->addRange(LiveRange(StartIndex, LIs->getNextSlot(EndIndex), RetVNI)); + LI->addRange(LiveRange(StartIndex, EndIndex.getNextSlot(), RetVNI)); if (IsIntraBlock) RetVNI->addKill(EndIndex); @@ -733,8 +736,8 @@ void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) { DE = MRI->def_end(); DI != DE; ++DI) { Defs[(*DI).getParent()].insert(&*DI); - LiveIndex DefIdx = LIs->getInstructionIndex(&*DI); - DefIdx = LIs->getDefIndex(DefIdx); + SlotIndex DefIdx = LIs->getInstructionIndex(&*DI); + DefIdx = DefIdx.getDefIndex(); assert(DI->getOpcode() != TargetInstrInfo::PHI && "Following NewVN isPHIDef flag incorrect. Fix me!"); @@ -769,13 +772,13 @@ void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) { // Add ranges for dead defs for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(LI->reg), DE = MRI->def_end(); DI != DE; ++DI) { - LiveIndex DefIdx = LIs->getInstructionIndex(&*DI); - DefIdx = LIs->getDefIndex(DefIdx); + SlotIndex DefIdx = LIs->getInstructionIndex(&*DI); + DefIdx = DefIdx.getDefIndex(); if (LI->liveAt(DefIdx)) continue; VNInfo* DeadVN = NewVNs[&*DI]; - LI->addRange(LiveRange(DefIdx, LIs->getNextSlot(DefIdx), DeadVN)); + LI->addRange(LiveRange(DefIdx, DefIdx.getNextSlot(), DeadVN)); DeadVN->addKill(DefIdx); } @@ -784,8 +787,8 @@ void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) { VI != VE; ++VI) { VNInfo* VNI = *VI; for (unsigned i = 0, e = VNI->kills.size(); i != e; ++i) { - LiveIndex KillIdx = VNI->kills[i]; - if (KillIdx.isPHIIndex()) + SlotIndex KillIdx = VNI->kills[i]; + if (KillIdx.isPHI()) continue; MachineInstr *KillMI = LIs->getInstructionFromIndex(KillIdx); if (KillMI) { @@ -826,14 +829,14 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) { // Locate two-address redefinitions for (VNInfo::KillSet::iterator KI = OldVN->kills.begin(), KE = OldVN->kills.end(); KI != KE; ++KI) { - assert(!KI->isPHIIndex() && + assert(!KI->isPHI() && "VN previously reported having no PHI kills."); MachineInstr* MI = LIs->getInstructionFromIndex(*KI); unsigned DefIdx = MI->findRegisterDefOperandIdx(CurrLI->reg); if (DefIdx == ~0U) continue; if (MI->isRegTiedToUseOperand(DefIdx)) { VNInfo* NextVN = - CurrLI->findDefinedVNInfoForRegInt(LIs->getDefIndex(*KI)); + CurrLI->findDefinedVNInfoForRegInt(KI->getDefIndex()); if (NextVN == OldVN) continue; Stack.push_back(NextVN); } @@ -865,10 +868,10 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) { for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(CurrLI->reg), E = MRI->reg_end(); I != E; ++I) { MachineOperand& MO = I.getOperand(); - LiveIndex InstrIdx = LIs->getInstructionIndex(&*I); + SlotIndex InstrIdx = LIs->getInstructionIndex(&*I); - if ((MO.isUse() && NewLI.liveAt(LIs->getUseIndex(InstrIdx))) || - (MO.isDef() && NewLI.liveAt(LIs->getDefIndex(InstrIdx)))) + if ((MO.isUse() && NewLI.liveAt(InstrIdx.getUseIndex())) || + (MO.isDef() && NewLI.liveAt(InstrIdx.getDefIndex()))) OpsToChange.push_back(std::make_pair(&*I, I.getOperandNo())); } @@ -893,12 +896,12 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) { bool PreAllocSplitting::Rematerialize(unsigned VReg, VNInfo* ValNo, MachineInstr* DefMI, MachineBasicBlock::iterator RestorePt, - LiveIndex RestoreIdx, + SlotIndex RestoreIdx, SmallPtrSet<MachineInstr*, 4>& RefsInMBB) { MachineBasicBlock& MBB = *RestorePt->getParent(); MachineBasicBlock::iterator KillPt = BarrierMBB->end(); - LiveIndex KillIdx; + SlotIndex KillIdx; if (!ValNo->isDefAccurate() || DefMI->getParent() == BarrierMBB) KillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, KillIdx); else @@ -911,8 +914,8 @@ bool PreAllocSplitting::Rematerialize(unsigned VReg, VNInfo* ValNo, LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); ReconstructLiveInterval(CurrLI); - LiveIndex RematIdx = LIs->getInstructionIndex(prior(RestorePt)); - RematIdx = LIs->getDefIndex(RematIdx); + SlotIndex RematIdx = LIs->getInstructionIndex(prior(RestorePt)); + RematIdx = RematIdx.getDefIndex(); RenumberValno(CurrLI->findDefinedVNInfoForRegInt(RematIdx)); ++NumSplits; @@ -968,7 +971,7 @@ MachineInstr* PreAllocSplitting::FoldSpill(unsigned vreg, if (CurrSLI->hasAtLeastOneValue()) CurrSValNo = CurrSLI->getValNumInfo(0); else - CurrSValNo = CurrSLI->getNextValue(LiveIndex(), 0, false, + CurrSValNo = CurrSLI->getNextValue(SlotIndex(), 0, false, LSs->getVNInfoAllocator()); } @@ -1052,11 +1055,14 @@ MachineInstr* PreAllocSplitting::FoldRestore(unsigned vreg, /// so it would not cross the barrier that's being processed. Shrink wrap /// (minimize) the live interval to the last uses. bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { + DEBUG(errs() << "Pre-alloc splitting " << LI->reg << " for " << *Barrier + << " result: "); + CurrLI = LI; // Find live range where current interval cross the barrier. LiveInterval::iterator LR = - CurrLI->FindLiveRangeContaining(LIs->getUseIndex(BarrierIdx)); + CurrLI->FindLiveRangeContaining(BarrierIdx.getUseIndex()); VNInfo *ValNo = LR->valno; assert(!ValNo->isUnused() && "Val# is defined by a dead def?"); @@ -1065,8 +1071,10 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { ? LIs->getInstructionFromIndex(ValNo->def) : NULL; // If this would create a new join point, do not split. - if (DefMI && createsNewJoin(LR, DefMI->getParent(), Barrier->getParent())) + if (DefMI && createsNewJoin(LR, DefMI->getParent(), Barrier->getParent())) { + DEBUG(errs() << "FAILED (would create a new join point).\n"); return false; + } // Find all references in the barrier mbb. SmallPtrSet<MachineInstr*, 4> RefsInMBB; @@ -1078,21 +1086,25 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { } // Find a point to restore the value after the barrier. - LiveIndex RestoreIndex; + SlotIndex RestoreIndex; MachineBasicBlock::iterator RestorePt = findRestorePoint(BarrierMBB, Barrier, LR->end, RefsInMBB, RestoreIndex); - if (RestorePt == BarrierMBB->end()) + if (RestorePt == BarrierMBB->end()) { + DEBUG(errs() << "FAILED (could not find a suitable restore point).\n"); return false; + } if (DefMI && LIs->isReMaterializable(*LI, ValNo, DefMI)) if (Rematerialize(LI->reg, ValNo, DefMI, RestorePt, - RestoreIndex, RefsInMBB)) - return true; + RestoreIndex, RefsInMBB)) { + DEBUG(errs() << "success (remat).\n"); + return true; + } // Add a spill either before the barrier or after the definition. MachineBasicBlock *DefMBB = DefMI ? DefMI->getParent() : NULL; const TargetRegisterClass *RC = MRI->getRegClass(CurrLI->reg); - LiveIndex SpillIndex; + SlotIndex SpillIndex; MachineInstr *SpillMI = NULL; int SS = -1; if (!ValNo->isDefAccurate()) { @@ -1103,8 +1115,10 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { } else { MachineBasicBlock::iterator SpillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, SpillIndex); - if (SpillPt == BarrierMBB->begin()) + if (SpillPt == BarrierMBB->begin()) { + DEBUG(errs() << "FAILED (could not find a suitable spill point).\n"); return false; // No gap to insert spill. + } // Add spill. SS = CreateSpillStackSlot(CurrLI->reg, RC); @@ -1116,8 +1130,10 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { RestoreIndex, SpillIndex, SS)) { // If it's already split, just restore the value. There is no need to spill // the def again. - if (!DefMI) + if (!DefMI) { + DEBUG(errs() << "FAILED (def is dead).\n"); return false; // Def is dead. Do nothing. + } if ((SpillMI = FoldSpill(LI->reg, RC, DefMI, Barrier, BarrierMBB, SS, RefsInMBB))) { @@ -1129,12 +1145,16 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { // Add spill after the def and the last use before the barrier. SpillPt = findSpillPoint(BarrierMBB, Barrier, DefMI, RefsInMBB, SpillIndex); - if (SpillPt == DefMBB->begin()) + if (SpillPt == DefMBB->begin()) { + DEBUG(errs() << "FAILED (could not find a suitable spill point).\n"); return false; // No gap to insert spill. + } } else { SpillPt = findNextEmptySlot(DefMBB, DefMI, SpillIndex); - if (SpillPt == DefMBB->end()) + if (SpillPt == DefMBB->end()) { + DEBUG(errs() << "FAILED (could not find a suitable spill point).\n"); return false; // No gap to insert spill. + } } // Add spill. SS = CreateSpillStackSlot(CurrLI->reg, RC); @@ -1162,18 +1182,19 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { } // Update spill stack slot live interval. - UpdateSpillSlotInterval(ValNo, LIs->getNextSlot(LIs->getUseIndex(SpillIndex)), - LIs->getDefIndex(RestoreIndex)); + UpdateSpillSlotInterval(ValNo, SpillIndex.getUseIndex().getNextSlot(), + RestoreIndex.getDefIndex()); ReconstructLiveInterval(CurrLI); if (!FoldedRestore) { - LiveIndex RestoreIdx = LIs->getInstructionIndex(prior(RestorePt)); - RestoreIdx = LIs->getDefIndex(RestoreIdx); + SlotIndex RestoreIdx = LIs->getInstructionIndex(prior(RestorePt)); + RestoreIdx = RestoreIdx.getDefIndex(); RenumberValno(CurrLI->findDefinedVNInfoForRegInt(RestoreIdx)); } ++NumSplits; + DEBUG(errs() << "success.\n"); return true; } @@ -1254,8 +1275,8 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet<LiveInterval*, 8>& split) { // reaching definition (VNInfo). for (MachineRegisterInfo::use_iterator UI = MRI->use_begin((*LI)->reg), UE = MRI->use_end(); UI != UE; ++UI) { - LiveIndex index = LIs->getInstructionIndex(&*UI); - index = LIs->getUseIndex(index); + SlotIndex index = LIs->getInstructionIndex(&*UI); + index = index.getUseIndex(); const LiveRange* LR = (*LI)->getLiveRangeContaining(index); VNUseCount[LR->valno].insert(&*UI); @@ -1404,7 +1425,7 @@ bool PreAllocSplitting::createsNewJoin(LiveRange* LR, if (LR->valno->hasPHIKill()) return false; - LiveIndex MBBEnd = LIs->getMBBEndIdx(BarrierMBB); + SlotIndex MBBEnd = LIs->getMBBEndIdx(BarrierMBB); if (LR->end < MBBEnd) return false; @@ -1467,6 +1488,7 @@ bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) { TII = TM->getInstrInfo(); MFI = MF.getFrameInfo(); MRI = &MF.getRegInfo(); + SIs = &getAnalysis<SlotIndexes>(); LIs = &getAnalysis<LiveIntervals>(); LSs = &getAnalysis<LiveStacks>(); VRM = &getAnalysis<VirtRegMap>(); diff --git a/lib/CodeGen/ProcessImplicitDefs.cpp b/lib/CodeGen/ProcessImplicitDefs.cpp new file mode 100644 index 0000000..48567a0 --- /dev/null +++ b/lib/CodeGen/ProcessImplicitDefs.cpp @@ -0,0 +1,231 @@ +//===---------------------- ProcessImplicitDefs.cpp -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "processimplicitdefs" + +#include "llvm/CodeGen/ProcessImplicitDefs.h" + +#include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/CodeGen/LiveVariables.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Support/Debug.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" + + +using namespace llvm; + +char ProcessImplicitDefs::ID = 0; +static RegisterPass<ProcessImplicitDefs> X("processimpdefs", + "Process Implicit Definitions."); + +void ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + AU.addPreserved<AliasAnalysis>(); + AU.addPreserved<LiveVariables>(); + AU.addRequired<LiveVariables>(); + AU.addPreservedID(MachineLoopInfoID); + AU.addPreservedID(MachineDominatorsID); + AU.addPreservedID(TwoAddressInstructionPassID); + AU.addPreservedID(PHIEliminationID); + MachineFunctionPass::getAnalysisUsage(AU); +} + +bool ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI, + unsigned Reg, unsigned OpIdx, + const TargetInstrInfo *tii_) { + unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; + if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && + Reg == SrcReg) + return true; + + if (OpIdx == 2 && MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) + return true; + if (OpIdx == 1 && MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) + return true; + return false; +} + +/// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure +/// there is one implicit_def for each use. Add isUndef marker to +/// implicit_def defs and their uses. +bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { + + DEBUG(errs() << "********** PROCESS IMPLICIT DEFS **********\n" + << "********** Function: " + << ((Value*)fn.getFunction())->getName() << '\n'); + + bool Changed = false; + + const TargetInstrInfo *tii_ = fn.getTarget().getInstrInfo(); + const TargetRegisterInfo *tri_ = fn.getTarget().getRegisterInfo(); + MachineRegisterInfo *mri_ = &fn.getRegInfo(); + + LiveVariables *lv_ = &getAnalysis<LiveVariables>(); + + SmallSet<unsigned, 8> ImpDefRegs; + SmallVector<MachineInstr*, 8> ImpDefMIs; + MachineBasicBlock *Entry = fn.begin(); + SmallPtrSet<MachineBasicBlock*,16> Visited; + + for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> > + DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited); + DFI != E; ++DFI) { + MachineBasicBlock *MBB = *DFI; + for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); + I != E; ) { + MachineInstr *MI = &*I; + ++I; + if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) { + unsigned Reg = MI->getOperand(0).getReg(); + ImpDefRegs.insert(Reg); + if (TargetRegisterInfo::isPhysicalRegister(Reg)) { + for (const unsigned *SS = tri_->getSubRegisters(Reg); *SS; ++SS) + ImpDefRegs.insert(*SS); + } + ImpDefMIs.push_back(MI); + continue; + } + + if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { + MachineOperand &MO = MI->getOperand(2); + if (ImpDefRegs.count(MO.getReg())) { + // %reg1032<def> = INSERT_SUBREG %reg1032, undef, 2 + // This is an identity copy, eliminate it now. + if (MO.isKill()) { + LiveVariables::VarInfo& vi = lv_->getVarInfo(MO.getReg()); + vi.removeKill(MI); + } + MI->eraseFromParent(); + Changed = true; + continue; + } + } + + bool ChangedToImpDef = false; + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand& MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isUse() || MO.isUndef()) + continue; + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + if (!ImpDefRegs.count(Reg)) + continue; + // Use is a copy, just turn it into an implicit_def. + if (CanTurnIntoImplicitDef(MI, Reg, i, tii_)) { + bool isKill = MO.isKill(); + MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF)); + for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j) + MI->RemoveOperand(j); + if (isKill) { + ImpDefRegs.erase(Reg); + LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg); + vi.removeKill(MI); + } + ChangedToImpDef = true; + Changed = true; + break; + } + + Changed = true; + MO.setIsUndef(); + if (MO.isKill() || MI->isRegTiedToDefOperand(i)) { + // Make sure other uses of + for (unsigned j = i+1; j != e; ++j) { + MachineOperand &MOJ = MI->getOperand(j); + if (MOJ.isReg() && MOJ.isUse() && MOJ.getReg() == Reg) + MOJ.setIsUndef(); + } + ImpDefRegs.erase(Reg); + } + } + + if (ChangedToImpDef) { + // Backtrack to process this new implicit_def. + --I; + } else { + for (unsigned i = 0; i != MI->getNumOperands(); ++i) { + MachineOperand& MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) + continue; + ImpDefRegs.erase(MO.getReg()); + } + } + } + + // Any outstanding liveout implicit_def's? + for (unsigned i = 0, e = ImpDefMIs.size(); i != e; ++i) { + MachineInstr *MI = ImpDefMIs[i]; + unsigned Reg = MI->getOperand(0).getReg(); + if (TargetRegisterInfo::isPhysicalRegister(Reg) || + !ImpDefRegs.count(Reg)) { + // Delete all "local" implicit_def's. That include those which define + // physical registers since they cannot be liveout. + MI->eraseFromParent(); + Changed = true; + continue; + } + + // If there are multiple defs of the same register and at least one + // is not an implicit_def, do not insert implicit_def's before the + // uses. + bool Skip = false; + for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg), + DE = mri_->def_end(); DI != DE; ++DI) { + if (DI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) { + Skip = true; + break; + } + } + if (Skip) + continue; + + // The only implicit_def which we want to keep are those that are live + // out of its block. + MI->eraseFromParent(); + Changed = true; + + for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg), + UE = mri_->use_end(); UI != UE; ) { + MachineOperand &RMO = UI.getOperand(); + MachineInstr *RMI = &*UI; + ++UI; + MachineBasicBlock *RMBB = RMI->getParent(); + if (RMBB == MBB) + continue; + + // Turn a copy use into an implicit_def. + unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; + if (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) && + Reg == SrcReg) { + RMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF)); + for (int j = RMI->getNumOperands() - 1, ee = 0; j > ee; --j) + RMI->RemoveOperand(j); + continue; + } + + const TargetRegisterClass* RC = mri_->getRegClass(Reg); + unsigned NewVReg = mri_->createVirtualRegister(RC); + RMO.setReg(NewVReg); + RMO.setIsUndef(); + RMO.setIsKill(); + } + } + ImpDefRegs.clear(); + ImpDefMIs.clear(); + } + + return Changed; +} + diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index a0860a1..230a20c 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -542,7 +542,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // Make sure the special register scavenging spill slot is closest to the // frame pointer if a frame pointer is required. const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); - if (RS && RegInfo->hasFP(Fn)) { + if (RS && RegInfo->hasFP(Fn) && !RegInfo->needsStackRealignment(Fn)) { int SFI = RS->getScavengingFrameIndex(); if (SFI >= 0) AdjustStackOffset(FFI, SFI, StackGrowsDown, Offset, MaxAlign); @@ -571,7 +571,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // Make sure the special register scavenging spill slot is closest to the // stack pointer. - if (RS && !RegInfo->hasFP(Fn)) { + if (RS && (!RegInfo->hasFP(Fn) || RegInfo->needsStackRealignment(Fn))) { int SFI = RS->getScavengingFrameIndex(); if (SFI >= 0) AdjustStackOffset(FFI, SFI, StackGrowsDown, Offset, MaxAlign); diff --git a/lib/CodeGen/PseudoSourceValue.cpp b/lib/CodeGen/PseudoSourceValue.cpp index 70e8640..5507646 100644 --- a/lib/CodeGen/PseudoSourceValue.cpp +++ b/lib/CodeGen/PseudoSourceValue.cpp @@ -14,7 +14,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/DerivedTypes.h" -#include "llvm/Support/Compiler.h" +#include "llvm/LLVMContext.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" @@ -55,8 +55,7 @@ namespace { /// FixedStackPseudoSourceValue - A specialized PseudoSourceValue /// for holding FixedStack values, which must include a frame /// index. - class VISIBILITY_HIDDEN FixedStackPseudoSourceValue - : public PseudoSourceValue { + class FixedStackPseudoSourceValue : public PseudoSourceValue { const int FI; public: explicit FixedStackPseudoSourceValue(int fi) : FI(fi) {} @@ -65,6 +64,8 @@ namespace { virtual bool isAliased(const MachineFrameInfo *MFI) const; + virtual bool mayAlias(const MachineFrameInfo *) const; + virtual void printCustom(raw_ostream &OS) const { OS << "FixedStack" << FI; } @@ -101,6 +102,14 @@ bool PseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const { return true; } +bool PseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const { + if (this == getGOT() || + this == getConstantPool() || + this == getJumpTable()) + return false; + return true; +} + bool FixedStackPseudoSourceValue::isConstant(const MachineFrameInfo *MFI) const{ return MFI && MFI->isImmutableObjectIndex(FI); } @@ -114,3 +123,10 @@ bool FixedStackPseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const { // Spill slots should not alias others. return !MFI->isFixedObjectIndex(FI) && !MFI->isSpillSlotObjectIndex(FI); } + +bool FixedStackPseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const { + if (!MFI) + return true; + // Spill slots will not alias any LLVM IR value. + return !MFI->isSpillSlotObjectIndex(FI); +} diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index 5d58ea9..6930abf 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -33,7 +33,6 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -70,7 +69,7 @@ linearscanRegAlloc("linearscan", "linear scan register allocator", createLinearScanRegisterAllocator); namespace { - struct VISIBILITY_HIDDEN RALinScan : public MachineFunctionPass { + struct RALinScan : public MachineFunctionPass { static char ID; RALinScan() : MachineFunctionPass(&ID) {} @@ -146,6 +145,7 @@ namespace { virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired<LiveIntervals>(); + AU.addPreserved<SlotIndexes>(); if (StrongPHIElim) AU.addRequiredID(StrongPHIEliminationID); // Make sure PassManager knows which analyses to make available @@ -176,11 +176,11 @@ namespace { /// processActiveIntervals - expire old intervals and move non-overlapping /// ones to the inactive list. - void processActiveIntervals(LiveIndex CurPoint); + void processActiveIntervals(SlotIndex CurPoint); /// processInactiveIntervals - expire old intervals and move overlapping /// ones to the active list. - void processInactiveIntervals(LiveIndex CurPoint); + void processInactiveIntervals(SlotIndex CurPoint); /// hasNextReloadInterval - Return the next liveinterval that's being /// defined by a reload from the same SS as the specified one. @@ -366,7 +366,7 @@ unsigned RALinScan::attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg) { return Reg; VNInfo *vni = cur.begin()->valno; - if ((vni->def == LiveIndex()) || + if ((vni->def == SlotIndex()) || vni->isUnused() || !vni->isDefAccurate()) return Reg; MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def); @@ -403,7 +403,7 @@ unsigned RALinScan::attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg) { if (!O.isKill()) continue; MachineInstr *MI = &*I; - if (SrcLI.liveAt(li_->getDefIndex(li_->getInstructionIndex(MI)))) + if (SrcLI.liveAt(li_->getInstructionIndex(MI).getDefIndex())) O.setIsKill(false); } } @@ -480,10 +480,17 @@ void RALinScan::initIntervalSets() for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i) { if (TargetRegisterInfo::isPhysicalRegister(i->second->reg)) { - mri_->setPhysRegUsed(i->second->reg); - fixed_.push_back(std::make_pair(i->second, i->second->begin())); - } else - unhandled_.push(i->second); + if (!i->second->empty()) { + mri_->setPhysRegUsed(i->second->reg); + fixed_.push_back(std::make_pair(i->second, i->second->begin())); + } + } else { + if (i->second->empty()) { + assignRegOrStackSlotAtInterval(i->second); + } + else + unhandled_.push(i->second); + } } } @@ -503,13 +510,13 @@ void RALinScan::linearScan() { ++NumIters; DEBUG(errs() << "\n*** CURRENT ***: " << *cur << '\n'); - if (!cur->empty()) { - processActiveIntervals(cur->beginIndex()); - processInactiveIntervals(cur->beginIndex()); + assert(!cur->empty() && "Empty interval in unhandled set."); - assert(TargetRegisterInfo::isVirtualRegister(cur->reg) && - "Can only allocate virtual registers!"); - } + processActiveIntervals(cur->beginIndex()); + processInactiveIntervals(cur->beginIndex()); + + assert(TargetRegisterInfo::isVirtualRegister(cur->reg) && + "Can only allocate virtual registers!"); // Allocating a virtual register. try to find a free // physical register or spill an interval (possibly this one) in order to @@ -586,7 +593,7 @@ void RALinScan::linearScan() { /// processActiveIntervals - expire old intervals and move non-overlapping ones /// to the inactive list. -void RALinScan::processActiveIntervals(LiveIndex CurPoint) +void RALinScan::processActiveIntervals(SlotIndex CurPoint) { DEBUG(errs() << "\tprocessing active intervals:\n"); @@ -632,7 +639,7 @@ void RALinScan::processActiveIntervals(LiveIndex CurPoint) /// processInactiveIntervals - expire old intervals and move overlapping /// ones to the active list. -void RALinScan::processInactiveIntervals(LiveIndex CurPoint) +void RALinScan::processInactiveIntervals(SlotIndex CurPoint) { DEBUG(errs() << "\tprocessing inactive intervals:\n"); @@ -713,7 +720,7 @@ FindIntervalInVector(RALinScan::IntervalPtrs &IP, LiveInterval *LI) { return IP.end(); } -static void RevertVectorIteratorsTo(RALinScan::IntervalPtrs &V, LiveIndex Point){ +static void RevertVectorIteratorsTo(RALinScan::IntervalPtrs &V, SlotIndex Point){ for (unsigned i = 0, e = V.size(); i != e; ++i) { RALinScan::IntervalPtr &IP = V[i]; LiveInterval::iterator I = std::upper_bound(IP.first->begin(), @@ -739,7 +746,7 @@ static void addStackInterval(LiveInterval *cur, LiveStacks *ls_, if (SI.hasAtLeastOneValue()) VNI = SI.getValNumInfo(0); else - VNI = SI.getNextValue(LiveIndex(), 0, false, + VNI = SI.getNextValue(SlotIndex(), 0, false, ls_->getVNInfoAllocator()); LiveInterval &RI = li_->getInterval(cur->reg); @@ -907,7 +914,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) { backUpRegUses(); std::vector<std::pair<unsigned, float> > SpillWeightsToAdd; - LiveIndex StartPosition = cur->beginIndex(); + SlotIndex StartPosition = cur->beginIndex(); const TargetRegisterClass *RCLeader = RelatedRegClasses.getLeaderValue(RC); // If start of this live interval is defined by a move instruction and its @@ -917,7 +924,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) { // one, e.g. X86::mov32to32_. These move instructions are not coalescable. if (!vrm_->getRegAllocPref(cur->reg) && cur->hasAtLeastOneValue()) { VNInfo *vni = cur->begin()->valno; - if ((vni->def != LiveIndex()) && !vni->isUnused() && + if ((vni->def != SlotIndex()) && !vni->isUnused() && vni->isDefAccurate()) { MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def); unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; @@ -1119,6 +1126,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) { DowngradedRegs.clear(); assignRegOrStackSlotAtInterval(cur); } else { + assert(false && "Ran out of registers during register allocation!"); llvm_report_error("Ran out of registers during register allocation!"); } return; @@ -1173,7 +1181,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) { LiveInterval *ReloadLi = added[i]; if (ReloadLi->weight == HUGE_VALF && li_->getApproximateInstructionCount(*ReloadLi) == 0) { - LiveIndex ReloadIdx = ReloadLi->beginIndex(); + SlotIndex ReloadIdx = ReloadLi->beginIndex(); MachineBasicBlock *ReloadMBB = li_->getMBBFromIndex(ReloadIdx); int ReloadSS = vrm_->getStackSlot(ReloadLi->reg); if (LastReloadMBB == ReloadMBB && LastReloadSS == ReloadSS) { @@ -1243,7 +1251,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) { spilled.insert(sli->reg); } - LiveIndex earliestStart = earliestStartInterval->beginIndex(); + SlotIndex earliestStart = earliestStartInterval->beginIndex(); DEBUG(errs() << "\t\trolling back to: " << earliestStart << '\n'); @@ -1324,7 +1332,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) { LiveInterval *ReloadLi = added[i]; if (ReloadLi->weight == HUGE_VALF && li_->getApproximateInstructionCount(*ReloadLi) == 0) { - LiveIndex ReloadIdx = ReloadLi->beginIndex(); + SlotIndex ReloadIdx = ReloadLi->beginIndex(); MachineBasicBlock *ReloadMBB = li_->getMBBFromIndex(ReloadIdx); int ReloadSS = vrm_->getStackSlot(ReloadLi->reg); if (LastReloadMBB == ReloadMBB && LastReloadSS == ReloadSS) { diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp index 28ede55..1957c16 100644 --- a/lib/CodeGen/RegAllocLocal.cpp +++ b/lib/CodeGen/RegAllocLocal.cpp @@ -24,7 +24,6 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/DenseMap.h" @@ -44,7 +43,7 @@ static RegisterRegAlloc createLocalRegisterAllocator); namespace { - class VISIBILITY_HIDDEN RALocal : public MachineFunctionPass { + class RALocal : public MachineFunctionPass { public: static char ID; RALocal() : MachineFunctionPass(&ID), StackSlotForVirtReg(-1) {} diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp index bee5d93..5757e47 100644 --- a/lib/CodeGen/RegAllocPBQP.cpp +++ b/lib/CodeGen/RegAllocPBQP.cpp @@ -70,7 +70,7 @@ namespace { /// PBQP based allocators solve the register allocation problem by mapping /// register allocation problems to Partitioned Boolean Quadratic /// Programming problems. - class VISIBILITY_HIDDEN PBQPRegAlloc : public MachineFunctionPass { + class PBQPRegAlloc : public MachineFunctionPass { public: static char ID; @@ -85,6 +85,8 @@ namespace { /// PBQP analysis usage. virtual void getAnalysisUsage(AnalysisUsage &au) const { + au.addRequired<SlotIndexes>(); + au.addPreserved<SlotIndexes>(); au.addRequired<LiveIntervals>(); //au.addRequiredID(SplitCriticalEdgesID); au.addRequired<RegisterCoalescer>(); @@ -684,7 +686,7 @@ void PBQPRegAlloc::addStackInterval(const LiveInterval *spilled, vni = stackInterval.getValNumInfo(0); else vni = stackInterval.getNextValue( - LiveIndex(), 0, false, lss->getVNInfoAllocator()); + SlotIndex(), 0, false, lss->getVNInfoAllocator()); LiveInterval &rhsInterval = lis->getInterval(spilled->reg); stackInterval.MergeRangesInAsValue(rhsInterval, vni); @@ -832,7 +834,7 @@ bool PBQPRegAlloc::runOnMachineFunction(MachineFunction &MF) { tm = &mf->getTarget(); tri = tm->getRegisterInfo(); tii = tm->getInstrInfo(); - mri = &mf->getRegInfo(); + mri = &mf->getRegInfo(); lis = &getAnalysis<LiveIntervals>(); lss = &getAnalysis<LiveStacks>(); diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index 2518ce1..cf90aba 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -177,7 +177,24 @@ void RegScavenger::forward() { if (!Reg || isReserved(Reg)) continue; if (MO.isUse()) { - assert(isUsed(Reg) && "Using an undefined register!"); + if (!isUsed(Reg)) { + // Check if it's partial live: e.g. + // D0 = insert_subreg D0<undef>, S0 + // ... D0 + // The problem is the insert_subreg could be eliminated. The use of + // D0 is using a partially undef value. This is not *incorrect* since + // S1 is can be freely clobbered. + // Ideally we would like a way to model this, but leaving the + // insert_subreg around causes both correctness and performance issues. + bool SubUsed = false; + for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); + unsigned SubReg = *SubRegs; ++SubRegs) + if (isUsed(SubReg)) { + SubUsed = true; + break; + } + assert(SubUsed && "Using an undefined register!"); + } assert((!EarlyClobberRegs.test(Reg) || MI->isRegTiedToDefOperand(i)) && "Using an early clobbered register!"); } else { @@ -227,7 +244,7 @@ unsigned RegScavenger::FindUnusedReg(const TargetRegisterClass *RC) const { /// /// No more than InstrLimit instructions are inspected. /// -unsigned RegScavenger::findSurvivorReg(MachineBasicBlock::iterator MI, +unsigned RegScavenger::findSurvivorReg(MachineBasicBlock::iterator StartMI, BitVector &Candidates, unsigned InstrLimit, MachineBasicBlock::iterator &UseMI) { @@ -235,19 +252,37 @@ unsigned RegScavenger::findSurvivorReg(MachineBasicBlock::iterator MI, assert(Survivor > 0 && "No candidates for scavenging"); MachineBasicBlock::iterator ME = MBB->getFirstTerminator(); - assert(MI != ME && "MI already at terminator"); + assert(StartMI != ME && "MI already at terminator"); + MachineBasicBlock::iterator RestorePointMI = StartMI; + MachineBasicBlock::iterator MI = StartMI; + bool inVirtLiveRange = false; for (++MI; InstrLimit > 0 && MI != ME; ++MI, --InstrLimit) { + bool isVirtKillInsn = false; + bool isVirtDefInsn = false; // Remove any candidates touched by instruction. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg() || MO.isUndef() || !MO.getReg() || - TargetRegisterInfo::isVirtualRegister(MO.getReg())) + if (!MO.isReg() || MO.isUndef() || !MO.getReg()) continue; + if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) { + if (MO.isDef()) + isVirtDefInsn = true; + else if (MO.isKill()) + isVirtKillInsn = true; + continue; + } Candidates.reset(MO.getReg()); for (const unsigned *R = TRI->getAliasSet(MO.getReg()); *R; R++) Candidates.reset(*R); } + // If we're not in a virtual reg's live range, this is a valid + // restore point. + if (!inVirtLiveRange) RestorePointMI = MI; + + // Update whether we're in the live range of a virtual register + if (isVirtKillInsn) inVirtLiveRange = false; + if (isVirtDefInsn) inVirtLiveRange = true; // Was our survivor untouched by this instruction? if (Candidates.test(Survivor)) @@ -259,9 +294,13 @@ unsigned RegScavenger::findSurvivorReg(MachineBasicBlock::iterator MI, Survivor = Candidates.find_first(); } + // If we ran off the end, that's where we want to restore. + if (MI == ME) RestorePointMI = ME; + assert (RestorePointMI != StartMI && + "No available scavenger restore location!"); // We ran out of candidates, so stop the search. - UseMI = MI; + UseMI = RestorePointMI; return Survivor; } diff --git a/lib/CodeGen/ScheduleDAG.cpp b/lib/CodeGen/ScheduleDAG.cpp index 5a59862..1363a92 100644 --- a/lib/CodeGen/ScheduleDAG.cpp +++ b/lib/CodeGen/ScheduleDAG.cpp @@ -183,8 +183,8 @@ void SUnit::setHeightDirty() { /// setDepthToAtLeast - Update this node's successors to reflect the /// fact that this node's depth just increased. /// -void SUnit::setDepthToAtLeast(unsigned NewDepth) { - if (NewDepth <= getDepth()) +void SUnit::setDepthToAtLeast(unsigned NewDepth, bool IgnoreAntiDep) { + if (NewDepth <= getDepth(IgnoreAntiDep)) return; setDepthDirty(); Depth = NewDepth; @@ -194,8 +194,8 @@ void SUnit::setDepthToAtLeast(unsigned NewDepth) { /// setHeightToAtLeast - Update this node's predecessors to reflect the /// fact that this node's height just increased. /// -void SUnit::setHeightToAtLeast(unsigned NewHeight) { - if (NewHeight <= getHeight()) +void SUnit::setHeightToAtLeast(unsigned NewHeight, bool IgnoreAntiDep) { + if (NewHeight <= getHeight(IgnoreAntiDep)) return; setHeightDirty(); Height = NewHeight; @@ -204,7 +204,7 @@ void SUnit::setHeightToAtLeast(unsigned NewHeight) { /// ComputeDepth - Calculate the maximal path from the node to the exit. /// -void SUnit::ComputeDepth() { +void SUnit::ComputeDepth(bool IgnoreAntiDep) { SmallVector<SUnit*, 8> WorkList; WorkList.push_back(this); do { @@ -214,6 +214,7 @@ void SUnit::ComputeDepth() { unsigned MaxPredDepth = 0; for (SUnit::const_pred_iterator I = Cur->Preds.begin(), E = Cur->Preds.end(); I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; SUnit *PredSU = I->getSUnit(); if (PredSU->isDepthCurrent) MaxPredDepth = std::max(MaxPredDepth, @@ -237,7 +238,7 @@ void SUnit::ComputeDepth() { /// ComputeHeight - Calculate the maximal path from the node to the entry. /// -void SUnit::ComputeHeight() { +void SUnit::ComputeHeight(bool IgnoreAntiDep) { SmallVector<SUnit*, 8> WorkList; WorkList.push_back(this); do { @@ -247,6 +248,7 @@ void SUnit::ComputeHeight() { unsigned MaxSuccHeight = 0; for (SUnit::const_succ_iterator I = Cur->Succs.begin(), E = Cur->Succs.end(); I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; SUnit *SuccSU = I->getSUnit(); if (SuccSU->isHeightCurrent) MaxSuccHeight = std::max(MaxSuccHeight, @@ -346,7 +348,7 @@ void ScheduleDAG::VerifySchedule(bool isBottomUp) { AnyNotSched = true; } if (SUnits[i].isScheduled && - (isBottomUp ? SUnits[i].getHeight() : SUnits[i].getHeight()) > + (isBottomUp ? SUnits[i].getHeight() : SUnits[i].getDepth()) > unsigned(INT_MAX)) { if (!AnyNotSched) errs() << "*** Scheduling failed! ***\n"; diff --git a/lib/CodeGen/ScheduleDAGEmit.cpp b/lib/CodeGen/ScheduleDAGEmit.cpp index 0d15c02..8e03420 100644 --- a/lib/CodeGen/ScheduleDAGEmit.cpp +++ b/lib/CodeGen/ScheduleDAGEmit.cpp @@ -50,8 +50,10 @@ void ScheduleDAG::EmitPhysRegCopy(SUnit *SU, break; } } - TII->copyRegToReg(*BB, InsertPos, Reg, VRI->second, - SU->CopyDstRC, SU->CopySrcRC); + bool Success = TII->copyRegToReg(*BB, InsertPos, Reg, VRI->second, + SU->CopyDstRC, SU->CopySrcRC); + (void)Success; + assert(Success && "copyRegToReg failed!"); } else { // Copy from physical register. assert(I->getReg() && "Unknown physical register!"); @@ -59,8 +61,10 @@ void ScheduleDAG::EmitPhysRegCopy(SUnit *SU, bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second; isNew = isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); - TII->copyRegToReg(*BB, InsertPos, VRBase, I->getReg(), - SU->CopyDstRC, SU->CopySrcRC); + bool Success = TII->copyRegToReg(*BB, InsertPos, VRBase, I->getReg(), + SU->CopyDstRC, SU->CopySrcRC); + (void)Success; + assert(Success && "copyRegToReg failed!"); } break; } diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp index 43454dd..6070ff6 100644 --- a/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -98,7 +98,9 @@ static const Value *getUnderlyingObject(const Value *V) { /// information and it can be tracked to a normal reference to a known /// object, return the Value for that object. Otherwise return null. static const Value *getUnderlyingObjectForInstr(const MachineInstr *MI, - const MachineFrameInfo *MFI) { + const MachineFrameInfo *MFI, + bool &MayAlias) { + MayAlias = true; if (!MI->hasOneMemOperand() || !(*MI->memoperands_begin())->getValue() || (*MI->memoperands_begin())->isVolatile()) @@ -110,6 +112,7 @@ static const Value *getUnderlyingObjectForInstr(const MachineInstr *MI, V = getUnderlyingObject(V); if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V)) { + MayAlias = PSV->mayAlias(MFI); // For now, ignore PseudoSourceValues which may alias LLVM IR values // because the code that uses this function has no way to cope with // such aliases. @@ -124,6 +127,23 @@ static const Value *getUnderlyingObjectForInstr(const MachineInstr *MI, return 0; } +static bool mayUnderlyingObjectForInstrAlias(const MachineInstr *MI, + const MachineFrameInfo *MFI) { + if (!MI->hasOneMemOperand() || + !(*MI->memoperands_begin())->getValue() || + (*MI->memoperands_begin())->isVolatile()) + return true; + + const Value *V = (*MI->memoperands_begin())->getValue(); + if (!V) + return true; + + V = getUnderlyingObject(V); + if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V)) + return PSV->mayAlias(MFI); + return true; +} + void ScheduleDAGInstrs::StartBlock(MachineBasicBlock *BB) { if (MachineLoop *ML = MLI.getLoopFor(BB)) if (BB == ML->getLoopLatch()) { @@ -208,7 +228,7 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) { SUnit *DefSU = DefList[i]; if (DefSU != SU && (Kind != SDep::Output || !MO.isDead() || - !DefSU->getInstr()->registerDefIsDead(Reg))) + !DefSU->getInstr()->registerDefIsDead(*Alias))) DefSU->addPred(SDep(SU, Kind, AOLatency, /*Reg=*/ *Alias)); } } @@ -317,29 +337,35 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) { } // Add chain dependencies. + // Chain dependencies used to enforce memory order should have + // latency of 0 (except for true dependency of Store followed by + // aliased Load... we estimate that with a single cycle of latency + // assuming the hardware will bypass) // Note that isStoreToStackSlot and isLoadFromStackSLot are not usable // after stack slots are lowered to actual addresses. // TODO: Use an AliasAnalysis and do real alias-analysis queries, and // produce more precise dependence information. +#define STORE_LOAD_LATENCY 1 + unsigned TrueMemOrderLatency = 0; if (TID.isCall() || TID.hasUnmodeledSideEffects()) { new_chain: // This is the conservative case. Add dependencies on all memory // references. if (Chain) - Chain->addPred(SDep(SU, SDep::Order, SU->Latency)); + Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); Chain = SU; for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) - PendingLoads[k]->addPred(SDep(SU, SDep::Order, SU->Latency)); + PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); PendingLoads.clear(); for (std::map<const Value *, SUnit *>::iterator I = MemDefs.begin(), E = MemDefs.end(); I != E; ++I) { - I->second->addPred(SDep(SU, SDep::Order, SU->Latency)); + I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); I->second = SU; } for (std::map<const Value *, std::vector<SUnit *> >::iterator I = MemUses.begin(), E = MemUses.end(); I != E; ++I) { for (unsigned i = 0, e = I->second.size(); i != e; ++i) - I->second[i]->addPred(SDep(SU, SDep::Order, SU->Latency)); + I->second[i]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); I->second.clear(); } // See if it is known to just have a single memory reference. @@ -356,12 +382,14 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) { // Unknown memory accesses. Assume the worst. ChainMMO = 0; } else if (TID.mayStore()) { - if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) { + bool MayAlias = true; + TrueMemOrderLatency = STORE_LOAD_LATENCY; + if (const Value *V = getUnderlyingObjectForInstr(MI, MFI, MayAlias)) { // A store to a specific PseudoSourceValue. Add precise dependencies. // Handle the def in MemDefs, if there is one. std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V); if (I != MemDefs.end()) { - I->second->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0, + I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0, /*Reg=*/0, /*isNormalMemory=*/true)); I->second = SU; } else { @@ -372,49 +400,58 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) { MemUses.find(V); if (J != MemUses.end()) { for (unsigned i = 0, e = J->second.size(); i != e; ++i) - J->second[i]->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0, - /*isNormalMemory=*/true)); + J->second[i]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency, + /*Reg=*/0, /*isNormalMemory=*/true)); J->second.clear(); } - // Add dependencies from all the PendingLoads, since without - // memoperands we must assume they alias anything. - for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) - PendingLoads[k]->addPred(SDep(SU, SDep::Order, SU->Latency)); - // Add a general dependence too, if needed. - if (Chain) - Chain->addPred(SDep(SU, SDep::Order, SU->Latency)); - } else + if (MayAlias) { + // Add dependencies from all the PendingLoads, since without + // memoperands we must assume they alias anything. + for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) + PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); + // Add a general dependence too, if needed. + if (Chain) + Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + } + } else if (MayAlias) { // Treat all other stores conservatively. goto new_chain; + } } else if (TID.mayLoad()) { + bool MayAlias = true; + TrueMemOrderLatency = 0; if (MI->isInvariantLoad(AA)) { // Invariant load, no chain dependencies needed! - } else if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) { + } else if (const Value *V = + getUnderlyingObjectForInstr(MI, MFI, MayAlias)) { // A load from a specific PseudoSourceValue. Add precise dependencies. std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V); if (I != MemDefs.end()) - I->second->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0, + I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0, /*Reg=*/0, /*isNormalMemory=*/true)); MemUses[V].push_back(SU); // Add a general dependence too, if needed. if (Chain && (!ChainMMO || (ChainMMO->isStore() || ChainMMO->isVolatile()))) - Chain->addPred(SDep(SU, SDep::Order, SU->Latency)); + Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); } else if (MI->hasVolatileMemoryRef()) { // Treat volatile loads conservatively. Note that this includes // cases where memoperand information is unavailable. goto new_chain; - } else { - // A normal load. Depend on the general chain, as well as on + } else if (MayAlias) { + // A "MayAlias" load. Depend on the general chain, as well as on // all stores. In the absense of MachineMemOperand information, // we can't even assume that the load doesn't alias well-behaved // memory locations. if (Chain) - Chain->addPred(SDep(SU, SDep::Order, SU->Latency)); + Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); for (std::map<const Value *, SUnit *>::iterator I = MemDefs.begin(), - E = MemDefs.end(); I != E; ++I) - I->second->addPred(SDep(SU, SDep::Order, SU->Latency)); + E = MemDefs.end(); I != E; ++I) { + SUnit *DefSU = I->second; + if (mayUnderlyingObjectForInstrAlias(DefSU->getInstr(), MFI)) + DefSU->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + } PendingLoads.push_back(SU); } } diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e3f8f0f..5f70cb8 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -31,7 +31,6 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -57,7 +56,7 @@ namespace { //------------------------------ DAGCombiner ---------------------------------// - class VISIBILITY_HIDDEN DAGCombiner { + class DAGCombiner { SelectionDAG &DAG; const TargetLowering &TLI; CombineLevel Level; @@ -280,8 +279,7 @@ public: namespace { /// WorkListRemover - This class is a DAGUpdateListener that removes any deleted /// nodes from the worklist. -class VISIBILITY_HIDDEN WorkListRemover : - public SelectionDAG::DAGUpdateListener { +class WorkListRemover : public SelectionDAG::DAGUpdateListener { DAGCombiner &DC; public: explicit WorkListRemover(DAGCombiner &dc) : DC(dc) {} @@ -5732,15 +5730,17 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, // If this is an EXTLOAD, the VT's must match. if (LLD->getMemoryVT() == RLD->getMemoryVT()) { - // FIXME: this conflates two src values, discarding one. This is not - // the right thing to do, but nothing uses srcvalues now. When they do, - // turn SrcValue into a list of locations. + // FIXME: this discards src value information. This is + // over-conservative. It would be beneficial to be able to remember + // both potential memory locations. SDValue Addr; if (TheSelect->getOpcode() == ISD::SELECT) { // Check that the condition doesn't reach either load. If so, folding // this will induce a cycle into the DAG. - if (!LLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && - !RLD->isPredecessorOf(TheSelect->getOperand(0).getNode())) { + if ((!LLD->hasAnyUseOfValue(1) || + !LLD->isPredecessorOf(TheSelect->getOperand(0).getNode())) && + (!RLD->hasAnyUseOfValue(1) || + !RLD->isPredecessorOf(TheSelect->getOperand(0).getNode()))) { Addr = DAG.getNode(ISD::SELECT, TheSelect->getDebugLoc(), LLD->getBasePtr().getValueType(), TheSelect->getOperand(0), LLD->getBasePtr(), @@ -5749,10 +5749,12 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, } else { // Check that the condition doesn't reach either load. If so, folding // this will induce a cycle into the DAG. - if (!LLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && - !RLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && - !LLD->isPredecessorOf(TheSelect->getOperand(1).getNode()) && - !RLD->isPredecessorOf(TheSelect->getOperand(1).getNode())) { + if ((!LLD->hasAnyUseOfValue(1) || + (!LLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && + !LLD->isPredecessorOf(TheSelect->getOperand(1).getNode()))) && + (!RLD->hasAnyUseOfValue(1) || + (!RLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && + !RLD->isPredecessorOf(TheSelect->getOperand(1).getNode())))) { Addr = DAG.getNode(ISD::SELECT_CC, TheSelect->getDebugLoc(), LLD->getBasePtr().getValueType(), TheSelect->getOperand(0), @@ -5768,16 +5770,14 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, Load = DAG.getLoad(TheSelect->getValueType(0), TheSelect->getDebugLoc(), LLD->getChain(), - Addr,LLD->getSrcValue(), - LLD->getSrcValueOffset(), + Addr, 0, 0, LLD->isVolatile(), LLD->getAlignment()); } else { Load = DAG.getExtLoad(LLD->getExtensionType(), TheSelect->getDebugLoc(), TheSelect->getValueType(0), - LLD->getChain(), Addr, LLD->getSrcValue(), - LLD->getSrcValueOffset(), + LLD->getChain(), Addr, 0, 0, LLD->getMemoryVT(), LLD->isVolatile(), LLD->getAlignment()); diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index d3ffb2a..da311ed 100644 --- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -349,6 +349,8 @@ void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op, } else if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) { MI->addOperand(MachineOperand::CreateES(ES->getSymbol(), ES->getTargetFlags())); + } else if (BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) { + MI->addOperand(MachineOperand::CreateBA(BA->getBlockAddress())); } else { assert(Op.getValueType() != MVT::Other && Op.getValueType() != MVT::Flag && @@ -556,7 +558,7 @@ void InstrEmitter::EmitNode(SDNode *Node, bool IsClone, bool IsCloned, MI->setMemRefs(cast<MachineSDNode>(Node)->memoperands_begin(), cast<MachineSDNode>(Node)->memoperands_end()); - if (II.usesCustomDAGSchedInsertionHook()) { + if (II.usesCustomInsertionHook()) { // Insert this instruction into the basic block using a target // specific inserter which may returns a new basic block. MBB = TLI->EmitInstrWithCustomInserter(MI, MBB, EM); @@ -571,6 +573,12 @@ void InstrEmitter::EmitNode(SDNode *Node, bool IsClone, bool IsCloned, unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()]; if (Node->hasAnyUseOfValue(i)) EmitCopyFromReg(Node, i, IsClone, IsCloned, Reg, VRBaseMap); + // If there are no uses, mark the register as dead now, so that + // MachineLICM/Sink can see that it's dead. Don't do this if the + // node has a Flag value, for the benefit of targets still using + // Flag for values in physregs. + else if (Node->getValueType(Node->getNumValues()-1) != MVT::Flag) + MI->addRegisterDead(Reg, TRI); } } return; diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 7138dd2..f389f7f 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -32,7 +32,6 @@ #include "llvm/GlobalVariable.h" #include "llvm/LLVMContext.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" @@ -55,7 +54,7 @@ using namespace llvm; /// will attempt merge setcc and brc instructions into brcc's. /// namespace { -class VISIBILITY_HIDDEN SelectionDAGLegalize { +class SelectionDAGLegalize { TargetLowering &TLI; SelectionDAG &DAG; CodeGenOpt::Level OptLevel; @@ -2574,16 +2573,8 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, case ISD::ConstantFP: { ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Node); // Check to see if this FP immediate is already legal. - bool isLegal = false; - for (TargetLowering::legal_fpimm_iterator I = TLI.legal_fpimm_begin(), - E = TLI.legal_fpimm_end(); I != E; ++I) { - if (CFP->isExactlyValue(*I)) { - isLegal = true; - break; - } - } // If this is a legal constant, turn it into a TargetConstantFP node. - if (isLegal) + if (TLI.isFPImmLegal(CFP->getValueAPF(), Node->getValueType(0))) Results.push_back(SDValue(Node, 0)); else Results.push_back(ExpandConstantFP(CFP, true, DAG, TLI)); diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 5992f5d..c4bd552 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -623,8 +623,7 @@ void DAGTypeLegalizer::RemapValue(SDValue &N) { namespace { /// NodeUpdateListener - This class is a DAGUpdateListener that listens for /// updates to nodes and recomputes their ready state. - class VISIBILITY_HIDDEN NodeUpdateListener : - public SelectionDAG::DAGUpdateListener { + class NodeUpdateListener : public SelectionDAG::DAGUpdateListener { DAGTypeLegalizer &DTL; SmallSetVector<SDNode*, 16> &NodesToAnalyze; public: diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp index e0f93d8..4045a34 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp @@ -19,7 +19,6 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Compiler.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" @@ -40,7 +39,7 @@ namespace { /// FastPriorityQueue - A degenerate priority queue that considers /// all nodes to have the same priority. /// - struct VISIBILITY_HIDDEN FastPriorityQueue { + struct FastPriorityQueue { SmallVector<SUnit *, 16> Queue; bool empty() const { return Queue.empty(); } @@ -60,7 +59,7 @@ namespace { //===----------------------------------------------------------------------===// /// ScheduleDAGFast - The actual "fast" list scheduler implementation. /// -class VISIBILITY_HIDDEN ScheduleDAGFast : public ScheduleDAGSDNodes { +class ScheduleDAGFast : public ScheduleDAGSDNodes { private: /// AvailableQueue - The priority queue to use for the available SUnits. FastPriorityQueue AvailableQueue; diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp index c8d2158..faf21f7 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp @@ -28,7 +28,6 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/PriorityQueue.h" @@ -48,7 +47,7 @@ namespace { /// ScheduleDAGList - The actual list scheduler implementation. This supports /// top-down scheduling. /// -class VISIBILITY_HIDDEN ScheduleDAGList : public ScheduleDAGSDNodes { +class ScheduleDAGList : public ScheduleDAGSDNodes { private: /// AvailableQueue - The priority queue to use for the available SUnits. /// diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index cec24e6..7e1015a 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -24,7 +24,6 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/ADT/PriorityQueue.h" #include "llvm/ADT/SmallSet.h" @@ -53,7 +52,7 @@ namespace { /// ScheduleDAGRRList - The actual register reduction list scheduler /// implementation. This supports both top-down and bottom-up scheduling. /// -class VISIBILITY_HIDDEN ScheduleDAGRRList : public ScheduleDAGSDNodes { +class ScheduleDAGRRList : public ScheduleDAGSDNodes { private: /// isBottomUp - This is true if the scheduling problem is bottom-up, false if /// it is top-down. @@ -965,8 +964,7 @@ CalcNodeSethiUllmanNumber(const SUnit *SU, std::vector<unsigned> &SUNumbers) { namespace { template<class SF> - class VISIBILITY_HIDDEN RegReductionPriorityQueue - : public SchedulingPriorityQueue { + class RegReductionPriorityQueue : public SchedulingPriorityQueue { PriorityQueue<SUnit*, std::vector<SUnit*>, SF> Queue; unsigned currentQueueId; diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h index c9c36f7..ebb31ac 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h @@ -58,6 +58,7 @@ namespace llvm { if (isa<ConstantPoolSDNode>(Node)) return true; if (isa<JumpTableSDNode>(Node)) return true; if (isa<ExternalSymbolSDNode>(Node)) return true; + if (isa<BlockAddressSDNode>(Node)) return true; if (Node->getOpcode() == ISD::EntryToken) return true; return false; } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 37736c0..98e7317 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -460,6 +460,11 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) { ID.AddInteger(SVN->getMaskElt(i)); break; } + case ISD::TargetBlockAddress: + case ISD::BlockAddress: { + ID.AddPointer(cast<BlockAddressSDNode>(N)); + break; + } } // end switch (N->getOpcode()) } @@ -1317,6 +1322,23 @@ SDValue SelectionDAG::getLabel(unsigned Opcode, DebugLoc dl, return SDValue(N, 0); } +SDValue SelectionDAG::getBlockAddress(BlockAddress *BA, DebugLoc DL, + bool isTarget) { + unsigned Opc = isTarget ? ISD::TargetBlockAddress : ISD::BlockAddress; + + FoldingSetNodeID ID; + AddNodeIDNode(ID, Opc, getVTList(TLI.getPointerTy()), 0, 0); + ID.AddPointer(BA); + void *IP = 0; + if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) + return SDValue(E, 0); + SDNode *N = NodeAllocator.Allocate<BlockAddressSDNode>(); + new (N) BlockAddressSDNode(Opc, DL, TLI.getPointerTy(), BA); + CSEMap.InsertNode(N, IP); + AllNodes.push_back(N); + return SDValue(N, 0); +} + SDValue SelectionDAG::getSrcValue(const Value *V) { assert((!V || isa<PointerType>(V->getType())) && "SrcValue is not a pointer?"); @@ -5307,31 +5329,26 @@ bool SDValue::reachesChainWithoutSideEffects(SDValue Dest, return false; } - -static void findPredecessor(SDNode *N, const SDNode *P, bool &found, - SmallPtrSet<SDNode *, 32> &Visited) { - if (found || !Visited.insert(N)) - return; - - for (unsigned i = 0, e = N->getNumOperands(); !found && i != e; ++i) { - SDNode *Op = N->getOperand(i).getNode(); - if (Op == P) { - found = true; - return; - } - findPredecessor(Op, P, found, Visited); - } -} - /// isPredecessorOf - Return true if this node is a predecessor of N. This node -/// is either an operand of N or it can be reached by recursively traversing -/// up the operands. +/// is either an operand of N or it can be reached by traversing up the operands. /// NOTE: this is an expensive method. Use it carefully. bool SDNode::isPredecessorOf(SDNode *N) const { SmallPtrSet<SDNode *, 32> Visited; - bool found = false; - findPredecessor(N, this, found, Visited); - return found; + SmallVector<SDNode *, 16> Worklist; + Worklist.push_back(N); + + do { + N = Worklist.pop_back_val(); + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + SDNode *Op = N->getOperand(i).getNode(); + if (Op == this) + return true; + if (Visited.insert(Op)) + Worklist.push_back(Op); + } + } while (!Worklist.empty()); + + return false; } uint64_t SDNode::getConstantOperandVal(unsigned Num) const { @@ -5405,6 +5422,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::EH_RETURN: return "EH_RETURN"; case ISD::ConstantPool: return "ConstantPool"; case ISD::ExternalSymbol: return "ExternalSymbol"; + case ISD::BlockAddress: return "BlockAddress"; case ISD::INTRINSIC_WO_CHAIN: case ISD::INTRINSIC_VOID: case ISD::INTRINSIC_W_CHAIN: { @@ -5426,6 +5444,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::TargetJumpTable: return "TargetJumpTable"; case ISD::TargetConstantPool: return "TargetConstantPool"; case ISD::TargetExternalSymbol: return "TargetExternalSymbol"; + case ISD::TargetBlockAddress: return "TargetBlockAddress"; case ISD::CopyToReg: return "CopyToReg"; case ISD::CopyFromReg: return "CopyFromReg"; @@ -5735,9 +5754,9 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const { } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(this)) { if (G && R->getReg() && TargetRegisterInfo::isPhysicalRegister(R->getReg())) { - OS << " " << G->getTarget().getRegisterInfo()->getName(R->getReg()); + OS << " %" << G->getTarget().getRegisterInfo()->getName(R->getReg()); } else { - OS << " #" << R->getReg(); + OS << " %reg" << R->getReg(); } } else if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(this)) { @@ -5753,7 +5772,7 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const { OS << ":" << N->getVT().getEVTString(); } else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(this)) { - OS << " <" << *LD->getMemOperand(); + OS << "<" << *LD->getMemOperand(); bool doExt = true; switch (LD->getExtensionType()) { @@ -5771,7 +5790,7 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const { OS << ">"; } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(this)) { - OS << " <" << *ST->getMemOperand(); + OS << "<" << *ST->getMemOperand(); if (ST->isTruncatingStore()) OS << ", trunc to " << ST->getMemoryVT().getEVTString(); @@ -5782,7 +5801,14 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const { OS << ">"; } else if (const MemSDNode* M = dyn_cast<MemSDNode>(this)) { - OS << " <" << *M->getMemOperand() << ">"; + OS << "<" << *M->getMemOperand() << ">"; + } else if (const BlockAddressSDNode *BA = + dyn_cast<BlockAddressSDNode>(this)) { + OS << "<"; + WriteAsOperand(OS, BA->getBlockAddress()->getFunction(), false); + OS << ", "; + WriteAsOperand(OS, BA->getBlockAddress()->getBasicBlock(), false); + OS << ">"; } } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index adcc532..c0d2a4d 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -322,6 +322,12 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf, MBBMap[BB] = MBB; MF->push_back(MBB); + // Transfer the address-taken flag. This is necessary because there could + // be multiple MachineBasicBlocks corresponding to one BasicBlock, and only + // the first one should be marked. + if (BB->hasAddressTaken()) + MBB->setHasAddressTaken(); + // Create Machine PHI nodes for LLVM PHI nodes, lowering them as // appropriate. PHINode *PN; @@ -895,6 +901,9 @@ SDValue SelectionDAGLowering::getValue(const Value *V) { return DAG.getMergeValues(&Constants[0], NumElts, getCurDebugLoc()); } + if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) + return DAG.getBlockAddress(BA, getCurDebugLoc()); + const VectorType *VecTy = cast<VectorType>(V->getType()); unsigned NumElements = VecTy->getNumElements(); @@ -2131,6 +2140,16 @@ void SelectionDAGLowering::visitSwitch(SwitchInst &SI) { } } +void SelectionDAGLowering::visitIndirectBr(IndirectBrInst &I) { + // Update machine-CFG edges. + for (unsigned i = 0, e = I.getNumSuccessors(); i != e; ++i) + CurMBB->addSuccessor(FuncInfo.MBBMap[I.getSuccessor(i)]); + + DAG.setRoot(DAG.getNode(ISD::BRIND, getCurDebugLoc(), + MVT::Other, getControlRoot(), + getValue(I.getAddress()))); +} + void SelectionDAGLowering::visitFSub(User &I) { // -0.0 - X --> fneg @@ -2666,7 +2685,8 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { } // N = N + Idx * ElementSize; - uint64_t ElementSize = TD->getTypeAllocSize(Ty); + APInt ElementSize = APInt(TLI.getPointerTy().getSizeInBits(), + TD->getTypeAllocSize(Ty)); SDValue IdxN = getValue(Idx); // If the index is smaller or larger than intptr_t, truncate or extend @@ -2676,13 +2696,13 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { // If this is a multiply by a power of two, turn it into a shl // immediately. This is a very common case. if (ElementSize != 1) { - if (isPowerOf2_64(ElementSize)) { - unsigned Amt = Log2_64(ElementSize); + if (ElementSize.isPowerOf2()) { + unsigned Amt = ElementSize.logBase2(); IdxN = DAG.getNode(ISD::SHL, getCurDebugLoc(), N.getValueType(), IdxN, DAG.getConstant(Amt, TLI.getPointerTy())); } else { - SDValue Scale = DAG.getIntPtrConstant(ElementSize); + SDValue Scale = DAG.getConstant(ElementSize, TLI.getPointerTy()); IdxN = DAG.getNode(ISD::MUL, getCurDebugLoc(), N.getValueType(), IdxN, Scale); } @@ -4203,6 +4223,21 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { DAG.setRoot(Result); return 0; } + case Intrinsic::objectsize: { + // If we don't know by now, we're never going to know. + ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(2)); + + assert(CI && "Non-constant type in __builtin_object_size?"); + + SDValue Arg = getValue(I.getOperand(0)); + EVT Ty = Arg.getValueType(); + + if (CI->getZExtValue() < 2) + setValue(&I, DAG.getConstant(-1U, Ty)); + else + setValue(&I, DAG.getConstant(0, Ty)); + return 0; + } case Intrinsic::var_annotation: // Discard annotate attributes return 0; @@ -5485,26 +5520,6 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { DAG.setRoot(Chain); } -void SelectionDAGLowering::visitFree(FreeInst &I) { - TargetLowering::ArgListTy Args; - TargetLowering::ArgListEntry Entry; - Entry.Node = getValue(I.getOperand(0)); - Entry.Ty = TLI.getTargetData()->getIntPtrType(*DAG.getContext()); - Args.push_back(Entry); - EVT IntPtr = TLI.getPointerTy(); - bool isTailCall = PerformTailCallOpt && - isInTailCallPosition(&I, Attribute::None, TLI); - std::pair<SDValue,SDValue> Result = - TLI.LowerCallTo(getRoot(), Type::getVoidTy(*DAG.getContext()), - false, false, false, false, - 0, CallingConv::C, isTailCall, - /*isReturnValueUsed=*/true, - DAG.getExternalSymbol("free", IntPtr), Args, DAG, - getCurDebugLoc()); - if (Result.second.getNode()) - DAG.setRoot(Result.second); -} - void SelectionDAGLowering::visitVAStart(CallInst &I) { DAG.setRoot(DAG.getNode(ISD::VASTART, getCurDebugLoc(), MVT::Other, getRoot(), @@ -5735,8 +5750,7 @@ void SelectionDAGLowering::CopyValueToVirtualRegister(Value *V, unsigned Reg) { #include "llvm/CodeGen/SelectionDAGISel.h" -void SelectionDAGISel:: -LowerArguments(BasicBlock *LLVMBB) { +void SelectionDAGISel::LowerArguments(BasicBlock *LLVMBB) { // If this is the entry block, emit arguments. Function &F = *LLVMBB->getParent(); SelectionDAG &DAG = SDL->DAG; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h index 722b1d8..a0ec7aa 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h @@ -44,12 +44,12 @@ class FPExtInst; class FPToSIInst; class FPToUIInst; class FPTruncInst; -class FreeInst; class Function; class GetElementPtrInst; class GCFunctionInfo; class ICmpInst; class IntToPtrInst; +class IndirectBrInst; class InvokeInst; class InsertElementInst; class InsertValueInst; @@ -449,6 +449,7 @@ private: void visitRet(ReturnInst &I); void visitBr(BranchInst &I); void visitSwitch(SwitchInst &I); + void visitIndirectBr(IndirectBrInst &I); void visitUnreachable(UnreachableInst &I) { /* noop */ } // Helpers for visitSwitch @@ -528,7 +529,6 @@ private: void visitGetElementPtr(User &I); void visitSelect(User &I); - void visitFree(FreeInst &I); void visitAlloca(AllocaInst &I); void visitLoad(LoadInst &I); void visitStore(StoreInst &I); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 72e7f58..b63d5bb 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -26,6 +26,7 @@ #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" +#include "llvm/LLVMContext.h" #include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/GCMetadata.h" @@ -43,6 +44,7 @@ #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" +#include "llvm/Target/TargetIntrinsicInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" @@ -149,16 +151,20 @@ namespace llvm { } // EmitInstrWithCustomInserter - This method should be implemented by targets -// that mark instructions with the 'usesCustomDAGSchedInserter' flag. These +// that mark instructions with the 'usesCustomInserter' flag. These // instructions are special in various ways, which require special support to // insert. The specified MachineInstr is created but not inserted into any -// basic blocks, and the scheduler passes ownership of it to this method. +// basic blocks, and this method is called to expand it into a sequence of +// instructions, potentially also creating new basic blocks and control flow. +// When new basic blocks are inserted and the edges from MBB to its successors +// are modified, the method should insert pairs of <OldSucc, NewSucc> into the +// DenseMap. MachineBasicBlock *TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB, DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const { #ifndef NDEBUG errs() << "If a target marks an instruction with " - "'usesCustomDAGSchedInserter', it must implement " + "'usesCustomInserter', it must implement " "TargetLowering::EmitInstrWithCustomInserter!"; #endif llvm_unreachable(0); @@ -1288,5 +1294,56 @@ bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U, return !isNonImmUse(Root, N, U); } +SDNode *SelectionDAGISel::Select_INLINEASM(SDValue N) { + std::vector<SDValue> Ops(N.getNode()->op_begin(), N.getNode()->op_end()); + SelectInlineAsmMemoryOperands(Ops); + + std::vector<EVT> VTs; + VTs.push_back(MVT::Other); + VTs.push_back(MVT::Flag); + SDValue New = CurDAG->getNode(ISD::INLINEASM, N.getDebugLoc(), + VTs, &Ops[0], Ops.size()); + return New.getNode(); +} + +SDNode *SelectionDAGISel::Select_UNDEF(const SDValue &N) { + return CurDAG->SelectNodeTo(N.getNode(), TargetInstrInfo::IMPLICIT_DEF, + N.getValueType()); +} + +SDNode *SelectionDAGISel::Select_DBG_LABEL(const SDValue &N) { + SDValue Chain = N.getOperand(0); + unsigned C = cast<LabelSDNode>(N)->getLabelID(); + SDValue Tmp = CurDAG->getTargetConstant(C, MVT::i32); + return CurDAG->SelectNodeTo(N.getNode(), TargetInstrInfo::DBG_LABEL, + MVT::Other, Tmp, Chain); +} + +SDNode *SelectionDAGISel::Select_EH_LABEL(const SDValue &N) { + SDValue Chain = N.getOperand(0); + unsigned C = cast<LabelSDNode>(N)->getLabelID(); + SDValue Tmp = CurDAG->getTargetConstant(C, MVT::i32); + return CurDAG->SelectNodeTo(N.getNode(), TargetInstrInfo::EH_LABEL, + MVT::Other, Tmp, Chain); +} + +void SelectionDAGISel::CannotYetSelect(SDValue N) { + std::string msg; + raw_string_ostream Msg(msg); + Msg << "Cannot yet select: "; + N.getNode()->print(Msg, CurDAG); + llvm_report_error(Msg.str()); +} + +void SelectionDAGISel::CannotYetSelectIntrinsic(SDValue N) { + errs() << "Cannot yet select: "; + unsigned iid = + cast<ConstantSDNode>(N.getOperand(N.getOperand(0).getValueType() == MVT::Other))->getZExtValue(); + if (iid < Intrinsic::num_intrinsics) + llvm_report_error("Cannot yet select: intrinsic %" + Intrinsic::getName((Intrinsic::ID)iid)); + else if (const TargetIntrinsicInfo *tii = TM.getIntrinsicInfo()) + llvm_report_error(Twine("Cannot yet select: target intrinsic %") + + tii->getName(iid)); +} char SelectionDAGISel::ID = 0; diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index a2baee4..9f36b67 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -481,7 +481,7 @@ TargetLowering::TargetLowering(TargetMachine &tm,TargetLoweringObjectFile *tlof) setOperationAction(ISD::PREFETCH, MVT::Other, Expand); // ConstantFP nodes default to expand. Targets can either change this to - // Legal, in which case all fp constants are legal, or use addLegalFPImmediate + // Legal, in which case all fp constants are legal, or use isFPImmLegal() // to optimize expansions for certain constants. setOperationAction(ISD::ConstantFP, MVT::f32, Expand); setOperationAction(ISD::ConstantFP, MVT::f64, Expand); diff --git a/lib/CodeGen/ShadowStackGC.cpp b/lib/CodeGen/ShadowStackGC.cpp index 25a499b88..0e6d479 100644 --- a/lib/CodeGen/ShadowStackGC.cpp +++ b/lib/CodeGen/ShadowStackGC.cpp @@ -31,14 +31,13 @@ #include "llvm/CodeGen/GCStrategy.h" #include "llvm/IntrinsicInst.h" #include "llvm/Module.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/IRBuilder.h" using namespace llvm; namespace { - class VISIBILITY_HIDDEN ShadowStackGC : public GCStrategy { + class ShadowStackGC : public GCStrategy { /// RootChain - This is the global linked-list that contains the chain of GC /// roots. GlobalVariable *Head; @@ -84,7 +83,7 @@ namespace { /// /// It's wrapped up in a state machine using the same transform C# uses for /// 'yield return' enumerators, This transform allows it to be non-allocating. - class VISIBILITY_HIDDEN EscapeEnumerator { + class EscapeEnumerator { Function &F; const char *CleanupBBName; diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index 9c283b0..b5d6b47 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -76,6 +76,7 @@ void SimpleRegisterCoalescing::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<AliasAnalysis>(); AU.addRequired<LiveIntervals>(); AU.addPreserved<LiveIntervals>(); + AU.addPreserved<SlotIndexes>(); AU.addRequired<MachineLoopInfo>(); AU.addPreserved<MachineLoopInfo>(); AU.addPreservedID(MachineDominatorsID); @@ -105,7 +106,7 @@ void SimpleRegisterCoalescing::getAnalysisUsage(AnalysisUsage &AU) const { bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInterval &IntB, MachineInstr *CopyMI) { - LiveIndex CopyIdx = li_->getDefIndex(li_->getInstructionIndex(CopyMI)); + SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI).getDefIndex(); // BValNo is a value number in B that is defined by a copy from A. 'B3' in // the example above. @@ -120,7 +121,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, assert(BValNo->def == CopyIdx && "Copy doesn't define the value?"); // AValNo is the value number in A that defines the copy, A3 in the example. - LiveIndex CopyUseIdx = li_->getUseIndex(CopyIdx); + SlotIndex CopyUseIdx = CopyIdx.getUseIndex(); LiveInterval::iterator ALR = IntA.FindLiveRangeContaining(CopyUseIdx); assert(ALR != IntA.end() && "Live range not found!"); VNInfo *AValNo = ALR->valno; @@ -158,13 +159,13 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, // Get the LiveRange in IntB that this value number starts with. LiveInterval::iterator ValLR = - IntB.FindLiveRangeContaining(li_->getPrevSlot(AValNo->def)); + IntB.FindLiveRangeContaining(AValNo->def.getPrevSlot()); assert(ValLR != IntB.end() && "Live range not found!"); // Make sure that the end of the live range is inside the same block as // CopyMI. MachineInstr *ValLREndInst = - li_->getInstructionFromIndex(li_->getPrevSlot(ValLR->end)); + li_->getInstructionFromIndex(ValLR->end.getPrevSlot()); if (!ValLREndInst || ValLREndInst->getParent() != CopyMI->getParent()) return false; @@ -193,7 +194,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, IntB.print(errs(), tri_); }); - LiveIndex FillerStart = ValLR->end, FillerEnd = BLR->start; + SlotIndex FillerStart = ValLR->end, FillerEnd = BLR->start; // We are about to delete CopyMI, so need to remove it as the 'instruction // that defines this value #'. Update the the valnum with the new defining // instruction #. @@ -306,8 +307,8 @@ TransferImplicitOps(MachineInstr *MI, MachineInstr *NewMI) { bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, LiveInterval &IntB, MachineInstr *CopyMI) { - LiveIndex CopyIdx = - li_->getDefIndex(li_->getInstructionIndex(CopyMI)); + SlotIndex CopyIdx = + li_->getInstructionIndex(CopyMI).getDefIndex(); // FIXME: For now, only eliminate the copy by commuting its def when the // source register is a virtual register. We want to guard against cases @@ -330,7 +331,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, // AValNo is the value number in A that defines the copy, A3 in the example. LiveInterval::iterator ALR = - IntA.FindLiveRangeContaining(li_->getPrevSlot(CopyIdx)); + IntA.FindLiveRangeContaining(CopyIdx.getUseIndex()); // assert(ALR != IntA.end() && "Live range not found!"); VNInfo *AValNo = ALR->valno; @@ -376,7 +377,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(IntA.reg), UE = mri_->use_end(); UI != UE; ++UI) { MachineInstr *UseMI = &*UI; - LiveIndex UseIdx = li_->getInstructionIndex(UseMI); + SlotIndex UseIdx = li_->getInstructionIndex(UseMI); LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx); if (ULR == IntA.end()) continue; @@ -401,7 +402,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, bool BHasPHIKill = BValNo->hasPHIKill(); SmallVector<VNInfo*, 4> BDeadValNos; VNInfo::KillSet BKills; - std::map<LiveIndex, LiveIndex> BExtend; + std::map<SlotIndex, SlotIndex> BExtend; // If ALR and BLR overlaps and end of BLR extends beyond end of ALR, e.g. // A = or A, B @@ -428,7 +429,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, ++UI; if (JoinedCopies.count(UseMI)) continue; - LiveIndex UseIdx= li_->getUseIndex(li_->getInstructionIndex(UseMI)); + SlotIndex UseIdx = li_->getInstructionIndex(UseMI).getUseIndex(); LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx); if (ULR == IntA.end() || ULR->valno != AValNo) continue; @@ -439,7 +440,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, if (Extended) UseMO.setIsKill(false); else - BKills.push_back(li_->getNextSlot(UseIdx)); + BKills.push_back(UseIdx.getDefIndex()); } unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; if (!tii_->isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) @@ -448,7 +449,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, // This copy will become a noop. If it's defining a new val#, // remove that val# as well. However this live range is being // extended to the end of the existing live range defined by the copy. - LiveIndex DefIdx = li_->getDefIndex(UseIdx); + SlotIndex DefIdx = UseIdx.getDefIndex(); const LiveRange *DLR = IntB.getLiveRangeContaining(DefIdx); BHasPHIKill |= DLR->valno->hasPHIKill(); assert(DLR->valno->def == DefIdx); @@ -495,8 +496,8 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, for (LiveInterval::iterator AI = IntA.begin(), AE = IntA.end(); AI != AE; ++AI) { if (AI->valno != AValNo) continue; - LiveIndex End = AI->end; - std::map<LiveIndex, LiveIndex>::iterator + SlotIndex End = AI->end; + std::map<SlotIndex, SlotIndex>::iterator EI = BExtend.find(End); if (EI != BExtend.end()) End = EI->second; @@ -507,7 +508,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, if (BHasSubRegs) { for (const unsigned *SR = tri_->getSubRegisters(IntB.reg); *SR; ++SR) { LiveInterval &SRLI = li_->getInterval(*SR); - SRLI.MergeInClobberRange(AI->start, End, li_->getVNInfoAllocator()); + SRLI.MergeInClobberRange(*li_, AI->start, End, li_->getVNInfoAllocator()); } } } @@ -551,7 +552,7 @@ static bool isSameOrFallThroughBB(MachineBasicBlock *MBB, /// from a physical register live interval as well as from the live intervals /// of its sub-registers. static void removeRange(LiveInterval &li, - LiveIndex Start, LiveIndex End, + SlotIndex Start, SlotIndex End, LiveIntervals *li_, const TargetRegisterInfo *tri_) { li.removeRange(Start, End, true); if (TargetRegisterInfo::isPhysicalRegister(li.reg)) { @@ -559,8 +560,9 @@ static void removeRange(LiveInterval &li, if (!li_->hasInterval(*SR)) continue; LiveInterval &sli = li_->getInterval(*SR); - LiveIndex RemoveStart = Start; - LiveIndex RemoveEnd = Start; + SlotIndex RemoveStart = Start; + SlotIndex RemoveEnd = Start; + while (RemoveEnd != End) { LiveInterval::iterator LR = sli.FindLiveRangeContaining(RemoveStart); if (LR == sli.end()) @@ -577,14 +579,14 @@ static void removeRange(LiveInterval &li, /// as the copy instruction, trim the live interval to the last use and return /// true. bool -SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(LiveIndex CopyIdx, +SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(SlotIndex CopyIdx, MachineBasicBlock *CopyMBB, LiveInterval &li, const LiveRange *LR) { - LiveIndex MBBStart = li_->getMBBStartIdx(CopyMBB); - LiveIndex LastUseIdx; + SlotIndex MBBStart = li_->getMBBStartIdx(CopyMBB); + SlotIndex LastUseIdx; MachineOperand *LastUse = - lastRegisterUse(LR->start, li_->getPrevSlot(CopyIdx), li.reg, LastUseIdx); + lastRegisterUse(LR->start, CopyIdx.getPrevSlot(), li.reg, LastUseIdx); if (LastUse) { MachineInstr *LastUseMI = LastUse->getParent(); if (!isSameOrFallThroughBB(LastUseMI->getParent(), CopyMBB, tii_)) { @@ -603,8 +605,8 @@ SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(LiveIndex CopyIdx, // There are uses before the copy, just shorten the live range to the end // of last use. LastUse->setIsKill(); - removeRange(li, li_->getDefIndex(LastUseIdx), LR->end, li_, tri_); - LR->valno->addKill(li_->getNextSlot(LastUseIdx)); + removeRange(li, LastUseIdx.getDefIndex(), LR->end, li_, tri_); + LR->valno->addKill(LastUseIdx.getDefIndex()); unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; if (tii_->isMoveInstr(*LastUseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) && DstReg == li.reg) { @@ -617,7 +619,7 @@ SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(LiveIndex CopyIdx, // Is it livein? if (LR->start <= MBBStart && LR->end > MBBStart) { - if (LR->start == LiveIndex()) { + if (LR->start == li_->getZeroIndex()) { assert(TargetRegisterInfo::isPhysicalRegister(li.reg)); // Live-in to the function but dead. Remove it from entry live-in set. mf_->begin()->removeLiveIn(li.reg); @@ -634,7 +636,7 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, unsigned DstReg, unsigned DstSubIdx, MachineInstr *CopyMI) { - LiveIndex CopyIdx = li_->getUseIndex(li_->getInstructionIndex(CopyMI)); + SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI).getUseIndex(); LiveInterval::iterator SrcLR = SrcInt.FindLiveRangeContaining(CopyIdx); assert(SrcLR != SrcInt.end() && "Live range not found!"); VNInfo *ValNo = SrcLR->valno; @@ -683,7 +685,7 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, return false; } - LiveIndex DefIdx = li_->getDefIndex(CopyIdx); + SlotIndex DefIdx = CopyIdx.getDefIndex(); const LiveRange *DLR= li_->getInterval(DstReg).getLiveRangeContaining(DefIdx); DLR->valno->setCopy(0); // Don't forget to update sub-register intervals. @@ -716,7 +718,7 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, // should mark it dead: if (DefMI->getParent() == MBB) { DefMI->addRegisterDead(SrcInt.reg, tri_); - SrcLR->end = li_->getNextSlot(SrcLR->start); + SrcLR->end = SrcLR->start.getNextSlot(); } } @@ -815,8 +817,8 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg, (TargetRegisterInfo::isVirtualRegister(CopyDstReg) || allocatableRegs_[CopyDstReg])) { LiveInterval &LI = li_->getInterval(CopyDstReg); - LiveIndex DefIdx = - li_->getDefIndex(li_->getInstructionIndex(UseMI)); + SlotIndex DefIdx = + li_->getInstructionIndex(UseMI).getDefIndex(); if (const LiveRange *DLR = LI.getLiveRangeContaining(DefIdx)) { if (DLR->valno->def == DefIdx) DLR->valno->setCopy(UseMI); @@ -835,12 +837,12 @@ void SimpleRegisterCoalescing::RemoveUnnecessaryKills(unsigned Reg, if (!UseMO.isKill()) continue; MachineInstr *UseMI = UseMO.getParent(); - LiveIndex UseIdx = - li_->getUseIndex(li_->getInstructionIndex(UseMI)); + SlotIndex UseIdx = + li_->getInstructionIndex(UseMI).getUseIndex(); const LiveRange *LR = LI.getLiveRangeContaining(UseIdx); if (!LR || - (!LR->valno->isKill(li_->getNextSlot(UseIdx)) && - LR->valno->def != li_->getNextSlot(UseIdx))) { + (!LR->valno->isKill(UseIdx.getDefIndex()) && + LR->valno->def != UseIdx.getDefIndex())) { // Interesting problem. After coalescing reg1027's def and kill are both // at the same point: %reg1027,0.000000e+00 = [56,814:0) 0@70-(814) // @@ -881,16 +883,16 @@ static bool removeIntervalIfEmpty(LiveInterval &li, LiveIntervals *li_, /// Return true if live interval is removed. bool SimpleRegisterCoalescing::ShortenDeadCopyLiveRange(LiveInterval &li, MachineInstr *CopyMI) { - LiveIndex CopyIdx = li_->getInstructionIndex(CopyMI); + SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI); LiveInterval::iterator MLR = - li.FindLiveRangeContaining(li_->getDefIndex(CopyIdx)); + li.FindLiveRangeContaining(CopyIdx.getDefIndex()); if (MLR == li.end()) return false; // Already removed by ShortenDeadCopySrcLiveRange. - LiveIndex RemoveStart = MLR->start; - LiveIndex RemoveEnd = MLR->end; - LiveIndex DefIdx = li_->getDefIndex(CopyIdx); + SlotIndex RemoveStart = MLR->start; + SlotIndex RemoveEnd = MLR->end; + SlotIndex DefIdx = CopyIdx.getDefIndex(); // Remove the liverange that's defined by this. - if (RemoveStart == DefIdx && RemoveEnd == li_->getNextSlot(DefIdx)) { + if (RemoveStart == DefIdx && RemoveEnd == DefIdx.getStoreIndex()) { removeRange(li, RemoveStart, RemoveEnd, li_, tri_); return removeIntervalIfEmpty(li, li_, tri_); } @@ -901,7 +903,7 @@ bool SimpleRegisterCoalescing::ShortenDeadCopyLiveRange(LiveInterval &li, /// the val# it defines. If the live interval becomes empty, remove it as well. bool SimpleRegisterCoalescing::RemoveDeadDef(LiveInterval &li, MachineInstr *DefMI) { - LiveIndex DefIdx = li_->getDefIndex(li_->getInstructionIndex(DefMI)); + SlotIndex DefIdx = li_->getInstructionIndex(DefMI).getDefIndex(); LiveInterval::iterator MLR = li.FindLiveRangeContaining(DefIdx); if (DefIdx != MLR->valno->def) return false; @@ -912,18 +914,18 @@ bool SimpleRegisterCoalescing::RemoveDeadDef(LiveInterval &li, /// PropagateDeadness - Propagate the dead marker to the instruction which /// defines the val#. static void PropagateDeadness(LiveInterval &li, MachineInstr *CopyMI, - LiveIndex &LRStart, LiveIntervals *li_, + SlotIndex &LRStart, LiveIntervals *li_, const TargetRegisterInfo* tri_) { MachineInstr *DefMI = - li_->getInstructionFromIndex(li_->getDefIndex(LRStart)); + li_->getInstructionFromIndex(LRStart.getDefIndex()); if (DefMI && DefMI != CopyMI) { int DeadIdx = DefMI->findRegisterDefOperandIdx(li.reg, false); if (DeadIdx != -1) DefMI->getOperand(DeadIdx).setIsDead(); else DefMI->addOperand(MachineOperand::CreateReg(li.reg, - true, true, false, true)); - LRStart = li_->getNextSlot(LRStart); + /*def*/true, /*implicit*/true, /*kill*/false, /*dead*/true)); + LRStart = LRStart.getNextSlot(); } } @@ -934,8 +936,8 @@ static void PropagateDeadness(LiveInterval &li, MachineInstr *CopyMI, bool SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li, MachineInstr *CopyMI) { - LiveIndex CopyIdx = li_->getInstructionIndex(CopyMI); - if (CopyIdx == LiveIndex()) { + SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI); + if (CopyIdx == SlotIndex()) { // FIXME: special case: function live in. It can be a general case if the // first instruction index starts at > 0 value. assert(TargetRegisterInfo::isPhysicalRegister(li.reg)); @@ -948,13 +950,13 @@ SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li, } LiveInterval::iterator LR = - li.FindLiveRangeContaining(li_->getPrevSlot(CopyIdx)); + li.FindLiveRangeContaining(CopyIdx.getPrevIndex().getStoreIndex()); if (LR == li.end()) // Livein but defined by a phi. return false; - LiveIndex RemoveStart = LR->start; - LiveIndex RemoveEnd = li_->getNextSlot(li_->getDefIndex(CopyIdx)); + SlotIndex RemoveStart = LR->start; + SlotIndex RemoveEnd = CopyIdx.getStoreIndex(); if (LR->end > RemoveEnd) // More uses past this copy? Nothing to do. return false; @@ -974,7 +976,7 @@ SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li, // If the live range starts in another mbb and the copy mbb is not a fall // through mbb, then we can only cut the range from the beginning of the // copy mbb. - RemoveStart = li_->getNextSlot(li_->getMBBStartIdx(CopyMBB)); + RemoveStart = li_->getMBBStartIdx(CopyMBB).getNextIndex().getBaseIndex(); if (LR->valno->def == RemoveStart) { // If the def MI defines the val# and this copy is the only kill of the @@ -1030,14 +1032,14 @@ SimpleRegisterCoalescing::isWinToJoinVRWithSrcPhysReg(MachineInstr *CopyMI, // If the virtual register live interval extends into a loop, turn down // aggressiveness. - LiveIndex CopyIdx = - li_->getDefIndex(li_->getInstructionIndex(CopyMI)); + SlotIndex CopyIdx = + li_->getInstructionIndex(CopyMI).getDefIndex(); const MachineLoop *L = loopInfo->getLoopFor(CopyMBB); if (!L) { // Let's see if the virtual register live interval extends into the loop. LiveInterval::iterator DLR = DstInt.FindLiveRangeContaining(CopyIdx); assert(DLR != DstInt.end() && "Live range not found!"); - DLR = DstInt.FindLiveRangeContaining(li_->getNextSlot(DLR->end)); + DLR = DstInt.FindLiveRangeContaining(DLR->end.getNextSlot()); if (DLR != DstInt.end()) { CopyMBB = li_->getMBBFromIndex(DLR->start); L = loopInfo->getLoopFor(CopyMBB); @@ -1047,7 +1049,7 @@ SimpleRegisterCoalescing::isWinToJoinVRWithSrcPhysReg(MachineInstr *CopyMI, if (!L || Length <= Threshold) return true; - LiveIndex UseIdx = li_->getUseIndex(CopyIdx); + SlotIndex UseIdx = CopyIdx.getUseIndex(); LiveInterval::iterator SLR = SrcInt.FindLiveRangeContaining(UseIdx); MachineBasicBlock *SMBB = li_->getMBBFromIndex(SLR->start); if (loopInfo->getLoopFor(SMBB) != L) { @@ -1060,7 +1062,7 @@ SimpleRegisterCoalescing::isWinToJoinVRWithSrcPhysReg(MachineInstr *CopyMI, if (SuccMBB == CopyMBB) continue; if (DstInt.overlaps(li_->getMBBStartIdx(SuccMBB), - li_->getNextSlot(li_->getMBBEndIdx(SuccMBB)))) + li_->getMBBEndIdx(SuccMBB).getNextIndex().getBaseIndex())) return false; } } @@ -1091,12 +1093,12 @@ SimpleRegisterCoalescing::isWinToJoinVRWithDstPhysReg(MachineInstr *CopyMI, // If the virtual register live interval is defined or cross a loop, turn // down aggressiveness. - LiveIndex CopyIdx = - li_->getDefIndex(li_->getInstructionIndex(CopyMI)); - LiveIndex UseIdx = li_->getUseIndex(CopyIdx); + SlotIndex CopyIdx = + li_->getInstructionIndex(CopyMI).getDefIndex(); + SlotIndex UseIdx = CopyIdx.getUseIndex(); LiveInterval::iterator SLR = SrcInt.FindLiveRangeContaining(UseIdx); assert(SLR != SrcInt.end() && "Live range not found!"); - SLR = SrcInt.FindLiveRangeContaining(li_->getPrevSlot(SLR->start)); + SLR = SrcInt.FindLiveRangeContaining(SLR->start.getPrevSlot()); if (SLR == SrcInt.end()) return true; MachineBasicBlock *SMBB = li_->getMBBFromIndex(SLR->start); @@ -1116,7 +1118,7 @@ SimpleRegisterCoalescing::isWinToJoinVRWithDstPhysReg(MachineInstr *CopyMI, if (PredMBB == SMBB) continue; if (SrcInt.overlaps(li_->getMBBStartIdx(PredMBB), - li_->getNextSlot(li_->getMBBEndIdx(PredMBB)))) + li_->getMBBEndIdx(PredMBB).getNextIndex().getBaseIndex())) return false; } } @@ -1367,7 +1369,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { if (SrcSubIdx) SrcSubRC = SrcRC->getSubRegisterRegClass(SrcSubIdx); assert(SrcSubRC && "Illegal subregister index"); - if (!SrcSubRC->contains(DstReg)) { + if (!SrcSubRC->contains(DstSubReg)) { DEBUG(errs() << "\tIncompatible source regclass: " << tri_->getName(DstSubReg) << " not in " << SrcSubRC->getName() << ".\n"); @@ -1705,7 +1707,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { // Update the liveintervals of sub-registers. for (const unsigned *AS = tri_->getSubRegisters(DstReg); *AS; ++AS) - li_->getOrCreateInterval(*AS).MergeInClobberRanges(*ResSrcInt, + li_->getOrCreateInterval(*AS).MergeInClobberRanges(*li_, *ResSrcInt, li_->getVNInfoAllocator()); } @@ -1832,6 +1834,25 @@ static bool InVector(VNInfo *Val, const SmallVector<VNInfo*, 8> &V) { return std::find(V.begin(), V.end(), Val) != V.end(); } +static bool isValNoDefMove(const MachineInstr *MI, unsigned DR, unsigned SR, + const TargetInstrInfo *TII, + const TargetRegisterInfo *TRI) { + unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; + if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) + ; + else if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) { + DstReg = MI->getOperand(0).getReg(); + SrcReg = MI->getOperand(1).getReg(); + } else if (MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG || + MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { + DstReg = MI->getOperand(0).getReg(); + SrcReg = MI->getOperand(2).getReg(); + } else + return false; + return (SrcReg == SR || TRI->isSuperRegister(SR, SrcReg)) && + (DstReg == DR || TRI->isSuperRegister(DR, DstReg)); +} + /// RangeIsDefinedByCopyFromReg - Return true if the specified live range of /// the specified live interval is defined by a copy from the specified /// register. @@ -1848,12 +1869,9 @@ bool SimpleRegisterCoalescing::RangeIsDefinedByCopyFromReg(LiveInterval &li, // It's a sub-register live interval, we may not have precise information. // Re-compute it. MachineInstr *DefMI = li_->getInstructionFromIndex(LR->start); - unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; - if (DefMI && - tii_->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) && - DstReg == li.reg && SrcReg == Reg) { + if (DefMI && isValNoDefMove(DefMI, li.reg, Reg, tii_, tri_)) { // Cache computed info. - LR->valno->def = LR->start; + LR->valno->def = LR->start; LR->valno->setCopy(DefMI); return true; } @@ -1861,6 +1879,23 @@ bool SimpleRegisterCoalescing::RangeIsDefinedByCopyFromReg(LiveInterval &li, return false; } + +/// ValueLiveAt - Return true if the LiveRange pointed to by the given +/// iterator, or any subsequent range with the same value number, +/// is live at the given point. +bool SimpleRegisterCoalescing::ValueLiveAt(LiveInterval::iterator LRItr, + LiveInterval::iterator LREnd, + SlotIndex defPoint) const { + for (const VNInfo *valno = LRItr->valno; + (LRItr != LREnd) && (LRItr->valno == valno); ++LRItr) { + if (LRItr->contains(defPoint)) + return true; + } + + return false; +} + + /// SimpleJoin - Attempt to joint the specified interval into this one. The /// caller of this method must guarantee that the RHS only contains a single /// value number and that the RHS is not defined by a copy from this @@ -1907,7 +1942,7 @@ bool SimpleRegisterCoalescing::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS){ if (!RangeIsDefinedByCopyFromReg(LHS, LHSIt, RHS.reg)) return false; // Nope, bail out. - if (LHSIt->contains(RHSIt->valno->def)) + if (ValueLiveAt(LHSIt, LHS.end(), RHSIt->valno->def)) // Here is an interesting situation: // BB1: // vr1025 = copy vr1024 @@ -1945,7 +1980,7 @@ bool SimpleRegisterCoalescing::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS){ // Otherwise, if this is a copy from the RHS, mark it as being merged // in. if (RangeIsDefinedByCopyFromReg(LHS, LHSIt, RHS.reg)) { - if (LHSIt->contains(RHSIt->valno->def)) + if (ValueLiveAt(LHSIt, LHS.end(), RHSIt->valno->def)) // Here is an interesting situation: // BB1: // vr1025 = copy vr1024 @@ -2030,7 +2065,7 @@ bool SimpleRegisterCoalescing::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS){ // Update the liveintervals of sub-registers. if (TargetRegisterInfo::isPhysicalRegister(LHS.reg)) for (const unsigned *AS = tri_->getSubRegisters(LHS.reg); *AS; ++AS) - li_->getOrCreateInterval(*AS).MergeInClobberRanges(LHS, + li_->getOrCreateInterval(*AS).MergeInClobberRanges(*li_, LHS, li_->getVNInfoAllocator()); return true; @@ -2131,7 +2166,7 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS, } else { // It was defined as a copy from the LHS, find out what value # it is. RHSValNoInfo = - LHS.getLiveRangeContaining(li_->getPrevSlot(RHSValNoInfo0->def))->valno; + LHS.getLiveRangeContaining(RHSValNoInfo0->def.getPrevSlot())->valno; RHSValID = RHSValNoInfo->id; RHSVal0DefinedFromLHS = RHSValID; } @@ -2195,7 +2230,7 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS, // Figure out the value # from the RHS. LHSValsDefinedFromRHS[VNI]= - RHS.getLiveRangeContaining(li_->getPrevSlot(VNI->def))->valno; + RHS.getLiveRangeContaining(VNI->def.getPrevSlot())->valno; } // Loop over the value numbers of the RHS, seeing if any are defined from @@ -2213,7 +2248,7 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS, // Figure out the value # from the LHS. RHSValsDefinedFromLHS[VNI]= - LHS.getLiveRangeContaining(li_->getPrevSlot(VNI->def))->valno; + LHS.getLiveRangeContaining(VNI->def.getPrevSlot())->valno; } LHSValNoAssignments.resize(LHS.getNumValNums(), -1); @@ -2477,11 +2512,11 @@ SimpleRegisterCoalescing::differingRegisterClasses(unsigned RegA, /// lastRegisterUse - Returns the last use of the specific register between /// cycles Start and End or NULL if there are no uses. MachineOperand * -SimpleRegisterCoalescing::lastRegisterUse(LiveIndex Start, - LiveIndex End, +SimpleRegisterCoalescing::lastRegisterUse(SlotIndex Start, + SlotIndex End, unsigned Reg, - LiveIndex &UseIdx) const{ - UseIdx = LiveIndex(); + SlotIndex &UseIdx) const{ + UseIdx = SlotIndex(); if (TargetRegisterInfo::isVirtualRegister(Reg)) { MachineOperand *LastUse = NULL; for (MachineRegisterInfo::use_iterator I = mri_->use_begin(Reg), @@ -2493,22 +2528,24 @@ SimpleRegisterCoalescing::lastRegisterUse(LiveIndex Start, SrcReg == DstReg) // Ignore identity copies. continue; - LiveIndex Idx = li_->getInstructionIndex(UseMI); + SlotIndex Idx = li_->getInstructionIndex(UseMI); + // FIXME: Should this be Idx != UseIdx? SlotIndex() will return something + // that compares higher than any other interval. if (Idx >= Start && Idx < End && Idx >= UseIdx) { LastUse = &Use; - UseIdx = li_->getUseIndex(Idx); + UseIdx = Idx.getUseIndex(); } } return LastUse; } - LiveIndex s = Start; - LiveIndex e = li_->getBaseIndex(li_->getPrevSlot(End)); + SlotIndex s = Start; + SlotIndex e = End.getPrevSlot().getBaseIndex(); while (e >= s) { // Skip deleted instructions MachineInstr *MI = li_->getInstructionFromIndex(e); - while (e != LiveIndex() && li_->getPrevIndex(e) >= s && !MI) { - e = li_->getPrevIndex(e); + while (e != SlotIndex() && e.getPrevIndex() >= s && !MI) { + e = e.getPrevIndex(); MI = li_->getInstructionFromIndex(e); } if (e < s || MI == NULL) @@ -2522,12 +2559,12 @@ SimpleRegisterCoalescing::lastRegisterUse(LiveIndex Start, MachineOperand &Use = MI->getOperand(i); if (Use.isReg() && Use.isUse() && Use.getReg() && tri_->regsOverlap(Use.getReg(), Reg)) { - UseIdx = li_->getUseIndex(e); + UseIdx = e.getUseIndex(); return &Use; } } - e = li_->getPrevIndex(e); + e = e.getPrevIndex(); } return NULL; @@ -2551,24 +2588,30 @@ void SimpleRegisterCoalescing::releaseMemory() { static bool isZeroLengthInterval(LiveInterval *li, LiveIntervals *li_) { for (LiveInterval::Ranges::const_iterator i = li->ranges.begin(), e = li->ranges.end(); i != e; ++i) - if (li_->getPrevIndex(i->end) > i->start) + if (i->end.getPrevIndex() > i->start) return false; return true; } + void SimpleRegisterCoalescing::CalculateSpillWeights() { SmallSet<unsigned, 4> Processed; for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end(); mbbi != mbbe; ++mbbi) { MachineBasicBlock* MBB = mbbi; - LiveIndex MBBEnd = li_->getMBBEndIdx(MBB); + SlotIndex MBBEnd = li_->getMBBEndIdx(MBB); MachineLoop* loop = loopInfo->getLoopFor(MBB); unsigned loopDepth = loop ? loop->getLoopDepth() : 0; - bool isExit = loop ? loop->isLoopExit(MBB) : false; + bool isExiting = loop ? loop->isLoopExiting(MBB) : false; - for (MachineBasicBlock::iterator mii = MBB->begin(), mie = MBB->end(); + for (MachineBasicBlock::const_iterator mii = MBB->begin(), mie = MBB->end(); mii != mie; ++mii) { - MachineInstr *MI = mii; + const MachineInstr *MI = mii; + if (tii_->isIdentityCopy(*MI)) + continue; + + if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) + continue; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &mopi = MI->getOperand(i); @@ -2596,10 +2639,9 @@ void SimpleRegisterCoalescing::CalculateSpillWeights() { LiveInterval &RegInt = li_->getInterval(Reg); float Weight = li_->getSpillWeight(HasDef, HasUse, loopDepth); - if (HasDef && isExit) { + if (HasDef && isExiting) { // Looks like this is a loop count variable update. - LiveIndex DefIdx = - li_->getDefIndex(li_->getInstructionIndex(MI)); + SlotIndex DefIdx = li_->getInstructionIndex(MI).getDefIndex(); const LiveRange *DLR = li_->getInterval(Reg).getLiveRangeContaining(DefIdx); if (DLR->end > MBBEnd) @@ -2706,7 +2748,7 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) { // registers unless the definition is dead. e.g. // %DO<def> = INSERT_SUBREG %D0<undef>, %S0<kill>, 1 // or else the scavenger may complain. LowerSubregs will - // change this to an IMPLICIT_DEF later. + // delete them later. DoDelete = false; } if (MI->registerDefIsDead(DstReg)) { diff --git a/lib/CodeGen/SimpleRegisterCoalescing.h b/lib/CodeGen/SimpleRegisterCoalescing.h index 3ebe3a1..78f8a9a 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.h +++ b/lib/CodeGen/SimpleRegisterCoalescing.h @@ -146,7 +146,7 @@ namespace llvm { /// TrimLiveIntervalToLastUse - If there is a last use in the same basic /// block as the copy instruction, trim the ive interval to the last use /// and return true. - bool TrimLiveIntervalToLastUse(LiveIndex CopyIdx, + bool TrimLiveIntervalToLastUse(SlotIndex CopyIdx, MachineBasicBlock *CopyMBB, LiveInterval &li, const LiveRange *LR); @@ -201,6 +201,12 @@ namespace llvm { bool CanJoinInsertSubRegToPhysReg(unsigned DstReg, unsigned SrcReg, unsigned SubIdx, unsigned &RealDstReg); + /// ValueLiveAt - Return true if the LiveRange pointed to by the given + /// iterator, or any subsequent range with the same value number, + /// is live at the given point. + bool ValueLiveAt(LiveInterval::iterator LRItr, LiveInterval::iterator LREnd, + SlotIndex defPoint) const; + /// RangeIsDefinedByCopyFromReg - Return true if the specified live range of /// the specified live interval is defined by a copy from the specified /// register. @@ -235,9 +241,8 @@ namespace llvm { /// lastRegisterUse - Returns the last use of the specific register between /// cycles Start and End or NULL if there are no uses. - MachineOperand *lastRegisterUse(LiveIndex Start, - LiveIndex End, unsigned Reg, - LiveIndex &LastUseIdx) const; + MachineOperand *lastRegisterUse(SlotIndex Start, SlotIndex End, + unsigned Reg, SlotIndex &LastUseIdx) const; /// CalculateSpillWeights - Compute spill weights for all virtual register /// live intervals. diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp index e987fa2..6de03e1 100644 --- a/lib/CodeGen/SjLjEHPrepare.cpp +++ b/lib/CodeGen/SjLjEHPrepare.cpp @@ -27,7 +27,6 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetLowering.h" @@ -38,7 +37,7 @@ STATISTIC(NumUnwinds, "Number of unwinds replaced"); STATISTIC(NumSpilled, "Number of registers live across unwind edges"); namespace { - class VISIBILITY_HIDDEN SjLjEHPass : public FunctionPass { + class SjLjEHPass : public FunctionPass { const TargetLowering *TLI; diff --git a/lib/CodeGen/SlotIndexes.cpp b/lib/CodeGen/SlotIndexes.cpp new file mode 100644 index 0000000..6b04029 --- /dev/null +++ b/lib/CodeGen/SlotIndexes.cpp @@ -0,0 +1,189 @@ +//===-- SlotIndexes.cpp - Slot Indexes Pass ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "slotindexes" + +#include "llvm/CodeGen/SlotIndexes.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +std::auto_ptr<IndexListEntry> SlotIndex::emptyKeyPtr(0), + SlotIndex::tombstoneKeyPtr(0); + +char SlotIndexes::ID = 0; +static RegisterPass<SlotIndexes> X("slotindexes", "Slot index numbering"); + +void SlotIndexes::getAnalysisUsage(AnalysisUsage &au) const { + au.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(au); +} + +void SlotIndexes::releaseMemory() { + mi2iMap.clear(); + mbb2IdxMap.clear(); + idx2MBBMap.clear(); + terminatorGaps.clear(); + clearList(); +} + +bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) { + + // Compute numbering as follows: + // Grab an iterator to the start of the index list. + // Iterate over all MBBs, and within each MBB all MIs, keeping the MI + // iterator in lock-step (though skipping it over indexes which have + // null pointers in the instruction field). + // At each iteration assert that the instruction pointed to in the index + // is the same one pointed to by the MI iterator. This + + // FIXME: This can be simplified. The mi2iMap_, Idx2MBBMap, etc. should + // only need to be set up once after the first numbering is computed. + + mf = &fn; + initList(); + + const unsigned gap = 1; + + // Check that the list contains only the sentinal. + assert(indexListHead->getNext() == 0 && + "Index list non-empty at initial numbering?"); + assert(idx2MBBMap.empty() && + "Index -> MBB mapping non-empty at initial numbering?"); + assert(mbb2IdxMap.empty() && + "MBB -> Index mapping non-empty at initial numbering?"); + assert(mi2iMap.empty() && + "MachineInstr -> Index mapping non-empty at initial numbering?"); + + functionSize = 0; + /* + for (unsigned s = 0; s < SlotIndex::NUM; ++s) { + indexList.push_back(createEntry(0, s)); + } + + unsigned index = gap * SlotIndex::NUM; + */ + + unsigned index = 0; + + // Iterate over the the function. + for (MachineFunction::iterator mbbItr = mf->begin(), mbbEnd = mf->end(); + mbbItr != mbbEnd; ++mbbItr) { + MachineBasicBlock *mbb = &*mbbItr; + + // Insert an index for the MBB start. + push_back(createEntry(0, index)); + SlotIndex blockStartIndex(back(), SlotIndex::LOAD); + + index += gap * SlotIndex::NUM; + + for (MachineBasicBlock::iterator miItr = mbb->begin(), miEnd = mbb->end(); + miItr != miEnd; ++miItr) { + MachineInstr *mi = &*miItr; + + if (miItr == mbb->getFirstTerminator()) { + push_back(createEntry(0, index)); + terminatorGaps.insert( + std::make_pair(mbb, SlotIndex(back(), SlotIndex::PHI_BIT))); + index += gap * SlotIndex::NUM; + } + + // Insert a store index for the instr. + push_back(createEntry(mi, index)); + + // Save this base index in the maps. + mi2iMap.insert( + std::make_pair(mi, SlotIndex(back(), SlotIndex::LOAD))); + + ++functionSize; + + unsigned Slots = mi->getDesc().getNumDefs(); + if (Slots == 0) + Slots = 1; + + index += (Slots + 1) * gap * SlotIndex::NUM; + } + + if (mbb->getFirstTerminator() == mbb->end()) { + push_back(createEntry(0, index)); + terminatorGaps.insert( + std::make_pair(mbb, SlotIndex(back(), SlotIndex::PHI_BIT))); + index += gap * SlotIndex::NUM; + } + + SlotIndex blockEndIndex(back(), SlotIndex::STORE); + mbb2IdxMap.insert( + std::make_pair(mbb, std::make_pair(blockStartIndex, blockEndIndex))); + + idx2MBBMap.push_back(IdxMBBPair(blockStartIndex, mbb)); + } + + // One blank instruction at the end. + push_back(createEntry(0, index)); + + // Sort the Idx2MBBMap + std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); + + DEBUG(dump()); + + // And we're done! + return false; +} + +void SlotIndexes::renumber() { + assert(false && "SlotIndexes::runmuber is not fully implemented yet."); + + // Compute numbering as follows: + // Grab an iterator to the start of the index list. + // Iterate over all MBBs, and within each MBB all MIs, keeping the MI + // iterator in lock-step (though skipping it over indexes which have + // null pointers in the instruction field). + // At each iteration assert that the instruction pointed to in the index + // is the same one pointed to by the MI iterator. This + + // FIXME: This can be simplified. The mi2iMap_, Idx2MBBMap, etc. should + // only need to be set up once - when the first numbering is computed. + + assert(false && "Renumbering not supported yet."); +} + +void SlotIndexes::dump() const { + for (const IndexListEntry *itr = front(); itr != getTail(); + itr = itr->getNext()) { + errs() << itr->getIndex() << " "; + + if (itr->getInstr() != 0) { + errs() << *itr->getInstr(); + } else { + errs() << "\n"; + } + } + + for (MBB2IdxMap::iterator itr = mbb2IdxMap.begin(); + itr != mbb2IdxMap.end(); ++itr) { + errs() << "MBB " << itr->first->getNumber() << " (" << itr->first << ") - [" + << itr->second.first << ", " << itr->second.second << "]\n"; + } +} + +// Print a SlotIndex to a raw_ostream. +void SlotIndex::print(raw_ostream &os) const { + os << getIndex(); + if (isPHI()) + os << "*"; +} + +// Dump a SlotIndex to stderr. +void SlotIndex::dump() const { + print(errs()); + errs() << "\n"; +} + diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp index 0277d64..95e85be 100644 --- a/lib/CodeGen/Spiller.cpp +++ b/lib/CodeGen/Spiller.cpp @@ -51,13 +51,15 @@ protected: /// Ensures there is space before the given machine instruction, returns the /// instruction's new number. - LiveIndex makeSpaceBefore(MachineInstr *mi) { + SlotIndex makeSpaceBefore(MachineInstr *mi) { if (!lis->hasGapBeforeInstr(lis->getInstructionIndex(mi))) { - lis->scaleNumbering(2); - ls->scaleNumbering(2); + // FIXME: Should be updated to use rewrite-in-place methods when they're + // introduced. Currently broken. + //lis->scaleNumbering(2); + //ls->scaleNumbering(2); } - LiveIndex miIdx = lis->getInstructionIndex(mi); + SlotIndex miIdx = lis->getInstructionIndex(mi); assert(lis->hasGapBeforeInstr(miIdx)); @@ -66,13 +68,15 @@ protected: /// Ensure there is space after the given machine instruction, returns the /// instruction's new number. - LiveIndex makeSpaceAfter(MachineInstr *mi) { + SlotIndex makeSpaceAfter(MachineInstr *mi) { if (!lis->hasGapAfterInstr(lis->getInstructionIndex(mi))) { - lis->scaleNumbering(2); - ls->scaleNumbering(2); + // FIXME: Should be updated to use rewrite-in-place methods when they're + // introduced. Currently broken. + // lis->scaleNumbering(2); + // ls->scaleNumbering(2); } - LiveIndex miIdx = lis->getInstructionIndex(mi); + SlotIndex miIdx = lis->getInstructionIndex(mi); assert(lis->hasGapAfterInstr(miIdx)); @@ -83,19 +87,19 @@ protected: /// after the given instruction. Returns the base index of the inserted /// instruction. The caller is responsible for adding an appropriate /// LiveInterval to the LiveIntervals analysis. - LiveIndex insertStoreAfter(MachineInstr *mi, unsigned ss, + SlotIndex insertStoreAfter(MachineInstr *mi, unsigned ss, unsigned vreg, const TargetRegisterClass *trc) { MachineBasicBlock::iterator nextInstItr(next(mi)); - LiveIndex miIdx = makeSpaceAfter(mi); + SlotIndex miIdx = makeSpaceAfter(mi); tii->storeRegToStackSlot(*mi->getParent(), nextInstItr, vreg, true, ss, trc); MachineBasicBlock::iterator storeInstItr(next(mi)); MachineInstr *storeInst = &*storeInstItr; - LiveIndex storeInstIdx = lis->getNextIndex(miIdx); + SlotIndex storeInstIdx = miIdx.getNextIndex(); assert(lis->getInstructionFromIndex(storeInstIdx) == 0 && "Store inst index already in use."); @@ -108,15 +112,15 @@ protected: /// Insert a store of the given vreg to the given stack slot immediately /// before the given instructnion. Returns the base index of the inserted /// Instruction. - LiveIndex insertStoreBefore(MachineInstr *mi, unsigned ss, + SlotIndex insertStoreBefore(MachineInstr *mi, unsigned ss, unsigned vreg, const TargetRegisterClass *trc) { - LiveIndex miIdx = makeSpaceBefore(mi); + SlotIndex miIdx = makeSpaceBefore(mi); tii->storeRegToStackSlot(*mi->getParent(), mi, vreg, true, ss, trc); MachineBasicBlock::iterator storeInstItr(prior(mi)); MachineInstr *storeInst = &*storeInstItr; - LiveIndex storeInstIdx = lis->getPrevIndex(miIdx); + SlotIndex storeInstIdx = miIdx.getPrevIndex(); assert(lis->getInstructionFromIndex(storeInstIdx) == 0 && "Store inst index already in use."); @@ -131,9 +135,9 @@ protected: unsigned vreg, const TargetRegisterClass *trc) { - LiveIndex storeInstIdx = insertStoreAfter(mi, ss, vreg, trc); - LiveIndex start = lis->getDefIndex(lis->getInstructionIndex(mi)), - end = lis->getUseIndex(storeInstIdx); + SlotIndex storeInstIdx = insertStoreAfter(mi, ss, vreg, trc); + SlotIndex start = lis->getInstructionIndex(mi).getDefIndex(), + end = storeInstIdx.getUseIndex(); VNInfo *vni = li->getNextValue(storeInstIdx, 0, true, lis->getVNInfoAllocator()); @@ -149,18 +153,18 @@ protected: /// after the given instruction. Returns the base index of the inserted /// instruction. The caller is responsibel for adding/removing an appropriate /// range vreg's LiveInterval. - LiveIndex insertLoadAfter(MachineInstr *mi, unsigned ss, + SlotIndex insertLoadAfter(MachineInstr *mi, unsigned ss, unsigned vreg, const TargetRegisterClass *trc) { MachineBasicBlock::iterator nextInstItr(next(mi)); - LiveIndex miIdx = makeSpaceAfter(mi); + SlotIndex miIdx = makeSpaceAfter(mi); tii->loadRegFromStackSlot(*mi->getParent(), nextInstItr, vreg, ss, trc); MachineBasicBlock::iterator loadInstItr(next(mi)); MachineInstr *loadInst = &*loadInstItr; - LiveIndex loadInstIdx = lis->getNextIndex(miIdx); + SlotIndex loadInstIdx = miIdx.getNextIndex(); assert(lis->getInstructionFromIndex(loadInstIdx) == 0 && "Store inst index already in use."); @@ -174,15 +178,15 @@ protected: /// before the given instruction. Returns the base index of the inserted /// instruction. The caller is responsible for adding an appropriate /// LiveInterval to the LiveIntervals analysis. - LiveIndex insertLoadBefore(MachineInstr *mi, unsigned ss, + SlotIndex insertLoadBefore(MachineInstr *mi, unsigned ss, unsigned vreg, const TargetRegisterClass *trc) { - LiveIndex miIdx = makeSpaceBefore(mi); + SlotIndex miIdx = makeSpaceBefore(mi); tii->loadRegFromStackSlot(*mi->getParent(), mi, vreg, ss, trc); MachineBasicBlock::iterator loadInstItr(prior(mi)); MachineInstr *loadInst = &*loadInstItr; - LiveIndex loadInstIdx = lis->getPrevIndex(miIdx); + SlotIndex loadInstIdx = miIdx.getPrevIndex(); assert(lis->getInstructionFromIndex(loadInstIdx) == 0 && "Load inst index already in use."); @@ -197,9 +201,9 @@ protected: unsigned vreg, const TargetRegisterClass *trc) { - LiveIndex loadInstIdx = insertLoadBefore(mi, ss, vreg, trc); - LiveIndex start = lis->getDefIndex(loadInstIdx), - end = lis->getUseIndex(lis->getInstructionIndex(mi)); + SlotIndex loadInstIdx = insertLoadBefore(mi, ss, vreg, trc); + SlotIndex start = loadInstIdx.getDefIndex(), + end = lis->getInstructionIndex(mi).getUseIndex(); VNInfo *vni = li->getNextValue(loadInstIdx, 0, true, lis->getVNInfoAllocator()); @@ -321,21 +325,21 @@ public: vrm->assignVirt2StackSlot(li->reg, ss); MachineInstr *mi = 0; - LiveIndex storeIdx = LiveIndex(); + SlotIndex storeIdx = SlotIndex(); if (valno->isDefAccurate()) { // If we have an accurate def we can just grab an iterator to the instr // after the def. mi = lis->getInstructionFromIndex(valno->def); - storeIdx = lis->getDefIndex(insertStoreAfter(mi, ss, li->reg, trc)); + storeIdx = insertStoreAfter(mi, ss, li->reg, trc).getDefIndex(); } else { // if we get here we have a PHI def. mi = &lis->getMBBFromIndex(valno->def)->front(); - storeIdx = lis->getDefIndex(insertStoreBefore(mi, ss, li->reg, trc)); + storeIdx = insertStoreBefore(mi, ss, li->reg, trc).getDefIndex(); } MachineBasicBlock *defBlock = mi->getParent(); - LiveIndex loadIdx = LiveIndex(); + SlotIndex loadIdx = SlotIndex(); // Now we need to find the load... MachineBasicBlock::iterator useItr(mi); @@ -343,11 +347,11 @@ public: if (useItr != defBlock->end()) { MachineInstr *loadInst = useItr; - loadIdx = lis->getUseIndex(insertLoadBefore(loadInst, ss, li->reg, trc)); + loadIdx = insertLoadBefore(loadInst, ss, li->reg, trc).getUseIndex(); } else { MachineInstr *loadInst = &defBlock->back(); - loadIdx = lis->getUseIndex(insertLoadAfter(loadInst, ss, li->reg, trc)); + loadIdx = insertLoadAfter(loadInst, ss, li->reg, trc).getUseIndex(); } li->removeRange(storeIdx, loadIdx, true); diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index 0204969..e8ee822 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -37,7 +37,7 @@ SSPBufferSize("stack-protector-buffer-size", cl::init(8), "stack protection")); namespace { - class VISIBILITY_HIDDEN StackProtector : public FunctionPass { + class StackProtector : public FunctionPass { /// TLI - Keep a pointer of a TargetLowering to consult for determining /// target type sizes. const TargetLowering *TLI; diff --git a/lib/CodeGen/StackSlotColoring.cpp b/lib/CodeGen/StackSlotColoring.cpp index fad0808..c299192 100644 --- a/lib/CodeGen/StackSlotColoring.cpp +++ b/lib/CodeGen/StackSlotColoring.cpp @@ -22,7 +22,6 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" @@ -53,7 +52,7 @@ STATISTIC(NumStoreElim, "Number of stores eliminated"); STATISTIC(NumDead, "Number of trivially dead stack accesses eliminated"); namespace { - class VISIBILITY_HIDDEN StackSlotColoring : public MachineFunctionPass { + class StackSlotColoring : public MachineFunctionPass { bool ColorWithRegs; LiveStacks* LS; VirtRegMap* VRM; @@ -99,6 +98,8 @@ namespace { virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addRequired<SlotIndexes>(); + AU.addPreserved<SlotIndexes>(); AU.addRequired<LiveStacks>(); AU.addRequired<VirtRegMap>(); AU.addPreserved<VirtRegMap>(); diff --git a/lib/CodeGen/StrongPHIElimination.cpp b/lib/CodeGen/StrongPHIElimination.cpp index 48d6dc1..3c13906 100644 --- a/lib/CodeGen/StrongPHIElimination.cpp +++ b/lib/CodeGen/StrongPHIElimination.cpp @@ -32,12 +32,11 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/Statistic.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" using namespace llvm; namespace { - struct VISIBILITY_HIDDEN StrongPHIElimination : public MachineFunctionPass { + struct StrongPHIElimination : public MachineFunctionPass { static char ID; // Pass identification, replacement for typeid StrongPHIElimination() : MachineFunctionPass(&ID) {} @@ -73,6 +72,8 @@ namespace { virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired<MachineDominatorTree>(); + AU.addRequired<SlotIndexes>(); + AU.addPreserved<SlotIndexes>(); AU.addRequired<LiveIntervals>(); // TODO: Actually make this true. @@ -295,7 +296,7 @@ StrongPHIElimination::computeDomForest( static bool isLiveIn(unsigned r, MachineBasicBlock* MBB, LiveIntervals& LI) { LiveInterval& I = LI.getOrCreateInterval(r); - LiveIndex idx = LI.getMBBStartIdx(MBB); + SlotIndex idx = LI.getMBBStartIdx(MBB); return I.liveAt(idx); } @@ -428,7 +429,7 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { } LiveInterval& PI = LI.getOrCreateInterval(DestReg); - LiveIndex pIdx = LI.getDefIndex(LI.getInstructionIndex(P)); + SlotIndex pIdx = LI.getInstructionIndex(P).getDefIndex(); VNInfo* PVN = PI.getLiveRangeContaining(pIdx)->valno; PhiValueNumber.insert(std::make_pair(DestReg, PVN->id)); @@ -748,7 +749,7 @@ void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB, LiveInterval& I = LI.getInterval(curr.second); MachineBasicBlock::iterator term = MBB->getFirstTerminator(); - LiveIndex endIdx = LiveIndex(); + SlotIndex endIdx = SlotIndex(); if (term != MBB->end()) endIdx = LI.getInstructionIndex(term); else @@ -772,7 +773,7 @@ void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB, // Renumber the instructions so that we can perform the index computations // needed to create new live intervals. - LI.computeNumbering(); + LI.renumber(); // For copies that we inserted at the ends of predecessors, we construct // live intervals. This is pretty easy, since we know that the destination @@ -784,15 +785,15 @@ void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB, InsertedPHIDests.begin(), E = InsertedPHIDests.end(); I != E; ++I) { if (RegHandled.insert(I->first).second) { LiveInterval& Int = LI.getOrCreateInterval(I->first); - LiveIndex instrIdx = LI.getInstructionIndex(I->second); - if (Int.liveAt(LI.getDefIndex(instrIdx))) - Int.removeRange(LI.getDefIndex(instrIdx), - LI.getNextSlot(LI.getMBBEndIdx(I->second->getParent())), + SlotIndex instrIdx = LI.getInstructionIndex(I->second); + if (Int.liveAt(instrIdx.getDefIndex())) + Int.removeRange(instrIdx.getDefIndex(), + LI.getMBBEndIdx(I->second->getParent()).getNextSlot(), true); LiveRange R = LI.addLiveRangeToEndOfBlock(I->first, I->second); R.valno->setCopy(I->second); - R.valno->def = LI.getDefIndex(LI.getInstructionIndex(I->second)); + R.valno->def = LI.getInstructionIndex(I->second).getDefIndex(); } } } @@ -817,8 +818,8 @@ void StrongPHIElimination::InsertCopies(MachineDomTreeNode* MDTN, Stacks[I->getOperand(i).getReg()].size()) { // Remove the live range for the old vreg. LiveInterval& OldInt = LI.getInterval(I->getOperand(i).getReg()); - LiveInterval::iterator OldLR = OldInt.FindLiveRangeContaining( - LI.getUseIndex(LI.getInstructionIndex(I))); + LiveInterval::iterator OldLR = + OldInt.FindLiveRangeContaining(LI.getInstructionIndex(I).getUseIndex()); if (OldLR != OldInt.end()) OldInt.removeRange(*OldLR, true); @@ -830,11 +831,10 @@ void StrongPHIElimination::InsertCopies(MachineDomTreeNode* MDTN, VNInfo* FirstVN = *Int.vni_begin(); FirstVN->setHasPHIKill(false); if (I->getOperand(i).isKill()) - FirstVN->addKill( - LI.getUseIndex(LI.getInstructionIndex(I))); + FirstVN->addKill(LI.getInstructionIndex(I).getUseIndex()); LiveRange LR (LI.getMBBStartIdx(I->getParent()), - LI.getNextSlot(LI.getUseIndex(LI.getInstructionIndex(I))), + LI.getInstructionIndex(I).getUseIndex().getNextSlot(), FirstVN); Int.addRange(LR); @@ -863,14 +863,14 @@ bool StrongPHIElimination::mergeLiveIntervals(unsigned primary, LiveInterval& LHS = LI.getOrCreateInterval(primary); LiveInterval& RHS = LI.getOrCreateInterval(secondary); - LI.computeNumbering(); + LI.renumber(); DenseMap<VNInfo*, VNInfo*> VNMap; for (LiveInterval::iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { LiveRange R = *I; - LiveIndex Start = R.start; - LiveIndex End = R.end; + SlotIndex Start = R.start; + SlotIndex End = R.end; if (LHS.getLiveRangeContaining(Start)) return false; @@ -964,19 +964,19 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) { TII->copyRegToReg(*SI->second, SI->second->getFirstTerminator(), I->first, SI->first, RC, RC); - LI.computeNumbering(); + LI.renumber(); LiveInterval& Int = LI.getOrCreateInterval(I->first); - LiveIndex instrIdx = + SlotIndex instrIdx = LI.getInstructionIndex(--SI->second->getFirstTerminator()); - if (Int.liveAt(LI.getDefIndex(instrIdx))) - Int.removeRange(LI.getDefIndex(instrIdx), - LI.getNextSlot(LI.getMBBEndIdx(SI->second)), true); + if (Int.liveAt(instrIdx.getDefIndex())) + Int.removeRange(instrIdx.getDefIndex(), + LI.getMBBEndIdx(SI->second).getNextSlot(), true); LiveRange R = LI.addLiveRangeToEndOfBlock(I->first, --SI->second->getFirstTerminator()); R.valno->setCopy(--SI->second->getFirstTerminator()); - R.valno->def = LI.getDefIndex(instrIdx); + R.valno->def = instrIdx.getDefIndex(); DEBUG(errs() << "Renaming failed: " << SI->first << " -> " << I->first << "\n"); @@ -1011,7 +1011,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) { if (PI.containsOneValue()) { LI.removeInterval(DestReg); } else { - LiveIndex idx = LI.getDefIndex(LI.getInstructionIndex(PInstr)); + SlotIndex idx = LI.getInstructionIndex(PInstr).getDefIndex(); PI.removeRange(*PI.getLiveRangeContaining(idx), true); } } else { @@ -1025,7 +1025,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) { LiveInterval& InputI = LI.getInterval(reg); if (MBB != PInstr->getParent() && InputI.liveAt(LI.getMBBStartIdx(PInstr->getParent())) && - InputI.expiredAt(LI.getNextIndex(LI.getInstructionIndex(PInstr)))) + InputI.expiredAt(LI.getInstructionIndex(PInstr).getNextIndex())) InputI.removeRange(LI.getMBBStartIdx(PInstr->getParent()), LI.getInstructionIndex(PInstr), true); @@ -1033,7 +1033,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) { // If the PHI is not dead, then the valno defined by the PHI // now has an unknown def. - LiveIndex idx = LI.getDefIndex(LI.getInstructionIndex(PInstr)); + SlotIndex idx = LI.getInstructionIndex(PInstr).getDefIndex(); const LiveRange* PLR = PI.getLiveRangeContaining(idx); PLR->valno->setIsPHIDef(true); LiveRange R (LI.getMBBStartIdx(PInstr->getParent()), @@ -1045,7 +1045,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) { PInstr->eraseFromParent(); } - LI.computeNumbering(); + LI.renumber(); return true; } diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index a5a0f5b..0a6a0d7 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -39,7 +39,6 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" @@ -57,8 +56,7 @@ STATISTIC(NumReMats, "Number of instructions re-materialized"); STATISTIC(NumDeletes, "Number of dead instructions deleted"); namespace { - class VISIBILITY_HIDDEN TwoAddressInstructionPass - : public MachineFunctionPass { + class TwoAddressInstructionPass : public MachineFunctionPass { const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; MachineRegisterInfo *MRI; diff --git a/lib/CodeGen/UnreachableBlockElim.cpp b/lib/CodeGen/UnreachableBlockElim.cpp index e7c3412..6ab5db2 100644 --- a/lib/CodeGen/UnreachableBlockElim.cpp +++ b/lib/CodeGen/UnreachableBlockElim.cpp @@ -33,14 +33,13 @@ #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/CFG.h" -#include "llvm/Support/Compiler.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SmallPtrSet.h" using namespace llvm; namespace { - class VISIBILITY_HIDDEN UnreachableBlockElim : public FunctionPass { + class UnreachableBlockElim : public FunctionPass { virtual bool runOnFunction(Function &F); public: static char ID; // Pass identification, replacement for typeid @@ -95,8 +94,7 @@ bool UnreachableBlockElim::runOnFunction(Function &F) { namespace { - class VISIBILITY_HIDDEN UnreachableMachineBlockElim : - public MachineFunctionPass { + class UnreachableMachineBlockElim : public MachineFunctionPass { virtual bool runOnMachineFunction(MachineFunction &F); virtual void getAnalysisUsage(AnalysisUsage &AU) const; MachineModuleInfo *MMI; diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index cac098b..ce3eed1 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -56,7 +56,7 @@ bool VirtRegMap::runOnMachineFunction(MachineFunction &mf) { TII = mf.getTarget().getInstrInfo(); TRI = mf.getTarget().getRegisterInfo(); MF = &mf; - + ReMatId = MAX_STACK_SLOT+1; LowSpillSlot = HighSpillSlot = NO_STACK_SLOT; diff --git a/lib/CodeGen/VirtRegMap.h b/lib/CodeGen/VirtRegMap.h index bdc2d1f..a5599f6 100644 --- a/lib/CodeGen/VirtRegMap.h +++ b/lib/CodeGen/VirtRegMap.h @@ -80,7 +80,7 @@ namespace llvm { /// Virt2SplitKillMap - This is splitted virtual register to its last use /// (kill) index mapping. - IndexedMap<LiveIndex> Virt2SplitKillMap; + IndexedMap<SlotIndex> Virt2SplitKillMap; /// ReMatMap - This is virtual register to re-materialized instruction /// mapping. Each virtual register whose definition is going to be @@ -142,7 +142,7 @@ namespace llvm { VirtRegMap() : MachineFunctionPass(&ID), Virt2PhysMap(NO_PHYS_REG), Virt2StackSlotMap(NO_STACK_SLOT), Virt2ReMatIdMap(NO_STACK_SLOT), Virt2SplitMap(0), - Virt2SplitKillMap(LiveIndex()), ReMatMap(NULL), + Virt2SplitKillMap(SlotIndex()), ReMatMap(NULL), ReMatId(MAX_STACK_SLOT+1), LowSpillSlot(NO_STACK_SLOT), HighSpillSlot(NO_STACK_SLOT) { } virtual bool runOnMachineFunction(MachineFunction &MF); @@ -266,17 +266,17 @@ namespace llvm { } /// @brief record the last use (kill) of a split virtual register. - void addKillPoint(unsigned virtReg, LiveIndex index) { + void addKillPoint(unsigned virtReg, SlotIndex index) { Virt2SplitKillMap[virtReg] = index; } - LiveIndex getKillPoint(unsigned virtReg) const { + SlotIndex getKillPoint(unsigned virtReg) const { return Virt2SplitKillMap[virtReg]; } /// @brief remove the last use (kill) of a split virtual register. void removeKillPoint(unsigned virtReg) { - Virt2SplitKillMap[virtReg] = LiveIndex(); + Virt2SplitKillMap[virtReg] = SlotIndex(); } /// @brief returns true if the specified MachineInstr is a spill point. diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp index 401bcb6..fd80f46 100644 --- a/lib/CodeGen/VirtRegRewriter.cpp +++ b/lib/CodeGen/VirtRegRewriter.cpp @@ -13,7 +13,6 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -66,7 +65,7 @@ namespace { /// This class is intended for use with the new spilling framework only. It /// rewrites vreg def/uses to use the assigned preg, but does not insert any /// spill code. -struct VISIBILITY_HIDDEN TrivialRewriter : public VirtRegRewriter { +struct TrivialRewriter : public VirtRegRewriter { bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM, LiveIntervals* LIs) { @@ -125,7 +124,7 @@ namespace { /// on a per-stack-slot / remat id basis as the low bit in the value of the /// SpillSlotsAvailable entries. The predicate 'canClobberPhysReg()' checks /// this bit and addAvailable sets it if. -class VISIBILITY_HIDDEN AvailableSpills { +class AvailableSpills { const TargetRegisterInfo *TRI; const TargetInstrInfo *TII; @@ -340,7 +339,7 @@ struct ReusedOp { /// ReuseInfo - This maintains a collection of ReuseOp's for each operand that /// is reused instead of reloaded. -class VISIBILITY_HIDDEN ReuseInfo { +class ReuseInfo { MachineInstr &MI; std::vector<ReusedOp> Reuses; BitVector PhysRegsClobbered; @@ -614,7 +613,7 @@ static void ReMaterialize(MachineBasicBlock &MBB, assert(MO.isUse()); unsigned SubIdx = MO.getSubReg(); unsigned Phys = VRM.getPhys(VirtReg); - assert(Phys); + assert(Phys && "Virtual register is not assigned a register?"); unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys; MO.setReg(RReg); MO.setSubReg(0); @@ -857,7 +856,7 @@ unsigned ReuseInfo::GetRegForReload(const TargetRegisterClass *RC, Spills.ClobberPhysReg(NewPhysReg); Spills.ClobberPhysReg(NewOp.PhysRegReused); - unsigned RReg = SubIdx ? TRI->getSubReg(NewPhysReg, SubIdx) : NewPhysReg; + unsigned RReg = SubIdx ? TRI->getSubReg(NewPhysReg, SubIdx) :NewPhysReg; MI->getOperand(NewOp.Operand).setReg(RReg); MI->getOperand(NewOp.Operand).setSubReg(0); @@ -995,7 +994,7 @@ namespace { namespace { -class VISIBILITY_HIDDEN LocalRewriter : public VirtRegRewriter { +class LocalRewriter : public VirtRegRewriter { MachineRegisterInfo *RegInfo; const TargetRegisterInfo *TRI; const TargetInstrInfo *TII; @@ -1431,8 +1430,9 @@ private: std::vector<MachineOperand*> &KillOps, VirtRegMap &VRM) { + MachineBasicBlock::iterator oldNextMII = next(MII); TII->storeRegToStackSlot(MBB, next(MII), PhysReg, true, StackSlot, RC); - MachineInstr *StoreMI = next(MII); + MachineInstr *StoreMI = prior(oldNextMII); VRM.addSpillSlotUse(StackSlot, StoreMI); DEBUG(errs() << "Store:\t" << *StoreMI); @@ -1467,7 +1467,9 @@ private: } } - LastStore = next(MII); + // Allow for multi-instruction spill sequences, as on PPC Altivec. Presume + // the last of multiple instructions is the actual store. + LastStore = prior(oldNextMII); // If the stack slot value was previously available in some other // register, change it now. Otherwise, make the register available, @@ -1749,8 +1751,9 @@ private: const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg); unsigned Phys = VRM.getPhys(VirtReg); int StackSlot = VRM.getStackSlot(VirtReg); + MachineBasicBlock::iterator oldNextMII = next(MII); TII->storeRegToStackSlot(MBB, next(MII), Phys, isKill, StackSlot, RC); - MachineInstr *StoreMI = next(MII); + MachineInstr *StoreMI = prior(oldNextMII); VRM.addSpillSlotUse(StackSlot, StoreMI); DEBUG(errs() << "Store:\t" << *StoreMI); VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod); |