1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
123
124
125
126
127
128
|
//===---- 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"
#include "llvm/ADT/SmallPtrSet.h"
namespace llvm {
class AliasAnalysis;
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_;
/// 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.
/// @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),
firstNew_(newRegs.size()), scannedRemattable_(false) {}
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(); }
unsigned size() const { return newRegs_.size()-firstNew_; }
LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; }
/// create - Create a new register with the same class and stack slot as
/// parent.
LiveInterval &create(MachineRegisterInfo&, LiveIntervals&, VirtRegMap&);
/// 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.
explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI), OrigMI(0) {}
};
/// 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 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);
}
};
}
#endif
|