0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 //===-- llvm/CodeGen/VirtRegMap.cpp - Virtual Register Map ----------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3 // The LLVM Compiler Infrastructure
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
4 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 // This file is distributed under the University of Illinois Open Source
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 // License. See LICENSE.TXT for details.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 // This file implements the VirtRegMap class.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12 // It also contains implementations of the Spiller interface, which, given a
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13 // virtual register map and a machine function, eliminates all virtual
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 // references by replacing them with physical register references - adding spill
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
15 // code as necessary.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
16 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
19 #include "llvm/CodeGen/VirtRegMap.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
20 #include "LiveDebugVariables.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
21 #include "llvm/ADT/STLExtras.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 #include "llvm/ADT/Statistic.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
23 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
24 #include "llvm/CodeGen/LiveStackAnalysis.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
25 #include "llvm/CodeGen/MachineFrameInfo.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
26 #include "llvm/CodeGen/MachineFunction.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
27 #include "llvm/CodeGen/MachineInstrBuilder.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
28 #include "llvm/CodeGen/MachineRegisterInfo.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
29 #include "llvm/CodeGen/Passes.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
30 #include "llvm/IR/Function.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
31 #include "llvm/Support/Compiler.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
32 #include "llvm/Support/Debug.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
33 #include "llvm/Support/raw_ostream.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
34 #include "llvm/Target/TargetInstrInfo.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
35 #include "llvm/Target/TargetMachine.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
36 #include "llvm/Target/TargetRegisterInfo.h"
|
77
|
37 #include "llvm/Target/TargetSubtargetInfo.h"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
38 #include <algorithm>
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
39 using namespace llvm;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
40
|
77
|
41 #define DEBUG_TYPE "regalloc"
|
|
42
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
43 STATISTIC(NumSpillSlots, "Number of spill slots allocated");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
44 STATISTIC(NumIdCopies, "Number of identity moves eliminated after rewriting");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
45
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
46 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
47 // VirtRegMap implementation
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
48 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
49
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
50 char VirtRegMap::ID = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
51
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
52 INITIALIZE_PASS(VirtRegMap, "virtregmap", "Virtual Register Map", false, false)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
53
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
54 bool VirtRegMap::runOnMachineFunction(MachineFunction &mf) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
55 MRI = &mf.getRegInfo();
|
77
|
56 TII = mf.getSubtarget().getInstrInfo();
|
|
57 TRI = mf.getSubtarget().getRegisterInfo();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
58 MF = &mf;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
59
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
60 Virt2PhysMap.clear();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
61 Virt2StackSlotMap.clear();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
62 Virt2SplitMap.clear();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
63
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
64 grow();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
65 return false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
66 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
67
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
68 void VirtRegMap::grow() {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
69 unsigned NumRegs = MF->getRegInfo().getNumVirtRegs();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
70 Virt2PhysMap.resize(NumRegs);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
71 Virt2StackSlotMap.resize(NumRegs);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
72 Virt2SplitMap.resize(NumRegs);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
73 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
74
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
75 unsigned VirtRegMap::createSpillSlot(const TargetRegisterClass *RC) {
|
120
|
76 int SS = MF->getFrameInfo().CreateSpillStackObject(RC->getSize(),
|
|
77 RC->getAlignment());
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
78 ++NumSpillSlots;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
79 return SS;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
80 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
81
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
82 bool VirtRegMap::hasPreferredPhys(unsigned VirtReg) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
83 unsigned Hint = MRI->getSimpleHint(VirtReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
84 if (!Hint)
|
120
|
85 return false;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
86 if (TargetRegisterInfo::isVirtualRegister(Hint))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
87 Hint = getPhys(Hint);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
88 return getPhys(VirtReg) == Hint;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
89 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
90
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
91 bool VirtRegMap::hasKnownPreference(unsigned VirtReg) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
92 std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(VirtReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
93 if (TargetRegisterInfo::isPhysicalRegister(Hint.second))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
94 return true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
95 if (TargetRegisterInfo::isVirtualRegister(Hint.second))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
96 return hasPhys(Hint.second);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
97 return false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
98 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
99
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
100 int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
101 assert(TargetRegisterInfo::isVirtualRegister(virtReg));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
102 assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
103 "attempt to assign stack slot to already spilled register");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
104 const TargetRegisterClass* RC = MF->getRegInfo().getRegClass(virtReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
105 return Virt2StackSlotMap[virtReg] = createSpillSlot(RC);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
106 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
107
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
108 void VirtRegMap::assignVirt2StackSlot(unsigned virtReg, int SS) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
109 assert(TargetRegisterInfo::isVirtualRegister(virtReg));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
110 assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
111 "attempt to assign stack slot to already spilled register");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
112 assert((SS >= 0 ||
|
120
|
113 (SS >= MF->getFrameInfo().getObjectIndexBegin())) &&
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
114 "illegal fixed frame index");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
115 Virt2StackSlotMap[virtReg] = SS;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
116 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
117
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
118 void VirtRegMap::print(raw_ostream &OS, const Module*) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
119 OS << "********** REGISTER MAP **********\n";
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
120 for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
121 unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
122 if (Virt2PhysMap[Reg] != (unsigned)VirtRegMap::NO_PHYS_REG) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
123 OS << '[' << PrintReg(Reg, TRI) << " -> "
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
124 << PrintReg(Virt2PhysMap[Reg], TRI) << "] "
|
83
|
125 << TRI->getRegClassName(MRI->getRegClass(Reg)) << "\n";
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
126 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
127 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
128
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
129 for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
130 unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
131 if (Virt2StackSlotMap[Reg] != VirtRegMap::NO_STACK_SLOT) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
132 OS << '[' << PrintReg(Reg, TRI) << " -> fi#" << Virt2StackSlotMap[Reg]
|
83
|
133 << "] " << TRI->getRegClassName(MRI->getRegClass(Reg)) << "\n";
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
134 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
135 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
136 OS << '\n';
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
137 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
138
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
139 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
120
|
140 LLVM_DUMP_METHOD void VirtRegMap::dump() const {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
141 print(dbgs());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
142 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
143 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
144
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
145 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
146 // VirtRegRewriter
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
147 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
148 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
149 // The VirtRegRewriter is the last of the register allocator passes.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
150 // It rewrites virtual registers to physical registers as specified in the
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
151 // VirtRegMap analysis. It also updates live-in information on basic blocks
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
152 // according to LiveIntervals.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
153 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
154 namespace {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
155 class VirtRegRewriter : public MachineFunctionPass {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
156 MachineFunction *MF;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
157 const TargetMachine *TM;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
158 const TargetRegisterInfo *TRI;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
159 const TargetInstrInfo *TII;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
160 MachineRegisterInfo *MRI;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
161 SlotIndexes *Indexes;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
162 LiveIntervals *LIS;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
163 VirtRegMap *VRM;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
164
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
165 void rewrite();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
166 void addMBBLiveIns();
|
95
|
167 bool readsUndefSubreg(const MachineOperand &MO) const;
|
|
168 void addLiveInsForSubRanges(const LiveInterval &LI, unsigned PhysReg) const;
|
120
|
169 void handleIdentityCopy(MachineInstr &MI) const;
|
95
|
170
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
171 public:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
172 static char ID;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
173 VirtRegRewriter() : MachineFunctionPass(ID) {}
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
174
|
77
|
175 void getAnalysisUsage(AnalysisUsage &AU) const override;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
176
|
77
|
177 bool runOnMachineFunction(MachineFunction&) override;
|
120
|
178 MachineFunctionProperties getSetProperties() const override {
|
|
179 return MachineFunctionProperties().set(
|
|
180 MachineFunctionProperties::Property::NoVRegs);
|
|
181 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
182 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
183 } // end anonymous namespace
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
184
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
185 char &llvm::VirtRegRewriterID = VirtRegRewriter::ID;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
186
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
187 INITIALIZE_PASS_BEGIN(VirtRegRewriter, "virtregrewriter",
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
188 "Virtual Register Rewriter", false, false)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
189 INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
190 INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
191 INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
192 INITIALIZE_PASS_DEPENDENCY(LiveStacks)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
193 INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
194 INITIALIZE_PASS_END(VirtRegRewriter, "virtregrewriter",
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
195 "Virtual Register Rewriter", false, false)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
196
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
197 char VirtRegRewriter::ID = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
198
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
199 void VirtRegRewriter::getAnalysisUsage(AnalysisUsage &AU) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
200 AU.setPreservesCFG();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
201 AU.addRequired<LiveIntervals>();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
202 AU.addRequired<SlotIndexes>();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
203 AU.addPreserved<SlotIndexes>();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
204 AU.addRequired<LiveDebugVariables>();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
205 AU.addRequired<LiveStacks>();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
206 AU.addPreserved<LiveStacks>();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
207 AU.addRequired<VirtRegMap>();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
208 MachineFunctionPass::getAnalysisUsage(AU);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
209 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
210
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
211 bool VirtRegRewriter::runOnMachineFunction(MachineFunction &fn) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
212 MF = &fn;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
213 TM = &MF->getTarget();
|
83
|
214 TRI = MF->getSubtarget().getRegisterInfo();
|
|
215 TII = MF->getSubtarget().getInstrInfo();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
216 MRI = &MF->getRegInfo();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
217 Indexes = &getAnalysis<SlotIndexes>();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
218 LIS = &getAnalysis<LiveIntervals>();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
219 VRM = &getAnalysis<VirtRegMap>();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
220 DEBUG(dbgs() << "********** REWRITE VIRTUAL REGISTERS **********\n"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
221 << "********** Function: "
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
222 << MF->getName() << '\n');
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
223 DEBUG(VRM->dump());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
224
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
225 // Add kill flags while we still have virtual registers.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
226 LIS->addKillFlags(VRM);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
227
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
228 // Live-in lists on basic blocks are required for physregs.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
229 addMBBLiveIns();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
230
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
231 // Rewrite virtual registers.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
232 rewrite();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
233
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
234 // Write out new DBG_VALUE instructions.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
235 getAnalysis<LiveDebugVariables>().emitDebugValues(VRM);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
236
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
237 // All machine operands and other references to virtual registers have been
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
238 // replaced. Remove the virtual registers and release all the transient data.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
239 VRM->clearAllVirt();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
240 MRI->clearVirtRegs();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
241 return true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
242 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
243
|
95
|
244 void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI,
|
|
245 unsigned PhysReg) const {
|
|
246 assert(!LI.empty());
|
|
247 assert(LI.hasSubRanges());
|
|
248
|
|
249 typedef std::pair<const LiveInterval::SubRange *,
|
|
250 LiveInterval::const_iterator> SubRangeIteratorPair;
|
|
251 SmallVector<SubRangeIteratorPair, 4> SubRanges;
|
|
252 SlotIndex First;
|
|
253 SlotIndex Last;
|
|
254 for (const LiveInterval::SubRange &SR : LI.subranges()) {
|
|
255 SubRanges.push_back(std::make_pair(&SR, SR.begin()));
|
|
256 if (!First.isValid() || SR.segments.front().start < First)
|
|
257 First = SR.segments.front().start;
|
|
258 if (!Last.isValid() || SR.segments.back().end > Last)
|
|
259 Last = SR.segments.back().end;
|
|
260 }
|
|
261
|
|
262 // Check all mbb start positions between First and Last while
|
|
263 // simulatenously advancing an iterator for each subrange.
|
|
264 for (SlotIndexes::MBBIndexIterator MBBI = Indexes->findMBBIndex(First);
|
|
265 MBBI != Indexes->MBBIndexEnd() && MBBI->first <= Last; ++MBBI) {
|
|
266 SlotIndex MBBBegin = MBBI->first;
|
|
267 // Advance all subrange iterators so that their end position is just
|
|
268 // behind MBBBegin (or the iterator is at the end).
|
|
269 LaneBitmask LaneMask = 0;
|
|
270 for (auto &RangeIterPair : SubRanges) {
|
|
271 const LiveInterval::SubRange *SR = RangeIterPair.first;
|
|
272 LiveInterval::const_iterator &SRI = RangeIterPair.second;
|
|
273 while (SRI != SR->end() && SRI->end <= MBBBegin)
|
|
274 ++SRI;
|
|
275 if (SRI == SR->end())
|
|
276 continue;
|
|
277 if (SRI->start <= MBBBegin)
|
|
278 LaneMask |= SR->LaneMask;
|
|
279 }
|
|
280 if (LaneMask == 0)
|
|
281 continue;
|
|
282 MachineBasicBlock *MBB = MBBI->second;
|
|
283 MBB->addLiveIn(PhysReg, LaneMask);
|
|
284 }
|
|
285 }
|
|
286
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
287 // Compute MBB live-in lists from virtual register live ranges and their
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
288 // assignments.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
289 void VirtRegRewriter::addMBBLiveIns() {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
290 for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
291 unsigned VirtReg = TargetRegisterInfo::index2VirtReg(Idx);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
292 if (MRI->reg_nodbg_empty(VirtReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
293 continue;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
294 LiveInterval &LI = LIS->getInterval(VirtReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
295 if (LI.empty() || LIS->intervalIsInOneMBB(LI))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
296 continue;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
297 // This is a virtual register that is live across basic blocks. Its
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
298 // assigned PhysReg must be marked as live-in to those blocks.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
299 unsigned PhysReg = VRM->getPhys(VirtReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
300 assert(PhysReg != VirtRegMap::NO_PHYS_REG && "Unmapped virtual register.");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
301
|
83
|
302 if (LI.hasSubRanges()) {
|
95
|
303 addLiveInsForSubRanges(LI, PhysReg);
|
|
304 } else {
|
|
305 // Go over MBB begin positions and see if we have segments covering them.
|
|
306 // The following works because segments and the MBBIndex list are both
|
|
307 // sorted by slot indexes.
|
|
308 SlotIndexes::MBBIndexIterator I = Indexes->MBBIndexBegin();
|
|
309 for (const auto &Seg : LI) {
|
|
310 I = Indexes->advanceMBBIndex(I, Seg.start);
|
|
311 for (; I != Indexes->MBBIndexEnd() && I->first < Seg.end; ++I) {
|
|
312 MachineBasicBlock *MBB = I->second;
|
|
313 MBB->addLiveIn(PhysReg);
|
83
|
314 }
|
|
315 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
316 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
317 }
|
95
|
318
|
|
319 // Sort and unique MBB LiveIns as we've not checked if SubReg/PhysReg were in
|
|
320 // each MBB's LiveIns set before calling addLiveIn on them.
|
|
321 for (MachineBasicBlock &MBB : *MF)
|
|
322 MBB.sortUniqueLiveIns();
|
|
323 }
|
|
324
|
|
325 /// Returns true if the given machine operand \p MO only reads undefined lanes.
|
|
326 /// The function only works for use operands with a subregister set.
|
|
327 bool VirtRegRewriter::readsUndefSubreg(const MachineOperand &MO) const {
|
|
328 // Shortcut if the operand is already marked undef.
|
|
329 if (MO.isUndef())
|
|
330 return true;
|
|
331
|
|
332 unsigned Reg = MO.getReg();
|
|
333 const LiveInterval &LI = LIS->getInterval(Reg);
|
|
334 const MachineInstr &MI = *MO.getParent();
|
120
|
335 SlotIndex BaseIndex = LIS->getInstructionIndex(MI);
|
95
|
336 // This code is only meant to handle reading undefined subregisters which
|
|
337 // we couldn't properly detect before.
|
|
338 assert(LI.liveAt(BaseIndex) &&
|
|
339 "Reads of completely dead register should be marked undef already");
|
|
340 unsigned SubRegIdx = MO.getSubReg();
|
120
|
341 assert(SubRegIdx != 0 && LI.hasSubRanges());
|
95
|
342 LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(SubRegIdx);
|
|
343 // See if any of the relevant subregister liveranges is defined at this point.
|
|
344 for (const LiveInterval::SubRange &SR : LI.subranges()) {
|
|
345 if ((SR.LaneMask & UseMask) != 0 && SR.liveAt(BaseIndex))
|
|
346 return false;
|
|
347 }
|
|
348 return true;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
349 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
350
|
120
|
351 void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) const {
|
|
352 if (!MI.isIdentityCopy())
|
|
353 return;
|
|
354 DEBUG(dbgs() << "Identity copy: " << MI);
|
|
355 ++NumIdCopies;
|
|
356
|
|
357 // Copies like:
|
|
358 // %R0 = COPY %R0<undef>
|
|
359 // %AL = COPY %AL, %EAX<imp-def>
|
|
360 // give us additional liveness information: The target (super-)register
|
|
361 // must not be valid before this point. Replace the COPY with a KILL
|
|
362 // instruction to maintain this information.
|
|
363 if (MI.getOperand(0).isUndef() || MI.getNumOperands() > 2) {
|
|
364 MI.setDesc(TII->get(TargetOpcode::KILL));
|
|
365 DEBUG(dbgs() << " replace by: " << MI);
|
|
366 return;
|
|
367 }
|
|
368
|
|
369 if (Indexes)
|
|
370 Indexes->removeMachineInstrFromMaps(MI);
|
|
371 MI.eraseFromParent();
|
|
372 DEBUG(dbgs() << " deleted.\n");
|
|
373 }
|
|
374
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
375 void VirtRegRewriter::rewrite() {
|
95
|
376 bool NoSubRegLiveness = !MRI->subRegLivenessEnabled();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
377 SmallVector<unsigned, 8> SuperDeads;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
378 SmallVector<unsigned, 8> SuperDefs;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
379 SmallVector<unsigned, 8> SuperKills;
|
77
|
380
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
381 for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
382 MBBI != MBBE; ++MBBI) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
383 DEBUG(MBBI->print(dbgs(), Indexes));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
384 for (MachineBasicBlock::instr_iterator
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
385 MII = MBBI->instr_begin(), MIE = MBBI->instr_end(); MII != MIE;) {
|
95
|
386 MachineInstr *MI = &*MII;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
387 ++MII;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
388
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
389 for (MachineInstr::mop_iterator MOI = MI->operands_begin(),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
390 MOE = MI->operands_end(); MOI != MOE; ++MOI) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
391 MachineOperand &MO = *MOI;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
392
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
393 // Make sure MRI knows about registers clobbered by regmasks.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
394 if (MO.isRegMask())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
395 MRI->addPhysRegsUsedFromRegMask(MO.getRegMask());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
396
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
397 if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
398 continue;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
399 unsigned VirtReg = MO.getReg();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
400 unsigned PhysReg = VRM->getPhys(VirtReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
401 assert(PhysReg != VirtRegMap::NO_PHYS_REG &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
402 "Instruction uses unmapped VirtReg");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
403 assert(!MRI->isReserved(PhysReg) && "Reserved register assignment");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
404
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
405 // Preserve semantics of sub-register operands.
|
95
|
406 unsigned SubReg = MO.getSubReg();
|
|
407 if (SubReg != 0) {
|
|
408 if (NoSubRegLiveness) {
|
|
409 // A virtual register kill refers to the whole register, so we may
|
|
410 // have to add <imp-use,kill> operands for the super-register. A
|
|
411 // partial redef always kills and redefines the super-register.
|
|
412 if (MO.readsReg() && (MO.isDef() || MO.isKill()))
|
|
413 SuperKills.push_back(PhysReg);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
414
|
95
|
415 if (MO.isDef()) {
|
|
416 // Also add implicit defs for the super-register.
|
83
|
417 if (MO.isDead())
|
|
418 SuperDeads.push_back(PhysReg);
|
|
419 else
|
|
420 SuperDefs.push_back(PhysReg);
|
|
421 }
|
95
|
422 } else {
|
|
423 if (MO.isUse()) {
|
|
424 if (readsUndefSubreg(MO))
|
|
425 // We need to add an <undef> flag if the subregister is
|
|
426 // completely undefined (and we are not adding super-register
|
|
427 // defs).
|
|
428 MO.setIsUndef(true);
|
|
429 } else if (!MO.isDead()) {
|
|
430 assert(MO.isDef());
|
|
431 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
432 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
433
|
95
|
434 // The <def,undef> flag only makes sense for sub-register defs, and
|
|
435 // we are substituting a full physreg. An <imp-use,kill> operand
|
|
436 // from the SuperKills list will represent the partial read of the
|
|
437 // super-register.
|
|
438 if (MO.isDef())
|
|
439 MO.setIsUndef(false);
|
|
440
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
441 // PhysReg operands cannot have subregister indexes.
|
95
|
442 PhysReg = TRI->getSubReg(PhysReg, SubReg);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
443 assert(PhysReg && "Invalid SubReg for physical register");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
444 MO.setSubReg(0);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
445 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
446 // Rewrite. Note we could have used MachineOperand::substPhysReg(), but
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
447 // we need the inlining here.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
448 MO.setReg(PhysReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
449 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
450
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
451 // Add any missing super-register kills after rewriting the whole
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
452 // instruction.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
453 while (!SuperKills.empty())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
454 MI->addRegisterKilled(SuperKills.pop_back_val(), TRI, true);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
455
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
456 while (!SuperDeads.empty())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
457 MI->addRegisterDead(SuperDeads.pop_back_val(), TRI, true);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
458
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
459 while (!SuperDefs.empty())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
460 MI->addRegisterDefined(SuperDefs.pop_back_val(), TRI);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
461
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
462 DEBUG(dbgs() << "> " << *MI);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
463
|
120
|
464 // We can remove identity copies right now.
|
|
465 handleIdentityCopy(*MI);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
466 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
467 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
468 }
|