Move some of the InlineSpiller rematerialization code into LiveRangeEdit.
llvm-svn: 116951
diff --git a/llvm/lib/CodeGen/LiveRangeEdit.h b/llvm/lib/CodeGen/LiveRangeEdit.h
index d9d9c61..d6ba256 100644
--- a/llvm/lib/CodeGen/LiveRangeEdit.h
+++ b/llvm/lib/CodeGen/LiveRangeEdit.h
@@ -19,9 +19,11 @@
#define LLVM_CODEGEN_LIVERANGEEDIT_H
#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/ADT/SmallPtrSet.h"
namespace llvm {
+class AliasAnalysis;
class LiveIntervals;
class MachineRegisterInfo;
class VirtRegMap;
@@ -34,6 +36,27 @@
/// firstNew_ - Index of the first register added to newRegs_.
const unsigned firstNew_;
+ /// scannedRemattable_ - true when remattable values have been identified.
+ bool scannedRemattable_;
+
+ /// remattable_ - Values defined by remattable instructions as identified by
+ /// tii.isTriviallyReMaterializable().
+ SmallPtrSet<VNInfo*,4> remattable_;
+
+ /// rematted_ - Values that were actually rematted, and so need to have their
+ /// live range trimmed or entirely removed.
+ SmallPtrSet<VNInfo*,4> rematted_;
+
+ /// scanRemattable - Identify the parent_ values that may rematerialize.
+ void scanRemattable(LiveIntervals &lis,
+ const TargetInstrInfo &tii,
+ AliasAnalysis *aa);
+
+ /// allUsesAvailableAt - Return true if all registers used by OrigMI at
+ /// OrigIdx are also available with the same value at UseIdx.
+ bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx,
+ SlotIndex UseIdx, LiveIntervals &lis);
+
public:
/// Create a LiveRangeEdit for breaking down parent into smaller pieces.
/// @param parent The register being spilled or split.
@@ -45,7 +68,7 @@
SmallVectorImpl<LiveInterval*> &newRegs,
const SmallVectorImpl<LiveInterval*> &uselessRegs)
: parent_(parent), newRegs_(newRegs), uselessRegs_(uselessRegs),
- firstNew_(newRegs.size()) {}
+ firstNew_(newRegs.size()), scannedRemattable_(false) {}
LiveInterval &getParent() const { return parent_; }
unsigned getReg() const { return parent_.reg; }
@@ -63,11 +86,43 @@
/// parent.
LiveInterval &create(MachineRegisterInfo&, LiveIntervals&, VirtRegMap&);
- /// allUsesAvailableAt - Return true if all registers used by OrigMI at
- /// OrigIdx are also available with the same value at UseIdx.
- bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx,
- SlotIndex UseIdx, LiveIntervals &lis);
+ /// anyRematerializable - Return true if any parent values may be
+ /// rematerializable.
+ /// This function must be called before ny rematerialization is attempted.
+ bool anyRematerializable(LiveIntervals&, const TargetInstrInfo&,
+ AliasAnalysis*);
+ /// 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.
+ operator bool() const { return OrigMI; }
+ };
+
+ /// 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.
+ Remat canRematerializeAt(VNInfo *ParentVNI,
+ SlotIndex UseIdx,
+ bool cheapAsAMove,
+ LiveIntervals &lis);
+
+ /// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an
+ /// instruction into MBB before MI. The new instruction is mapped, but
+ /// liveness is not updated.
+ /// Return the SlotIndex of the new instruction.
+ SlotIndex rematerializeAt(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned DestReg,
+ const Remat &RM,
+ LiveIntervals&,
+ const TargetInstrInfo&,
+ const TargetRegisterInfo&);
+
+ /// didRematerialize - Return true if ParentVNI was rematerialized anywhere.
+ bool didRematerialize(VNInfo *ParentVNI) const {
+ return rematted_.count(ParentVNI);
+ }
};
}