@@ -57,6 +57,108 @@ namespace {
57
57
MachineFunctionProperties::Property::NoVRegs);
58
58
}
59
59
60
+ // This function removes any redundant load immediates. It has two level
61
+ // loops - The outer loop finds the load immediates BBI that could be used
62
+ // to replace following redundancy. The inner loop scans instructions that
63
+ // after BBI to find redundancy and update kill/dead flags accordingly. If
64
+ // AfterBBI is the same as BBI, it is redundant, otherwise any instructions
65
+ // that modify the def register of BBI would break the scanning.
66
+ // DeadOrKillToUnset is a pointer to the previous operand that had the
67
+ // kill/dead flag set. It keeps track of the def register of BBI, the use
68
+ // registers of AfterBBIs and the def registers of AfterBBIs.
69
+ bool removeRedundantLIs (MachineBasicBlock &MBB,
70
+ const TargetRegisterInfo *TRI) {
71
+ LLVM_DEBUG (dbgs () << " Remove redundant load immediates from MBB:\n " ;
72
+ MBB.dump (); dbgs () << " \n " );
73
+
74
+ DenseSet<MachineInstr *> InstrsToErase;
75
+ for (auto BBI = MBB.instr_begin (); BBI != MBB.instr_end (); ++BBI) {
76
+ // Skip load immediate that is marked to be erased later because it
77
+ // cannot be used to replace any other instructions.
78
+ if (InstrsToErase.find (&*BBI) != InstrsToErase.end ())
79
+ continue ;
80
+ // Skip non-load immediate.
81
+ unsigned Opc = BBI->getOpcode ();
82
+ if (Opc != PPC::LI && Opc != PPC::LI8 && Opc != PPC::LIS &&
83
+ Opc != PPC::LIS8)
84
+ continue ;
85
+ // Skip load immediate, where the operand is a relocation (e.g., $r3 =
86
+ // LI target-flags(ppc-lo) %const.0).
87
+ if (!BBI->getOperand (1 ).isImm ())
88
+ continue ;
89
+ assert (BBI->getOperand (0 ).isReg () &&
90
+ " Expected a register for the first operand" );
91
+
92
+ LLVM_DEBUG (dbgs () << " Scanning after load immediate: " ; BBI->dump (););
93
+
94
+ unsigned Reg = BBI->getOperand (0 ).getReg ();
95
+ int64_t Imm = BBI->getOperand (1 ).getImm ();
96
+ MachineOperand *DeadOrKillToUnset = nullptr ;
97
+ if (BBI->getOperand (0 ).isDead ()) {
98
+ DeadOrKillToUnset = &BBI->getOperand (0 );
99
+ LLVM_DEBUG (dbgs () << " Kill flag of " << *DeadOrKillToUnset
100
+ << " from load immediate " << *BBI
101
+ << " is a unsetting candidate\n " );
102
+ }
103
+ // This loop scans instructions after BBI to see if there is any
104
+ // redundant load immediate.
105
+ for (auto AfterBBI = std::next (BBI); AfterBBI != MBB.instr_end ();
106
+ ++AfterBBI) {
107
+ // Track the operand that kill Reg. We would unset the kill flag of
108
+ // the operand if there is a following redundant load immediate.
109
+ int KillIdx = AfterBBI->findRegisterUseOperandIdx (Reg, true , TRI);
110
+ if (KillIdx != -1 ) {
111
+ assert (!DeadOrKillToUnset && " Shouldn't kill same register twice" );
112
+ DeadOrKillToUnset = &AfterBBI->getOperand (KillIdx);
113
+ LLVM_DEBUG (dbgs ()
114
+ << " Kill flag of " << *DeadOrKillToUnset << " from "
115
+ << *AfterBBI << " is a unsetting candidate\n " );
116
+ }
117
+
118
+ if (!AfterBBI->modifiesRegister (Reg, TRI))
119
+ continue ;
120
+ assert (DeadOrKillToUnset &&
121
+ " Shouldn't overwrite a register before it is killed" );
122
+ // Finish scanning because Reg is overwritten by a non-load
123
+ // instruction.
124
+ if (AfterBBI->getOpcode () != Opc)
125
+ break ;
126
+ assert (AfterBBI->getOperand (0 ).isReg () &&
127
+ " Expected a register for the first operand" );
128
+ // Finish scanning because Reg is overwritten by a relocation or a
129
+ // different value.
130
+ if (!AfterBBI->getOperand (1 ).isImm () ||
131
+ AfterBBI->getOperand (1 ).getImm () != Imm)
132
+ break ;
133
+
134
+ // It loads same immediate value to the same Reg, which is redundant.
135
+ // We would unset kill flag in previous Reg usage to extend live range
136
+ // of Reg first, then remove the redundancy.
137
+ LLVM_DEBUG (dbgs () << " Unset dead/kill flag of " << *DeadOrKillToUnset
138
+ << " from " << *DeadOrKillToUnset->getParent ());
139
+ if (DeadOrKillToUnset->isDef ())
140
+ DeadOrKillToUnset->setIsDead (false );
141
+ else
142
+ DeadOrKillToUnset->setIsKill (false );
143
+ DeadOrKillToUnset =
144
+ AfterBBI->findRegisterDefOperand (Reg, true , true , TRI);
145
+ if (DeadOrKillToUnset)
146
+ LLVM_DEBUG (dbgs ()
147
+ << " Dead flag of " << *DeadOrKillToUnset << " from "
148
+ << *AfterBBI << " is a unsetting candidate\n " );
149
+ InstrsToErase.insert (&*AfterBBI);
150
+ LLVM_DEBUG (dbgs () << " Remove redundant load immediate: " ;
151
+ AfterBBI->dump ());
152
+ }
153
+ }
154
+
155
+ for (MachineInstr *MI : InstrsToErase) {
156
+ MI->eraseFromParent ();
157
+ }
158
+ NumRemovedInPreEmit += InstrsToErase.size ();
159
+ return !InstrsToErase.empty ();
160
+ }
161
+
60
162
bool runOnMachineFunction (MachineFunction &MF) override {
61
163
if (skipFunction (MF.getFunction ()) || !RunPreEmitPeephole)
62
164
return false ;
@@ -65,6 +167,7 @@ namespace {
65
167
const TargetRegisterInfo *TRI = MF.getSubtarget ().getRegisterInfo ();
66
168
SmallVector<MachineInstr *, 4 > InstrsToErase;
67
169
for (MachineBasicBlock &MBB : MF) {
170
+ Changed |= removeRedundantLIs (MBB, TRI);
68
171
for (MachineInstr &MI : MBB) {
69
172
unsigned Opc = MI.getOpcode ();
70
173
// Detect self copies - these can result from running AADB.
0 commit comments