Skip to content

Commit

Permalink
Recommit r265309 after fixed an invalid memory reference bug happened
Browse files Browse the repository at this point in the history
when DenseMap growed and moved memory. I verified it fixed the bootstrap
problem on x86_64-linux-gnu but I cannot verify whether it fixes
the bootstrap error on clang-ppc64be-linux. I will watch the build-bot
result closely.

Replace analyzeSiblingValues with new algorithm to fix its compile
time issue. The patch is to solve PR17409 and its duplicates.

analyzeSiblingValues is a N x N complexity algorithm where N is
the number of siblings generated by reg splitting. Although it
causes siginificant compile time issue when N is large, it is also
important for performance since it removes redundent spills and
enables rematerialization.

To solve the compile time issue, the patch removes analyzeSiblingValues
and replaces it with lower cost alternatives containing two parts. The
first part creates a new spill hoisting method in postOptimization of
register allocation. It does spill hoisting at once after all the spills
are generated instead of inside every instance of selectOrSplit. The
second part queries the define expr of the original register for
rematerializaiton and keep it always available during register allocation
even if it is already dead. It deletes those dead instructions only in
postOptimization. With the two parts in the patch, it can remove
analyzeSiblingValues without sacrificing performance.

Differential Revision: http://reviews.llvm.org/D15302

llvm-svn: 265547
  • Loading branch information
wmi-11 committed Apr 6, 2016
1 parent 506f295 commit 18293be
Show file tree
Hide file tree
Showing 16 changed files with 948 additions and 1,053 deletions.
44 changes: 35 additions & 9 deletions llvm/include/llvm/CodeGen/LiveRangeEdit.h
Expand Up @@ -72,6 +72,10 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate {
/// ScannedRemattable - true when remattable values have been identified.
bool ScannedRemattable;

/// DeadRemats - The saved instructions which have already been dead after
/// rematerialization but not deleted yet -- to be done in postOptimization.
SmallPtrSet<MachineInstr *, 32> *DeadRemats;

/// Remattable - Values defined by remattable instructions as identified by
/// tii.isTriviallyReMaterializable().
SmallPtrSet<const VNInfo*,4> Remattable;
Expand Down Expand Up @@ -116,13 +120,16 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate {
/// @param vrm Map of virtual registers to physical registers for this
/// function. If NULL, no virtual register map updates will
/// be done. This could be the case if called before Regalloc.
/// @param deadRemats The collection of all the instructions defining an
/// original reg and are dead after remat.
LiveRangeEdit(LiveInterval *parent, SmallVectorImpl<unsigned> &newRegs,
MachineFunction &MF, LiveIntervals &lis, VirtRegMap *vrm,
Delegate *delegate = nullptr)
Delegate *delegate = nullptr,
SmallPtrSet<MachineInstr *, 32> *deadRemats = nullptr)
: Parent(parent), NewRegs(newRegs), MRI(MF.getRegInfo()), LIS(lis),
VRM(vrm), TII(*MF.getSubtarget().getInstrInfo()),
TheDelegate(delegate), FirstNew(newRegs.size()),
ScannedRemattable(false) {
VRM(vrm), TII(*MF.getSubtarget().getInstrInfo()), TheDelegate(delegate),
FirstNew(newRegs.size()), ScannedRemattable(false),
DeadRemats(deadRemats) {
MRI.setDelegate(this);
}

Expand All @@ -142,6 +149,16 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate {
bool empty() const { return size() == 0; }
unsigned get(unsigned idx) const { return NewRegs[idx+FirstNew]; }

/// pop_back - It allows LiveRangeEdit users to drop new registers.
/// The context is when an original def instruction of a register is
/// dead after rematerialization, we still want to keep it for following
/// rematerializations. We save the def instruction in DeadRemats,
/// and replace the original dst register with a new dummy register so
/// the live range of original dst register can be shrinked normally.
/// We don't want to allocate phys register for the dummy register, so
/// we want to drop it from the NewRegs set.
void pop_back() { NewRegs.pop_back(); }

ArrayRef<unsigned> regs() const {
return makeArrayRef(NewRegs).slice(FirstNew);
}
Expand Down Expand Up @@ -175,15 +192,15 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate {
/// Remat - Information needed to rematerialize at a specific location.
struct Remat {
VNInfo *ParentVNI; // parent_'s value at the remat location.
MachineInstr *OrigMI; // Instruction defining ParentVNI.
MachineInstr *OrigMI; // Instruction defining OrigVNI. It contains the
// real expr for remat.
explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI), OrigMI(nullptr) {}
};

/// canRematerializeAt - Determine if ParentVNI can be rematerialized at
/// UseIdx. It is assumed that parent_.getVNINfoAt(UseIdx) == ParentVNI.
/// When cheapAsAMove is set, only cheap remats are allowed.
bool canRematerializeAt(Remat &RM,
SlotIndex UseIdx,
bool canRematerializeAt(Remat &RM, VNInfo *OrigVNI, SlotIndex UseIdx,
bool cheapAsAMove);

/// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an
Expand All @@ -208,6 +225,12 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate {
return Rematted.count(ParentVNI);
}

void markDeadRemat(MachineInstr *inst) {
// DeadRemats is an optional field.
if (DeadRemats)
DeadRemats->insert(inst);
}

/// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try
/// to erase it from LIS.
void eraseVirtReg(unsigned Reg);
Expand All @@ -218,8 +241,11 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate {
/// RegsBeingSpilled lists registers currently being spilled by the register
/// allocator. These registers should not be split into new intervals
/// as currently those new intervals are not guaranteed to spill.
void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
ArrayRef<unsigned> RegsBeingSpilled = None);
/// NoSplit indicates this func is used after the iterations of selectOrSplit
/// where registers should not be split into new intervals.
void eliminateDeadDefs(SmallVectorImpl<MachineInstr *> &Dead,
ArrayRef<unsigned> RegsBeingSpilled = None,
bool NoSplit = false);

/// calculateRegClassAndHint - Recompute register class and hint for each new
/// register.
Expand Down

0 comments on commit 18293be

Please sign in to comment.