Newer
Older
Jakob Stoklund Olesen
committed
//===---- LiveRangeEdit.h - Basic tools for split and spill -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The LiveRangeEdit class represents changes done to a virtual register when it
// is spilled or split.
//
// The parent register is never changed. Instead, a number of new virtual
// registers are created and added to the newRegs vector.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_LIVERANGEEDIT_H
#define LLVM_CODEGEN_LIVERANGEEDIT_H
#include "llvm/CodeGen/LiveInterval.h"
Jakob Stoklund Olesen
committed
#include "llvm/ADT/SmallPtrSet.h"
Jakob Stoklund Olesen
committed
namespace llvm {
Jakob Stoklund Olesen
committed
class AliasAnalysis;
Jakob Stoklund Olesen
committed
class LiveIntervals;
class MachineRegisterInfo;
class VirtRegMap;
class LiveRangeEdit {
LiveInterval &parent_;
SmallVectorImpl<LiveInterval*> &newRegs_;
const SmallVectorImpl<LiveInterval*> &uselessRegs_;
/// firstNew_ - Index of the first register added to newRegs_.
const unsigned firstNew_;
Jakob Stoklund Olesen
committed
/// 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);
Jakob Stoklund Olesen
committed
public:
/// Create a LiveRangeEdit for breaking down parent into smaller pieces.
/// @param parent The register being spilled or split.
/// @param newRegs List to receive any new registers created. This needn't be
/// empty initially, any existing registers are ignored.
/// @param uselessRegs List of registers that can't be used when
/// rematerializing values because they are about to be removed.
LiveRangeEdit(LiveInterval &parent,
SmallVectorImpl<LiveInterval*> &newRegs,
const SmallVectorImpl<LiveInterval*> &uselessRegs)
: parent_(parent), newRegs_(newRegs), uselessRegs_(uselessRegs),
Jakob Stoklund Olesen
committed
firstNew_(newRegs.size()), scannedRemattable_(false) {}
Jakob Stoklund Olesen
committed
LiveInterval &getParent() const { return parent_; }
unsigned getReg() const { return parent_.reg; }
/// Iterator for accessing the new registers added by this edit.
typedef SmallVectorImpl<LiveInterval*>::const_iterator iterator;
iterator begin() const { return newRegs_.begin()+firstNew_; }
iterator end() const { return newRegs_.end(); }
Jakob Stoklund Olesen
committed
unsigned size() const { return newRegs_.size()-firstNew_; }
LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; }
Jakob Stoklund Olesen
committed
/// assignStackSlot - Ensure a stack slot is assigned to parent.
/// @return the assigned stack slot number.
int assignStackSlot(VirtRegMap&);
/// create - Create a new register with the same class and stack slot as
/// parent.
Jakob Stoklund Olesen
committed
LiveInterval &create(MachineRegisterInfo&, LiveIntervals&, VirtRegMap&);
Jakob Stoklund Olesen
committed
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/// 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&);
Jakob Stoklund Olesen
committed
Jakob Stoklund Olesen
committed
/// didRematerialize - Return true if ParentVNI was rematerialized anywhere.
bool didRematerialize(VNInfo *ParentVNI) const {
return rematted_.count(ParentVNI);
}