LLVM 23.0.0git
X86OptimizeLEAs.cpp
Go to the documentation of this file.
1//===- X86OptimizeLEAs.cpp - optimize usage of LEA instructions -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the pass that performs some optimizations with LEA
10// instructions in order to improve performance and code size.
11// Currently, it does two things:
12// 1) If there are two LEA instructions calculating addresses which only differ
13// by displacement inside a basic block, one of them is removed.
14// 2) Address calculations in load and store instructions are replaced by
15// existing LEA def registers where possible.
16//
17//===----------------------------------------------------------------------===//
18
20#include "X86.h"
21#include "X86InstrInfo.h"
22#include "X86Subtarget.h"
23#include "llvm/ADT/DenseMap.h"
25#include "llvm/ADT/Hashing.h"
27#include "llvm/ADT/Statistic.h"
41#include "llvm/IR/DebugLoc.h"
42#include "llvm/IR/Function.h"
43#include "llvm/MC/MCInstrDesc.h"
45#include "llvm/Support/Debug.h"
49#include <cassert>
50#include <cstdint>
51#include <iterator>
52
53using namespace llvm;
54
55#define DEBUG_TYPE "x86-optimize-leas"
56
57static cl::opt<bool>
58 DisableX86LEAOpt("disable-x86-lea-opt", cl::Hidden,
59 cl::desc("X86: Disable LEA optimizations."),
60 cl::init(false));
61
62STATISTIC(NumSubstLEAs, "Number of LEA instruction substitutions");
63STATISTIC(NumRedundantLEAs, "Number of redundant LEA instructions removed");
64
65/// Returns true if two machine operands are identical and they are not
66/// physical registers.
67static inline bool isIdenticalOp(const MachineOperand &MO1,
68 const MachineOperand &MO2);
69
70/// Returns true if two address displacement operands are of the same
71/// type and use the same symbol/index/address regardless of the offset.
72static bool isSimilarDispOp(const MachineOperand &MO1,
73 const MachineOperand &MO2);
74
75/// Returns true if the instruction is LEA.
76static inline bool isLEA(const MachineInstr &MI);
77
78namespace {
79
80/// A key based on instruction's memory operands.
81class MemOpKey {
82public:
83 MemOpKey(const MachineOperand *Base, const MachineOperand *Scale,
84 const MachineOperand *Index, const MachineOperand *Segment,
85 const MachineOperand *Disp)
86 : Disp(Disp) {
87 Operands[0] = Base;
88 Operands[1] = Scale;
89 Operands[2] = Index;
90 Operands[3] = Segment;
91 }
92
93 bool operator==(const MemOpKey &Other) const {
94 // Addresses' bases, scales, indices and segments must be identical.
95 for (int i = 0; i < 4; ++i)
96 if (!isIdenticalOp(*Operands[i], *Other.Operands[i]))
97 return false;
98
99 // Addresses' displacements don't have to be exactly the same. It only
100 // matters that they use the same symbol/index/address. Immediates' or
101 // offsets' differences will be taken care of during instruction
102 // substitution.
103 return isSimilarDispOp(*Disp, *Other.Disp);
104 }
105
106 // Address' base, scale, index and segment operands.
107 const MachineOperand *Operands[4];
108
109 // Address' displacement operand.
110 const MachineOperand *Disp;
111};
112
113} // end anonymous namespace
114
115namespace llvm {
116
117/// Provide DenseMapInfo for MemOpKey.
118template <> struct DenseMapInfo<MemOpKey> {
120
121 static inline MemOpKey getEmptyKey() {
122 return MemOpKey(PtrInfo::getEmptyKey(), PtrInfo::getEmptyKey(),
123 PtrInfo::getEmptyKey(), PtrInfo::getEmptyKey(),
124 PtrInfo::getEmptyKey());
125 }
126
127 static unsigned getHashValue(const MemOpKey &Val) {
128 // Checking any field of MemOpKey is enough to determine if the key is
129 // empty.
130 assert(Val.Disp != PtrInfo::getEmptyKey() && "Cannot hash the empty key");
131
132 hash_code Hash = hash_combine(*Val.Operands[0], *Val.Operands[1],
133 *Val.Operands[2], *Val.Operands[3]);
134
135 // If the address displacement is an immediate, it should not affect the
136 // hash so that memory operands which differ only be immediate displacement
137 // would have the same hash. If the address displacement is something else,
138 // we should reflect symbol/index/address in the hash.
139 switch (Val.Disp->getType()) {
141 break;
144 Hash = hash_combine(Hash, Val.Disp->getIndex());
145 break;
147 Hash = hash_combine(Hash, Val.Disp->getSymbolName());
148 break;
150 Hash = hash_combine(Hash, Val.Disp->getGlobal());
151 break;
153 Hash = hash_combine(Hash, Val.Disp->getBlockAddress());
154 break;
156 Hash = hash_combine(Hash, Val.Disp->getMCSymbol());
157 break;
159 Hash = hash_combine(Hash, Val.Disp->getMBB());
160 break;
161 default:
162 llvm_unreachable("Invalid address displacement operand");
163 }
164
165 return (unsigned)Hash;
166 }
167
168 static bool isEqual(const MemOpKey &LHS, const MemOpKey &RHS) {
169 // Checking any field of MemOpKey is enough to determine if the key is
170 // empty.
171 if (RHS.Disp == PtrInfo::getEmptyKey())
172 return LHS.Disp == PtrInfo::getEmptyKey();
173 return LHS == RHS;
174 }
175};
176
177} // end namespace llvm
178
179/// Returns a hash table key based on memory operands of \p MI. The
180/// number of the first memory operand of \p MI is specified through \p N.
181static inline MemOpKey getMemOpKey(const MachineInstr &MI, unsigned N) {
182 assert((isLEA(MI) || MI.mayLoadOrStore()) &&
183 "The instruction must be a LEA, a load or a store");
184 return MemOpKey(&MI.getOperand(N + X86::AddrBaseReg),
185 &MI.getOperand(N + X86::AddrScaleAmt),
186 &MI.getOperand(N + X86::AddrIndexReg),
187 &MI.getOperand(N + X86::AddrSegmentReg),
188 &MI.getOperand(N + X86::AddrDisp));
189}
190
191static inline bool isIdenticalOp(const MachineOperand &MO1,
192 const MachineOperand &MO2) {
193 return MO1.isIdenticalTo(MO2) && (!MO1.isReg() || !MO1.getReg().isPhysical());
194}
195
196#ifndef NDEBUG
197static bool isValidDispOp(const MachineOperand &MO) {
198 return MO.isImm() || MO.isCPI() || MO.isJTI() || MO.isSymbol() ||
199 MO.isGlobal() || MO.isBlockAddress() || MO.isMCSymbol() || MO.isMBB();
200}
201#endif
202
203static bool isSimilarDispOp(const MachineOperand &MO1,
204 const MachineOperand &MO2) {
205 assert(isValidDispOp(MO1) && isValidDispOp(MO2) &&
206 "Address displacement operand is not valid");
207 return (MO1.isImm() && MO2.isImm()) ||
208 (MO1.isCPI() && MO2.isCPI() && MO1.getIndex() == MO2.getIndex()) ||
209 (MO1.isJTI() && MO2.isJTI() && MO1.getIndex() == MO2.getIndex()) ||
210 (MO1.isSymbol() && MO2.isSymbol() &&
211 MO1.getSymbolName() == MO2.getSymbolName()) ||
212 (MO1.isGlobal() && MO2.isGlobal() &&
213 MO1.getGlobal() == MO2.getGlobal()) ||
214 (MO1.isBlockAddress() && MO2.isBlockAddress() &&
215 MO1.getBlockAddress() == MO2.getBlockAddress()) ||
216 (MO1.isMCSymbol() && MO2.isMCSymbol() &&
217 MO1.getMCSymbol() == MO2.getMCSymbol()) ||
218 (MO1.isMBB() && MO2.isMBB() && MO1.getMBB() == MO2.getMBB());
219}
220
221static inline bool isLEA(const MachineInstr &MI) {
222 unsigned Opcode = MI.getOpcode();
223 return Opcode == X86::LEA16r || Opcode == X86::LEA32r ||
224 Opcode == X86::LEA64r || Opcode == X86::LEA64_32r;
225}
226
227namespace {
228
229class X86OptimizeLEAsImpl {
230public:
231 bool runOnMachineFunction(MachineFunction &MF, ProfileSummaryInfo *PSI,
232 MachineBlockFrequencyInfo *MBFI);
233
234private:
235 using MemOpMap = DenseMap<MemOpKey, SmallVector<MachineInstr *, 16>>;
236
237 /// Returns a distance between two instructions inside one basic block.
238 /// Negative result means, that instructions occur in reverse order.
239 int calcInstrDist(const MachineInstr &First, const MachineInstr &Last);
240
241 /// Choose the best \p LEA instruction from the \p List to replace
242 /// address calculation in \p MI instruction. Return the address displacement
243 /// and the distance between \p MI and the chosen \p BestLEA in
244 /// \p AddrDispShift and \p Dist.
245 bool chooseBestLEA(const SmallVectorImpl<MachineInstr *> &List,
246 const MachineInstr &MI, MachineInstr *&BestLEA,
247 int64_t &AddrDispShift, int &Dist);
248
249 /// Returns the difference between addresses' displacements of \p MI1
250 /// and \p MI2. The numbers of the first memory operands for the instructions
251 /// are specified through \p N1 and \p N2.
252 int64_t getAddrDispShift(const MachineInstr &MI1, unsigned N1,
253 const MachineInstr &MI2, unsigned N2) const;
254
255 /// Returns true if the \p Last LEA instruction can be replaced by the
256 /// \p First. The difference between displacements of the addresses calculated
257 /// by these LEAs is returned in \p AddrDispShift. It'll be used for proper
258 /// replacement of the \p Last LEA's uses with the \p First's def register.
259 bool isReplaceable(const MachineInstr &First, const MachineInstr &Last,
260 int64_t &AddrDispShift) const;
261
262 /// Find all LEA instructions in the basic block. Also, assign position
263 /// numbers to all instructions in the basic block to speed up calculation of
264 /// distance between them.
265 void findLEAs(const MachineBasicBlock &MBB, MemOpMap &LEAs);
266
267 /// Removes redundant address calculations.
268 bool removeRedundantAddrCalc(MemOpMap &LEAs);
269
270 /// Replace debug value MI with a new debug value instruction using register
271 /// VReg with an appropriate offset and DIExpression to incorporate the
272 /// address displacement AddrDispShift. Return new debug value instruction.
273 MachineInstr *replaceDebugValue(MachineInstr &MI, Register OldReg,
274 Register NewReg, int64_t AddrDispShift);
275
276 /// Removes LEAs which calculate similar addresses.
277 bool removeRedundantLEAs(MemOpMap &LEAs);
278
279 DenseMap<const MachineInstr *, unsigned> InstrPos;
280
281 MachineRegisterInfo *MRI = nullptr;
282 const X86InstrInfo *TII = nullptr;
283 const X86RegisterInfo *TRI = nullptr;
284};
285
286class X86OptimizeLEAsLegacy : public MachineFunctionPass {
287public:
288 X86OptimizeLEAsLegacy() : MachineFunctionPass(ID) {}
289
290 StringRef getPassName() const override { return "X86 LEA Optimize"; }
291
292 /// Loop over all of the basic blocks, replacing address
293 /// calculations in load and store instructions, if it's already
294 /// been calculated by LEA. Also, remove redundant LEAs.
295 bool runOnMachineFunction(MachineFunction &MF) override;
296
297 static char ID;
298
299 void getAnalysisUsage(AnalysisUsage &AU) const override {
300 AU.addRequired<ProfileSummaryInfoWrapperPass>();
301 AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
303 }
304};
305
306} // end anonymous namespace
307
308char X86OptimizeLEAsLegacy::ID = 0;
309
311 return new X86OptimizeLEAsLegacy();
312}
313INITIALIZE_PASS(X86OptimizeLEAsLegacy, DEBUG_TYPE, "X86 optimize LEA pass",
314 false, false)
315
316int X86OptimizeLEAsImpl::calcInstrDist(const MachineInstr &First,
318 // Both instructions must be in the same basic block and they must be
319 // presented in InstrPos.
320 assert(Last.getParent() == First.getParent() &&
321 "Instructions are in different basic blocks");
322 assert(InstrPos.contains(&First) && InstrPos.contains(&Last) &&
323 "Instructions' positions are undefined");
324
325 return InstrPos[&Last] - InstrPos[&First];
326}
327
328// Find the best LEA instruction in the List to replace address recalculation in
329// MI. Such LEA must meet these requirements:
330// 1) The address calculated by the LEA differs only by the displacement from
331// the address used in MI.
332// 2) The register class of the definition of the LEA is compatible with the
333// register class of the address base register of MI.
334// 3) Displacement of the new memory operand should fit in 1 byte if possible.
335// 4) The LEA should be as close to MI as possible, and prior to it if
336// possible.
337bool X86OptimizeLEAsImpl::chooseBestLEA(
339 MachineInstr *&BestLEA, int64_t &AddrDispShift, int &Dist) {
340 const MCInstrDesc &Desc = MI.getDesc();
341 int MemOpNo = X86II::getMemoryOperandNo(Desc.TSFlags) +
343
344 BestLEA = nullptr;
345
346 // Loop over all LEA instructions.
347 for (auto *DefMI : List) {
348 // Get new address displacement.
349 int64_t AddrDispShiftTemp = getAddrDispShift(MI, MemOpNo, *DefMI, 1);
350
351 // Make sure address displacement fits 4 bytes.
352 if (!isInt<32>(AddrDispShiftTemp))
353 continue;
354
355 // Check that LEA def register can be used as MI address base. Some
356 // instructions can use a limited set of registers as address base, for
357 // example MOV8mr_NOREX. We could constrain the register class of the LEA
358 // def to suit MI, however since this case is very rare and hard to
359 // reproduce in a test it's just more reliable to skip the LEA.
360 if (TII->getRegClass(Desc, MemOpNo + X86::AddrBaseReg) !=
362 continue;
363
364 // Choose the closest LEA instruction from the list, prior to MI if
365 // possible. Note that we took into account resulting address displacement
366 // as well. Also note that the list is sorted by the order in which the LEAs
367 // occur, so the break condition is pretty simple.
368 int DistTemp = calcInstrDist(*DefMI, MI);
369 assert(DistTemp != 0 &&
370 "The distance between two different instructions cannot be zero");
371 if (DistTemp > 0 || BestLEA == nullptr) {
372 // Do not update return LEA, if the current one provides a displacement
373 // which fits in 1 byte, while the new candidate does not.
374 if (BestLEA != nullptr && !isInt<8>(AddrDispShiftTemp) &&
375 isInt<8>(AddrDispShift))
376 continue;
377
378 BestLEA = DefMI;
379 AddrDispShift = AddrDispShiftTemp;
380 Dist = DistTemp;
381 }
382
383 // FIXME: Maybe we should not always stop at the first LEA after MI.
384 if (DistTemp < 0)
385 break;
386 }
387
388 return BestLEA != nullptr;
389}
390
391// Get the difference between the addresses' displacements of the two
392// instructions \p MI1 and \p MI2. The numbers of the first memory operands are
393// passed through \p N1 and \p N2.
394int64_t X86OptimizeLEAsImpl::getAddrDispShift(const MachineInstr &MI1,
395 unsigned N1,
396 const MachineInstr &MI2,
397 unsigned N2) const {
398 const MachineOperand &Op1 = MI1.getOperand(N1 + X86::AddrDisp);
399 const MachineOperand &Op2 = MI2.getOperand(N2 + X86::AddrDisp);
400
401 assert(isSimilarDispOp(Op1, Op2) &&
402 "Address displacement operands are not compatible");
403
404 // After the assert above we can be sure that both operands are of the same
405 // valid type and use the same symbol/index/address, thus displacement shift
406 // calculation is rather simple.
407 if (Op1.isJTI())
408 return 0;
409 return Op1.isImm() ? Op1.getImm() - Op2.getImm()
410 : Op1.getOffset() - Op2.getOffset();
411}
412
413// Check that the Last LEA can be replaced by the First LEA. To be so,
414// these requirements must be met:
415// 1) Addresses calculated by LEAs differ only by displacement.
416// 2) Def registers of LEAs belong to the same class.
417// 3) All uses of the Last LEA def register are replaceable, thus the
418// register is used only as address base.
419bool X86OptimizeLEAsImpl::isReplaceable(const MachineInstr &First,
420 const MachineInstr &Last,
421 int64_t &AddrDispShift) const {
422 assert(isLEA(First) && isLEA(Last) &&
423 "The function works only with LEA instructions");
424
425 // Make sure that LEA def registers belong to the same class. There may be
426 // instructions (like MOV8mr_NOREX) which allow a limited set of registers to
427 // be used as their operands, so we must be sure that replacing one LEA
428 // with another won't lead to putting a wrong register in the instruction.
429 if (MRI->getRegClass(First.getOperand(0).getReg()) !=
430 MRI->getRegClass(Last.getOperand(0).getReg()))
431 return false;
432
433 // Get new address displacement.
434 AddrDispShift = getAddrDispShift(Last, 1, First, 1);
435
436 // Loop over all uses of the Last LEA to check that its def register is
437 // used only as address base for memory accesses. If so, it can be
438 // replaced, otherwise - no.
439 for (auto &MO : MRI->use_nodbg_operands(Last.getOperand(0).getReg())) {
440 MachineInstr &MI = *MO.getParent();
441
442 // Get the number of the first memory operand.
443 const MCInstrDesc &Desc = MI.getDesc();
444 int MemOpNo = X86II::getMemoryOperandNo(Desc.TSFlags);
445
446 // If the use instruction has no memory operand - the LEA is not
447 // replaceable.
448 if (MemOpNo < 0)
449 return false;
450
451 MemOpNo += X86II::getOperandBias(Desc);
452
453 // If the address base of the use instruction is not the LEA def register -
454 // the LEA is not replaceable.
455 if (!isIdenticalOp(MI.getOperand(MemOpNo + X86::AddrBaseReg), MO))
456 return false;
457
458 // If the LEA def register is used as any other operand of the use
459 // instruction - the LEA is not replaceable.
460 for (unsigned i = 0; i < MI.getNumOperands(); i++)
461 if (i != (unsigned)(MemOpNo + X86::AddrBaseReg) &&
462 isIdenticalOp(MI.getOperand(i), MO))
463 return false;
464
465 // Check that the new address displacement will fit 4 bytes.
466 if (MI.getOperand(MemOpNo + X86::AddrDisp).isImm() &&
467 !isInt<32>(MI.getOperand(MemOpNo + X86::AddrDisp).getImm() +
468 AddrDispShift))
469 return false;
470 }
471
472 return true;
473}
474
475void X86OptimizeLEAsImpl::findLEAs(const MachineBasicBlock &MBB,
476 MemOpMap &LEAs) {
477 unsigned Pos = 0;
478 for (auto &MI : MBB) {
479 // Assign the position number to the instruction. Note that we are going to
480 // move some instructions during the optimization however there will never
481 // be a need to move two instructions before any selected instruction. So to
482 // avoid multiple positions' updates during moves we just increase position
483 // counter by two leaving a free space for instructions which will be moved.
484 InstrPos[&MI] = Pos += 2;
485
486 if (isLEA(MI))
487 LEAs[getMemOpKey(MI, 1)].push_back(const_cast<MachineInstr *>(&MI));
488 }
489}
490
491// Try to find load and store instructions which recalculate addresses already
492// calculated by some LEA and replace their memory operands with its def
493// register.
494bool X86OptimizeLEAsImpl::removeRedundantAddrCalc(MemOpMap &LEAs) {
495 bool Changed = false;
496
497 assert(!LEAs.empty());
498 MachineBasicBlock *MBB = (*LEAs.begin()->second.begin())->getParent();
499
500 // Process all instructions in basic block.
501 for (MachineInstr &MI : llvm::make_early_inc_range(*MBB)) {
502 // Instruction must be load or store.
503 if (!MI.mayLoadOrStore())
504 continue;
505
506 // Get the number of the first memory operand.
507 const MCInstrDesc &Desc = MI.getDesc();
508 int MemOpNo = X86II::getMemoryOperandNo(Desc.TSFlags);
509
510 // If instruction has no memory operand - skip it.
511 if (MemOpNo < 0)
512 continue;
513
514 MemOpNo += X86II::getOperandBias(Desc);
515
516 // Do not call chooseBestLEA if there was no matching LEA
517 auto Insns = LEAs.find(getMemOpKey(MI, MemOpNo));
518 if (Insns == LEAs.end())
519 continue;
520
521 // Get the best LEA instruction to replace address calculation.
522 MachineInstr *DefMI;
523 int64_t AddrDispShift;
524 int Dist;
525 if (!chooseBestLEA(Insns->second, MI, DefMI, AddrDispShift, Dist))
526 continue;
527
528 // If LEA occurs before current instruction, we can freely replace
529 // the instruction. If LEA occurs after, we can lift LEA above the
530 // instruction and this way to be able to replace it. Since LEA and the
531 // instruction have similar memory operands (thus, the same def
532 // instructions for these operands), we can always do that, without
533 // worries of using registers before their defs.
534 if (Dist < 0) {
537 InstrPos[DefMI] = InstrPos[&MI] - 1;
538
539 // Make sure the instructions' position numbers are sane.
540 assert(((InstrPos[DefMI] == 1 &&
542 InstrPos[DefMI] >
543 InstrPos[&*std::prev(MachineBasicBlock::iterator(DefMI))]) &&
544 "Instruction positioning is broken");
545 }
546
547 // Since we can possibly extend register lifetime, clear kill flags.
549
550 ++NumSubstLEAs;
551 LLVM_DEBUG(dbgs() << "OptimizeLEAs: Candidate to replace: "; MI.dump(););
552
553 // Change instruction operands.
554 MI.getOperand(MemOpNo + X86::AddrBaseReg)
555 .ChangeToRegister(DefMI->getOperand(0).getReg(), false);
556 MI.getOperand(MemOpNo + X86::AddrScaleAmt).ChangeToImmediate(1);
557 MI.getOperand(MemOpNo + X86::AddrIndexReg)
558 .ChangeToRegister(X86::NoRegister, false);
559 MI.getOperand(MemOpNo + X86::AddrDisp).ChangeToImmediate(AddrDispShift);
560 MI.getOperand(MemOpNo + X86::AddrSegmentReg)
561 .ChangeToRegister(X86::NoRegister, false);
562
563 LLVM_DEBUG(dbgs() << "OptimizeLEAs: Replaced by: "; MI.dump(););
564
565 Changed = true;
566 }
567
568 return Changed;
569}
570
571MachineInstr *X86OptimizeLEAsImpl::replaceDebugValue(MachineInstr &MI,
572 Register OldReg,
573 Register NewReg,
574 int64_t AddrDispShift) {
575 const DIExpression *Expr = MI.getDebugExpression();
576 if (AddrDispShift != 0) {
577 if (MI.isNonListDebugValue()) {
578 Expr =
580 } else {
581 // Update the Expression, appending an offset of `AddrDispShift` to the
582 // Op corresponding to `OldReg`.
584 DIExpression::appendOffset(Ops, AddrDispShift);
585 for (MachineOperand &Op : MI.getDebugOperandsForReg(OldReg)) {
586 unsigned OpIdx = MI.getDebugOperandIndex(&Op);
588 }
589 }
590 }
591
592 // Replace DBG_VALUE instruction with modified version.
593 MachineBasicBlock *MBB = MI.getParent();
594 DebugLoc DL = MI.getDebugLoc();
595 bool IsIndirect = MI.isIndirectDebugValue();
596 const MDNode *Var = MI.getDebugVariable();
597 unsigned Opcode = MI.isNonListDebugValue() ? TargetOpcode::DBG_VALUE
598 : TargetOpcode::DBG_VALUE_LIST;
599 if (IsIndirect)
600 assert(MI.getDebugOffset().getImm() == 0 &&
601 "DBG_VALUE with nonzero offset");
603 // If we encounter an operand using the old register, replace it with an
604 // operand that uses the new register; otherwise keep the old operand.
605 auto replaceOldReg = [OldReg, NewReg](const MachineOperand &Op) {
606 if (Op.isReg() && Op.getReg() == OldReg)
607 return MachineOperand::CreateReg(NewReg, false, false, false, false,
608 false, false, false, false, false,
609 /*IsRenamable*/ true);
610 return Op;
611 };
612 for (const MachineOperand &Op : MI.debug_operands())
613 NewOps.push_back(replaceOldReg(Op));
614 return BuildMI(*MBB, MBB->erase(&MI), DL, TII->get(Opcode), IsIndirect,
615 NewOps, Var, Expr);
616}
617
618// Try to find similar LEAs in the list and replace one with another.
619bool X86OptimizeLEAsImpl::removeRedundantLEAs(MemOpMap &LEAs) {
620 bool Changed = false;
621
622 // Loop over all entries in the table.
623 for (auto &E : LEAs) {
624 auto &List = E.second;
625
626 // Loop over all LEA pairs.
627 auto I1 = List.begin();
628 while (I1 != List.end()) {
629 MachineInstr &First = **I1;
630 auto I2 = std::next(I1);
631 while (I2 != List.end()) {
632 MachineInstr &Last = **I2;
633 int64_t AddrDispShift;
634
635 // LEAs should be in occurrence order in the list, so we can freely
636 // replace later LEAs with earlier ones.
637 assert(calcInstrDist(First, Last) > 0 &&
638 "LEAs must be in occurrence order in the list");
639
640 // Check that the Last LEA instruction can be replaced by the First.
641 if (!isReplaceable(First, Last, AddrDispShift)) {
642 ++I2;
643 continue;
644 }
645
646 // Loop over all uses of the Last LEA and update their operands. Note
647 // that the correctness of this has already been checked in the
648 // isReplaceable function.
649 Register FirstVReg = First.getOperand(0).getReg();
650 Register LastVReg = Last.getOperand(0).getReg();
651 // We use MRI->use_empty here instead of the combination of
652 // llvm::make_early_inc_range and MRI->use_operands because we could
653 // replace two or more uses in a debug instruction in one iteration, and
654 // that would deeply confuse llvm::make_early_inc_range.
655 while (!MRI->use_empty(LastVReg)) {
656 MachineOperand &MO = *MRI->use_begin(LastVReg);
657 MachineInstr &MI = *MO.getParent();
658
659 if (MI.isDebugValue()) {
660 // Replace DBG_VALUE instruction with modified version using the
661 // register from the replacing LEA and the address displacement
662 // between the LEA instructions.
663 replaceDebugValue(MI, LastVReg, FirstVReg, AddrDispShift);
664 continue;
665 }
666
667 // Get the number of the first memory operand.
668 const MCInstrDesc &Desc = MI.getDesc();
669 int MemOpNo =
672
673 // Update address base.
674 MO.setReg(FirstVReg);
675
676 // Update address disp.
677 MachineOperand &Op = MI.getOperand(MemOpNo + X86::AddrDisp);
678 if (Op.isImm())
679 Op.setImm(Op.getImm() + AddrDispShift);
680 else if (!Op.isJTI())
681 Op.setOffset(Op.getOffset() + AddrDispShift);
682 }
683
684 // Since we can possibly extend register lifetime, clear kill flags.
685 MRI->clearKillFlags(FirstVReg);
686
687 ++NumRedundantLEAs;
688 LLVM_DEBUG(dbgs() << "OptimizeLEAs: Remove redundant LEA: ";
689 Last.dump(););
690
691 // By this moment, all of the Last LEA's uses must be replaced. So we
692 // can freely remove it.
693 assert(MRI->use_empty(LastVReg) &&
694 "The LEA's def register must have no uses");
695 Last.eraseFromParent();
696
697 // Erase removed LEA from the list.
698 I2 = List.erase(I2);
699
700 Changed = true;
701 }
702 ++I1;
703 }
704 }
705
706 return Changed;
707}
708
709bool X86OptimizeLEAsImpl::runOnMachineFunction(
710 MachineFunction &MF, ProfileSummaryInfo *PSI,
711 MachineBlockFrequencyInfo *MBFI) {
712 bool Changed = false;
713
715 return false;
716
717 MRI = &MF.getRegInfo();
718 TII = MF.getSubtarget<X86Subtarget>().getInstrInfo();
719 TRI = MF.getSubtarget<X86Subtarget>().getRegisterInfo();
720
721 // Process all basic blocks.
722 for (auto &MBB : MF) {
723 MemOpMap LEAs;
724 InstrPos.clear();
725
726 // Find all LEA instructions in basic block.
727 findLEAs(MBB, LEAs);
728
729 // If current basic block has no LEAs, move on to the next one.
730 if (LEAs.empty())
731 continue;
732
733 // Remove redundant LEA instructions.
734 Changed |= removeRedundantLEAs(LEAs);
735
736 // Remove redundant address calculations. Do it only for -Os/-Oz since only
737 // a code size gain is expected from this part of the pass.
738 if (llvm::shouldOptimizeForSize(&MBB, PSI, MBFI))
739 Changed |= removeRedundantAddrCalc(LEAs);
740 }
741
742 return Changed;
743}
744
745bool X86OptimizeLEAsLegacy::runOnMachineFunction(MachineFunction &MF) {
746 if (skipFunction(MF.getFunction()))
747 return false;
748 ProfileSummaryInfo *PSI =
749 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
750 MachineBlockFrequencyInfo *MBFI =
751 (PSI && PSI->hasProfileSummary())
752 ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
753 : nullptr;
754 X86OptimizeLEAsImpl PassImpl;
755 return PassImpl.runOnMachineFunction(MF, PSI, MBFI);
756}
757
758PreservedAnalyses
761 ProfileSummaryInfo *PSI =
763 .getCachedResult<ProfileSummaryAnalysis>(
764 *MF.getFunction().getParent());
766 (PSI && PSI->hasProfileSummary())
768 : nullptr;
769 X86OptimizeLEAsImpl PassImpl;
770 bool Changed = PassImpl.runOnMachineFunction(MF, PSI, MBFI);
771 if (!Changed)
772 return PreservedAnalyses::all();
774}
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines DenseMapInfo traits for DenseMap.
This file defines the DenseMap class.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
===- LazyMachineBlockFrequencyInfo.h - Lazy Block Frequency -*- C++ -*–===//
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
static bool isLEA(unsigned Opcode)
static cl::opt< bool > DisableX86LEAOpt("disable-x86-lea-opt", cl::Hidden, cl::desc("X86: Disable LEA optimizations."), cl::init(false))
static bool isLEA(const MachineInstr &MI)
Returns true if the instruction is LEA.
static bool isValidDispOp(const MachineOperand &MO)
static MemOpKey getMemOpKey(const MachineInstr &MI, unsigned N)
Returns a hash table key based on memory operands of MI.
static bool isSimilarDispOp(const MachineOperand &MO1, const MachineOperand &MO2)
Returns true if two address displacement operands are of the same type and use the same symbol/index/...
static bool isIdenticalOp(const MachineOperand &MO1, const MachineOperand &MO2)
Returns true if two machine operands are identical and they are not physical registers.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
static LLVM_ABI void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
static LLVM_ABI DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)
Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...
static LLVM_ABI DIExpression * prepend(const DIExpression *Expr, uint8_t Flags, int64_t Offset=0)
Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value or/and an ...
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineInstrBundleIterator< MachineInstr > iterator
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
LLVM_ABI MachineInstr * removeFromParent()
Unlink 'this' from the containing basic block, and return it without deleting it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
const BlockAddress * getBlockAddress() const
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
bool isBlockAddress() const
isBlockAddress - Tests if this is a MO_BlockAddress operand.
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
MCSymbol * getMCSymbol() const
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_MCSymbol
MCSymbol reference (for debug/eh info)
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
int64_t getOffset() const
Return the offset from the symbol in this operand.
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
use_iterator use_begin(Register RegNo) const
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
void dump() const
Definition Pass.cpp:146
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
Analysis providing profile information.
bool hasProfileSummary() const
Returns true if profile summary is available.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
An opaque object representing a hash code.
Definition Hashing.h:78
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int getMemoryOperandNo(uint64_t TSFlags)
unsigned getOperandBias(const MCInstrDesc &Desc)
Compute whether all of the def operands are repeated in the uses and therefore should be skipped.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
FunctionPass * createX86OptimizeLEAsLegacyPass()
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:633
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
Op::Description Desc
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Other
Any other memory.
Definition ModRef.h:68
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
DWARFExpression::Operation Op
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition Hashing.h:325
#define N
static unsigned getHashValue(const MemOpKey &Val)
DenseMapInfo< const MachineOperand * > PtrInfo
static bool isEqual(const MemOpKey &LHS, const MemOpKey &RHS)
An information struct used to provide DenseMap with the various necessary components for a given valu...