summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-11-04 14:58:56 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-11-04 14:58:56 +0000
commit7ff99155c39edd73ebf1c6adfa023b1048fee9a4 (patch)
treeb4dc751bcee540346911aa4115729eff2f991657 /lib/CodeGen
parentd1f06de484602e72707476a6152974847bac1570 (diff)
downloadFreeBSD-src-7ff99155c39edd73ebf1c6adfa023b1048fee9a4.zip
FreeBSD-src-7ff99155c39edd73ebf1c6adfa023b1048fee9a4.tar.gz
Update LLVM to r86025.
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/AggressiveAntiDepBreaker.cpp794
-rw-r--r--lib/CodeGen/AggressiveAntiDepBreaker.h176
-rw-r--r--lib/CodeGen/AntiDepBreaker.h73
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp40
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp46
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h10
-rw-r--r--lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp3
-rw-r--r--lib/CodeGen/BranchFolding.cpp58
-rw-r--r--lib/CodeGen/CMakeLists.txt4
-rw-r--r--lib/CodeGen/CriticalAntiDepBreaker.cpp540
-rw-r--r--lib/CodeGen/CriticalAntiDepBreaker.h103
-rw-r--r--lib/CodeGen/DeadMachineInstructionElim.cpp4
-rw-r--r--lib/CodeGen/DwarfEHPrepare.cpp3
-rw-r--r--lib/CodeGen/ELF.h2
-rw-r--r--lib/CodeGen/ExactHazardRecognizer.cpp2
-rw-r--r--lib/CodeGen/GCMetadata.cpp5
-rw-r--r--lib/CodeGen/GCStrategy.cpp5
-rw-r--r--lib/CodeGen/IfConversion.cpp2
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp69
-rw-r--r--lib/CodeGen/LatencyPriorityQueue.cpp9
-rw-r--r--lib/CodeGen/LiveInterval.cpp89
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp793
-rw-r--r--lib/CodeGen/LiveStackAnalysis.cpp9
-rw-r--r--lib/CodeGen/LowerSubregs.cpp79
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp33
-rw-r--r--lib/CodeGen/MachineFunction.cpp125
-rw-r--r--lib/CodeGen/MachineInstr.cpp49
-rw-r--r--lib/CodeGen/MachineLICM.cpp161
-rw-r--r--lib/CodeGen/MachineSink.cpp3
-rw-r--r--lib/CodeGen/MachineVerifier.cpp9
-rw-r--r--lib/CodeGen/OcamlGC.cpp3
-rw-r--r--lib/CodeGen/PostRASchedulerList.cpp747
-rw-r--r--lib/CodeGen/PreAllocSplitting.cpp200
-rw-r--r--lib/CodeGen/ProcessImplicitDefs.cpp231
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp4
-rw-r--r--lib/CodeGen/PseudoSourceValue.cpp22
-rw-r--r--lib/CodeGen/RegAllocLinearScan.cpp58
-rw-r--r--lib/CodeGen/RegAllocLocal.cpp3
-rw-r--r--lib/CodeGen/RegAllocPBQP.cpp8
-rw-r--r--lib/CodeGen/RegisterScavenging.cpp51
-rw-r--r--lib/CodeGen/ScheduleDAG.cpp16
-rw-r--r--lib/CodeGen/ScheduleDAGEmit.cpp12
-rw-r--r--lib/CodeGen/ScheduleDAGInstrs.cpp89
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp34
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.cpp10
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp13
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.cpp3
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp5
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp3
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp6
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp78
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp66
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuild.h4
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp63
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp2
-rw-r--r--lib/CodeGen/ShadowStackGC.cpp5
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.cpp234
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.h13
-rw-r--r--lib/CodeGen/SjLjEHPrepare.cpp3
-rw-r--r--lib/CodeGen/SlotIndexes.cpp189
-rw-r--r--lib/CodeGen/Spiller.cpp68
-rw-r--r--lib/CodeGen/StackProtector.cpp2
-rw-r--r--lib/CodeGen/StackSlotColoring.cpp5
-rw-r--r--lib/CodeGen/StrongPHIElimination.cpp58
-rw-r--r--lib/CodeGen/TwoAddressInstructionPass.cpp4
-rw-r--r--lib/CodeGen/UnreachableBlockElim.cpp6
-rw-r--r--lib/CodeGen/VirtRegMap.cpp2
-rw-r--r--lib/CodeGen/VirtRegMap.h10
-rw-r--r--lib/CodeGen/VirtRegRewriter.cpp23
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);
OpenPOWER on IntegriCloud