LLVM 24.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"
42#include "llvm/IR/DebugLoc.h"
43#include "llvm/IR/Function.h"
44#include "llvm/MC/MCInstrDesc.h"
46#include "llvm/Support/Debug.h"
50#include <cassert>
51#include <cstdint>
52#include <iterator>
53
54using namespace llvm;
55
56#define DEBUG_TYPE "x86-optimize-leas"
57
58static cl::opt<bool>
59 DisableX86LEAOpt("disable-x86-lea-opt", cl::Hidden,
60 cl::desc("X86: Disable LEA optimizations."),
61 cl::init(false));
62
63STATISTIC(NumSubstLEAs, "Number of LEA instruction substitutions");
64STATISTIC(NumRedundantLEAs, "Number of redundant LEA instructions removed");
65
66/// Returns true if two machine operands are identical and they are not
67/// physical registers.
68static inline bool isIdenticalOp(const MachineOperand &MO1,
69 const MachineOperand &MO2);
70
71/// Returns true if two address displacement operands are of the same
72/// type and use the same symbol/index/address regardless of the offset.
73static bool isSimilarDispOp(const MachineOperand &MO1,
74 const MachineOperand &MO2);
75
76/// Returns true if the instruction is LEA.
77static inline bool isLEA(const MachineInstr &MI);
78
79namespace {
80
81/// A key based on instruction's memory operands.
82class MemOpKey {
83public:
84 MemOpKey(const MachineOperand *Base, const MachineOperand *Scale,
85 const MachineOperand *Index, const MachineOperand *Segment,
86 const MachineOperand *Disp)
87 : Disp(Disp) {
88 Operands[0] = Base;
89 Operands[1] = Scale;
90 Operands[2] = Index;
91 Operands[3] = Segment;
92 }
93
94 bool operator==(const MemOpKey &Other) const {
95 // Addresses' bases, scales, indices and segments must be identical.
96 for (int i = 0; i < 4; ++i)
97 if (!isIdenticalOp(*Operands[i], *Other.Operands[i]))
98 return false;
99
100 // Addresses' displacements don't have to be exactly the same. It only
101 // matters that they use the same symbol/index/address. Immediates' or
102 // offsets' differences will be taken care of during instruction
103 // substitution.
104 return isSimilarDispOp(*Disp, *Other.Disp);
105 }
106
107 // Address' base, scale, index and segment operands.
108 const MachineOperand *Operands[4];
109
110 // Address' displacement operand.
111 const MachineOperand *Disp;
112};
113
114} // end anonymous namespace
115
116namespace llvm {
117
118/// Provide DenseMapInfo for MemOpKey.
119template <> struct DenseMapInfo<MemOpKey> {
121
122 static unsigned getHashValue(const MemOpKey &Val) {
123 hash_code Hash = hash_combine(*Val.Operands[0], *Val.Operands[1],
124 *Val.Operands[2], *Val.Operands[3]);
125
126 // If the address displacement is an immediate, it should not affect the
127 // hash so that memory operands which differ only be immediate displacement
128 // would have the same hash. If the address displacement is something else,
129 // we should reflect symbol/index/address in the hash.
130 switch (Val.Disp->getType()) {
132 break;
135 Hash = hash_combine(Hash, Val.Disp->getIndex());
136 break;
138 Hash = hash_combine(Hash, Val.Disp->getSymbolName());
139 break;
141 Hash = hash_combine(Hash, Val.Disp->getGlobal());
142 break;
144 Hash = hash_combine(Hash, Val.Disp->getBlockAddress());
145 break;
147 Hash = hash_combine(Hash, Val.Disp->getMCSymbol());
148 break;
150 Hash = hash_combine(Hash, Val.Disp->getMBB());
151 break;
152 default:
153 llvm_unreachable("Invalid address displacement operand");
154 }
155
156 return (unsigned)Hash;
157 }
158
159 static bool isEqual(const MemOpKey &LHS, const MemOpKey &RHS) {
160 return LHS == RHS;
161 }
162};
163
164} // end namespace llvm
165
166/// Returns a hash table key based on memory operands of \p MI. The
167/// number of the first memory operand of \p MI is specified through \p N.
168static inline MemOpKey getMemOpKey(const MachineInstr &MI, unsigned N) {
169 assert((isLEA(MI) || MI.mayLoadOrStore()) &&
170 "The instruction must be a LEA, a load or a store");
171 return MemOpKey(&MI.getOperand(N + X86::AddrBaseReg),
172 &MI.getOperand(N + X86::AddrScaleAmt),
173 &MI.getOperand(N + X86::AddrIndexReg),
174 &MI.getOperand(N + X86::AddrSegmentReg),
175 &MI.getOperand(N + X86::AddrDisp));
176}
177
178static inline bool isIdenticalOp(const MachineOperand &MO1,
179 const MachineOperand &MO2) {
180 return MO1.isIdenticalTo(MO2) && (!MO1.isReg() || !MO1.getReg().isPhysical());
181}
182
183#ifndef NDEBUG
184static bool isValidDispOp(const MachineOperand &MO) {
185 return MO.isImm() || MO.isCPI() || MO.isJTI() || MO.isSymbol() ||
186 MO.isGlobal() || MO.isBlockAddress() || MO.isMCSymbol() || MO.isMBB();
187}
188#endif
189
190static bool isSimilarDispOp(const MachineOperand &MO1,
191 const MachineOperand &MO2) {
192 assert(isValidDispOp(MO1) && isValidDispOp(MO2) &&
193 "Address displacement operand is not valid");
194 return (MO1.isImm() && MO2.isImm()) ||
195 (MO1.isCPI() && MO2.isCPI() && MO1.getIndex() == MO2.getIndex()) ||
196 (MO1.isJTI() && MO2.isJTI() && MO1.getIndex() == MO2.getIndex()) ||
197 (MO1.isSymbol() && MO2.isSymbol() &&
198 MO1.getSymbolName() == MO2.getSymbolName()) ||
199 (MO1.isGlobal() && MO2.isGlobal() &&
200 MO1.getGlobal() == MO2.getGlobal()) ||
201 (MO1.isBlockAddress() && MO2.isBlockAddress() &&
202 MO1.getBlockAddress() == MO2.getBlockAddress()) ||
203 (MO1.isMCSymbol() && MO2.isMCSymbol() &&
204 MO1.getMCSymbol() == MO2.getMCSymbol()) ||
205 (MO1.isMBB() && MO2.isMBB() && MO1.getMBB() == MO2.getMBB());
206}
207
208static inline bool isLEA(const MachineInstr &MI) {
209 unsigned Opcode = MI.getOpcode();
210 return Opcode == X86::LEA16r || Opcode == X86::LEA32r ||
211 Opcode == X86::LEA64r || Opcode == X86::LEA64_32r;
212}
213
214namespace {
215
216class X86OptimizeLEAsImpl {
217public:
218 bool runOnMachineFunction(MachineFunction &MF, ProfileSummaryInfo *PSI,
219 MachineBlockFrequencyInfo *MBFI);
220
221private:
222 using MemOpMap = DenseMap<MemOpKey, SmallVector<MachineInstr *, 16>>;
223
224 /// Returns a distance between two instructions inside one basic block.
225 /// Negative result means, that instructions occur in reverse order.
226 int calcInstrDist(const MachineInstr &First, const MachineInstr &Last);
227
228 /// Choose the best \p LEA instruction from the \p List to replace
229 /// address calculation in \p MI instruction. Return the address displacement
230 /// and the distance between \p MI and the chosen \p BestLEA in
231 /// \p AddrDispShift and \p Dist.
232 bool chooseBestLEA(const SmallVectorImpl<MachineInstr *> &List,
233 const MachineInstr &MI, MachineInstr *&BestLEA,
234 int64_t &AddrDispShift, int &Dist);
235
236 /// Returns the difference between addresses' displacements of \p MI1
237 /// and \p MI2. The numbers of the first memory operands for the instructions
238 /// are specified through \p N1 and \p N2.
239 int64_t getAddrDispShift(const MachineInstr &MI1, unsigned N1,
240 const MachineInstr &MI2, unsigned N2) const;
241
242 /// Returns true if the \p Last LEA instruction can be replaced by the
243 /// \p First. The difference between displacements of the addresses calculated
244 /// by these LEAs is returned in \p AddrDispShift. It'll be used for proper
245 /// replacement of the \p Last LEA's uses with the \p First's def register.
246 bool isReplaceable(const MachineInstr &First, const MachineInstr &Last,
247 int64_t &AddrDispShift) const;
248
249 /// Find all LEA instructions in the basic block. Also, assign position
250 /// numbers to all instructions in the basic block to speed up calculation of
251 /// distance between them.
252 void findLEAs(const MachineBasicBlock &MBB, MemOpMap &LEAs);
253
254 /// Removes redundant address calculations.
255 bool removeRedundantAddrCalc(MemOpMap &LEAs);
256
257 /// Replace debug value MI with a new debug value instruction using register
258 /// VReg with an appropriate offset and DIExpression to incorporate the
259 /// address displacement AddrDispShift. Return new debug value instruction.
260 MachineInstr *replaceDebugValue(MachineInstr &MI, Register OldReg,
261 Register NewReg, int64_t AddrDispShift);
262
263 /// Removes LEAs which calculate similar addresses.
264 bool removeRedundantLEAs(MemOpMap &LEAs);
265
266 DenseMap<const MachineInstr *, unsigned> InstrPos;
267
268 MachineRegisterInfo *MRI = nullptr;
269 const X86InstrInfo *TII = nullptr;
270 const X86RegisterInfo *TRI = nullptr;
271};
272
273class X86OptimizeLEAsLegacy : public MachineFunctionPass {
274public:
275 X86OptimizeLEAsLegacy() : MachineFunctionPass(ID) {}
276
277 StringRef getPassName() const override { return "X86 LEA Optimize"; }
278
279 /// Loop over all of the basic blocks, replacing address
280 /// calculations in load and store instructions, if it's already
281 /// been calculated by LEA. Also, remove redundant LEAs.
282 bool runOnMachineFunction(MachineFunction &MF) override;
283
284 static char ID;
285
286 void getAnalysisUsage(AnalysisUsage &AU) const override {
287 AU.addRequired<ProfileSummaryInfoWrapperPass>();
288 AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
289 AU.addPreserved<MachineRegisterClassInfoWrapperPass>();
291 }
292};
293
294} // end anonymous namespace
295
296char X86OptimizeLEAsLegacy::ID = 0;
297
299 return new X86OptimizeLEAsLegacy();
300}
301INITIALIZE_PASS(X86OptimizeLEAsLegacy, DEBUG_TYPE, "X86 optimize LEA pass",
302 false, false)
303
304int X86OptimizeLEAsImpl::calcInstrDist(const MachineInstr &First,
306 // Both instructions must be in the same basic block and they must be
307 // presented in InstrPos.
308 assert(Last.getParent() == First.getParent() &&
309 "Instructions are in different basic blocks");
310 assert(InstrPos.contains(&First) && InstrPos.contains(&Last) &&
311 "Instructions' positions are undefined");
312
313 return InstrPos[&Last] - InstrPos[&First];
314}
315
316// Find the best LEA instruction in the List to replace address recalculation in
317// MI. Such LEA must meet these requirements:
318// 1) The address calculated by the LEA differs only by the displacement from
319// the address used in MI.
320// 2) The register class of the definition of the LEA is compatible with the
321// register class of the address base register of MI.
322// 3) Displacement of the new memory operand should fit in 1 byte if possible.
323// 4) The LEA should be as close to MI as possible, and prior to it if
324// possible.
325bool X86OptimizeLEAsImpl::chooseBestLEA(
327 MachineInstr *&BestLEA, int64_t &AddrDispShift, int &Dist) {
328 const MCInstrDesc &Desc = MI.getDesc();
329 int MemOpNo = X86II::getMemoryOperandNo(Desc.TSFlags) +
331
332 BestLEA = nullptr;
333
334 // Loop over all LEA instructions.
335 for (auto *DefMI : List) {
336 // Get new address displacement.
337 int64_t AddrDispShiftTemp = getAddrDispShift(MI, MemOpNo, *DefMI, 1);
338
339 // Make sure address displacement fits 4 bytes.
340 if (!isInt<32>(AddrDispShiftTemp))
341 continue;
342
343 // Check that LEA def register can be used as MI address base. Some
344 // instructions can use a limited set of registers as address base, for
345 // example MOV8mr_NOREX. We could constrain the register class of the LEA
346 // def to suit MI, however since this case is very rare and hard to
347 // reproduce in a test it's just more reliable to skip the LEA.
348 if (TII->getRegClass(Desc, MemOpNo + X86::AddrBaseReg) !=
350 continue;
351
352 // Choose the closest LEA instruction from the list, prior to MI if
353 // possible. Note that we took into account resulting address displacement
354 // as well. Also note that the list is sorted by the order in which the LEAs
355 // occur, so the break condition is pretty simple.
356 int DistTemp = calcInstrDist(*DefMI, MI);
357 assert(DistTemp != 0 &&
358 "The distance between two different instructions cannot be zero");
359 if (DistTemp > 0 || BestLEA == nullptr) {
360 // Do not update return LEA, if the current one provides a displacement
361 // which fits in 1 byte, while the new candidate does not.
362 if (BestLEA != nullptr && !isInt<8>(AddrDispShiftTemp) &&
363 isInt<8>(AddrDispShift))
364 continue;
365
366 BestLEA = DefMI;
367 AddrDispShift = AddrDispShiftTemp;
368 Dist = DistTemp;
369 }
370
371 // FIXME: Maybe we should not always stop at the first LEA after MI.
372 if (DistTemp < 0)
373 break;
374 }
375
376 return BestLEA != nullptr;
377}
378
379// Get the difference between the addresses' displacements of the two
380// instructions \p MI1 and \p MI2. The numbers of the first memory operands are
381// passed through \p N1 and \p N2.
382int64_t X86OptimizeLEAsImpl::getAddrDispShift(const MachineInstr &MI1,
383 unsigned N1,
384 const MachineInstr &MI2,
385 unsigned N2) const {
386 const MachineOperand &Op1 = MI1.getOperand(N1 + X86::AddrDisp);
387 const MachineOperand &Op2 = MI2.getOperand(N2 + X86::AddrDisp);
388
389 assert(isSimilarDispOp(Op1, Op2) &&
390 "Address displacement operands are not compatible");
391
392 // After the assert above we can be sure that both operands are of the same
393 // valid type and use the same symbol/index/address, thus displacement shift
394 // calculation is rather simple.
395 if (Op1.isJTI())
396 return 0;
397 return Op1.isImm() ? Op1.getImm() - Op2.getImm()
398 : Op1.getOffset() - Op2.getOffset();
399}
400
401// Check that the Last LEA can be replaced by the First LEA. To be so,
402// these requirements must be met:
403// 1) Addresses calculated by LEAs differ only by displacement.
404// 2) Def registers of LEAs belong to the same class.
405// 3) All uses of the Last LEA def register are replaceable, thus the
406// register is used only as address base.
407bool X86OptimizeLEAsImpl::isReplaceable(const MachineInstr &First,
408 const MachineInstr &Last,
409 int64_t &AddrDispShift) const {
410 assert(isLEA(First) && isLEA(Last) &&
411 "The function works only with LEA instructions");
412
413 // Make sure that LEA def registers belong to the same class. There may be
414 // instructions (like MOV8mr_NOREX) which allow a limited set of registers to
415 // be used as their operands, so we must be sure that replacing one LEA
416 // with another won't lead to putting a wrong register in the instruction.
417 if (MRI->getRegClass(First.getOperand(0).getReg()) !=
418 MRI->getRegClass(Last.getOperand(0).getReg()))
419 return false;
420
421 // Get new address displacement.
422 AddrDispShift = getAddrDispShift(Last, 1, First, 1);
423
424 // Loop over all uses of the Last LEA to check that its def register is
425 // used only as address base for memory accesses. If so, it can be
426 // replaced, otherwise - no.
427 for (auto &MO : MRI->use_nodbg_operands(Last.getOperand(0).getReg())) {
428 MachineInstr &MI = *MO.getParent();
429
430 // Get the number of the first memory operand.
431 const MCInstrDesc &Desc = MI.getDesc();
432 int MemOpNo = X86II::getMemoryOperandNo(Desc.TSFlags);
433
434 // If the use instruction has no memory operand - the LEA is not
435 // replaceable.
436 if (MemOpNo < 0)
437 return false;
438
439 MemOpNo += X86II::getOperandBias(Desc);
440
441 // If the address base of the use instruction is not the LEA def register -
442 // the LEA is not replaceable.
443 if (!isIdenticalOp(MI.getOperand(MemOpNo + X86::AddrBaseReg), MO))
444 return false;
445
446 // If the LEA def register is used as any other operand of the use
447 // instruction - the LEA is not replaceable.
448 for (unsigned i = 0; i < MI.getNumOperands(); i++)
449 if (i != (unsigned)(MemOpNo + X86::AddrBaseReg) &&
450 isIdenticalOp(MI.getOperand(i), MO))
451 return false;
452
453 // Check that the new address displacement will fit 4 bytes.
454 if (MI.getOperand(MemOpNo + X86::AddrDisp).isImm() &&
455 !isInt<32>(MI.getOperand(MemOpNo + X86::AddrDisp).getImm() +
456 AddrDispShift))
457 return false;
458 }
459
460 return true;
461}
462
463void X86OptimizeLEAsImpl::findLEAs(const MachineBasicBlock &MBB,
464 MemOpMap &LEAs) {
465 unsigned Pos = 0;
466 for (auto &MI : MBB) {
467 // Assign the position number to the instruction. Note that we are going to
468 // move some instructions during the optimization however there will never
469 // be a need to move two instructions before any selected instruction. So to
470 // avoid multiple positions' updates during moves we just increase position
471 // counter by two leaving a free space for instructions which will be moved.
472 InstrPos[&MI] = Pos += 2;
473
474 if (isLEA(MI))
475 LEAs[getMemOpKey(MI, 1)].push_back(const_cast<MachineInstr *>(&MI));
476 }
477}
478
479// Try to find load and store instructions which recalculate addresses already
480// calculated by some LEA and replace their memory operands with its def
481// register.
482bool X86OptimizeLEAsImpl::removeRedundantAddrCalc(MemOpMap &LEAs) {
483 bool Changed = false;
484
485 assert(!LEAs.empty());
486 MachineBasicBlock *MBB = (*LEAs.begin()->second.begin())->getParent();
487
488 // Process all instructions in basic block.
489 for (MachineInstr &MI : llvm::make_early_inc_range(*MBB)) {
490 // Instruction must be load or store.
491 if (!MI.mayLoadOrStore())
492 continue;
493
494 // Get the number of the first memory operand.
495 const MCInstrDesc &Desc = MI.getDesc();
496 int MemOpNo = X86II::getMemoryOperandNo(Desc.TSFlags);
497
498 // If instruction has no memory operand - skip it.
499 if (MemOpNo < 0)
500 continue;
501
502 MemOpNo += X86II::getOperandBias(Desc);
503
504 // Do not call chooseBestLEA if there was no matching LEA
505 auto Insns = LEAs.find(getMemOpKey(MI, MemOpNo));
506 if (Insns == LEAs.end())
507 continue;
508
509 // Get the best LEA instruction to replace address calculation.
510 MachineInstr *DefMI;
511 int64_t AddrDispShift;
512 int Dist;
513 if (!chooseBestLEA(Insns->second, MI, DefMI, AddrDispShift, Dist))
514 continue;
515
516 // If LEA occurs before current instruction, we can freely replace
517 // the instruction. If LEA occurs after, we can lift LEA above the
518 // instruction and this way to be able to replace it. Since LEA and the
519 // instruction have similar memory operands (thus, the same def
520 // instructions for these operands), we can always do that, without
521 // worries of using registers before their defs.
522 if (Dist < 0) {
525 InstrPos[DefMI] = InstrPos[&MI] - 1;
526
527 // Make sure the instructions' position numbers are sane.
528 assert(((InstrPos[DefMI] == 1 &&
530 InstrPos[DefMI] >
531 InstrPos[&*std::prev(MachineBasicBlock::iterator(DefMI))]) &&
532 "Instruction positioning is broken");
533 }
534
535 // Since we can possibly extend register lifetime, clear kill flags.
537
538 ++NumSubstLEAs;
539 LLVM_DEBUG(dbgs() << "OptimizeLEAs: Candidate to replace: "; MI.dump(););
540
541 // Change instruction operands.
542 MI.getOperand(MemOpNo + X86::AddrBaseReg)
543 .ChangeToRegister(DefMI->getOperand(0).getReg(), false);
544 MI.getOperand(MemOpNo + X86::AddrScaleAmt).ChangeToImmediate(1);
545 MI.getOperand(MemOpNo + X86::AddrIndexReg)
546 .ChangeToRegister(X86::NoRegister, false);
547 MI.getOperand(MemOpNo + X86::AddrDisp).ChangeToImmediate(AddrDispShift);
548 MI.getOperand(MemOpNo + X86::AddrSegmentReg)
549 .ChangeToRegister(X86::NoRegister, false);
550
551 LLVM_DEBUG(dbgs() << "OptimizeLEAs: Replaced by: "; MI.dump(););
552
553 Changed = true;
554 }
555
556 return Changed;
557}
558
559MachineInstr *X86OptimizeLEAsImpl::replaceDebugValue(MachineInstr &MI,
560 Register OldReg,
561 Register NewReg,
562 int64_t AddrDispShift) {
563 const DIExpression *Expr = MI.getDebugExpression();
564 if (AddrDispShift != 0) {
565 if (MI.isNonListDebugValue()) {
566 Expr =
568 } else {
569 // Update the Expression, appending an offset of `AddrDispShift` to the
570 // Op corresponding to `OldReg`.
572 DIExpression::appendOffset(Ops, AddrDispShift);
573 for (MachineOperand &Op : MI.getDebugOperandsForReg(OldReg)) {
574 unsigned OpIdx = MI.getDebugOperandIndex(&Op);
576 }
577 }
578 }
579
580 // Replace DBG_VALUE instruction with modified version.
581 MachineBasicBlock *MBB = MI.getParent();
582 DebugLoc DL = MI.getDebugLoc();
583 bool IsIndirect = MI.isIndirectDebugValue();
584 const MDNode *Var = MI.getDebugVariable();
585 unsigned Opcode = MI.isNonListDebugValue() ? TargetOpcode::DBG_VALUE
586 : TargetOpcode::DBG_VALUE_LIST;
587 if (IsIndirect)
588 assert(MI.getDebugOffset().getImm() == 0 &&
589 "DBG_VALUE with nonzero offset");
591 // If we encounter an operand using the old register, replace it with an
592 // operand that uses the new register; otherwise keep the old operand.
593 auto replaceOldReg = [OldReg, NewReg](const MachineOperand &Op) {
594 if (Op.isReg() && Op.getReg() == OldReg)
595 return MachineOperand::CreateReg(NewReg, false, false, false, false,
596 false, false, false, false, false,
597 /*IsRenamable*/ true);
598 return Op;
599 };
600 for (const MachineOperand &Op : MI.debug_operands())
601 NewOps.push_back(replaceOldReg(Op));
602 return BuildMI(*MBB, MBB->erase(&MI), DL, TII->get(Opcode), IsIndirect,
603 NewOps, Var, Expr);
604}
605
606// Try to find similar LEAs in the list and replace one with another.
607bool X86OptimizeLEAsImpl::removeRedundantLEAs(MemOpMap &LEAs) {
608 bool Changed = false;
609
610 // Loop over all entries in the table.
611 for (auto &E : LEAs) {
612 auto &List = E.second;
613
614 // Loop over all LEA pairs.
615 auto I1 = List.begin();
616 while (I1 != List.end()) {
617 MachineInstr &First = **I1;
618 auto I2 = std::next(I1);
619 while (I2 != List.end()) {
620 MachineInstr &Last = **I2;
621 int64_t AddrDispShift;
622
623 // LEAs should be in occurrence order in the list, so we can freely
624 // replace later LEAs with earlier ones.
625 assert(calcInstrDist(First, Last) > 0 &&
626 "LEAs must be in occurrence order in the list");
627
628 // Check that the Last LEA instruction can be replaced by the First.
629 if (!isReplaceable(First, Last, AddrDispShift)) {
630 ++I2;
631 continue;
632 }
633
634 // Loop over all uses of the Last LEA and update their operands. Note
635 // that the correctness of this has already been checked in the
636 // isReplaceable function.
637 Register FirstVReg = First.getOperand(0).getReg();
638 Register LastVReg = Last.getOperand(0).getReg();
639 // We use MRI->use_empty here instead of the combination of
640 // llvm::make_early_inc_range and MRI->use_operands because we could
641 // replace two or more uses in a debug instruction in one iteration, and
642 // that would deeply confuse llvm::make_early_inc_range.
643 while (!MRI->use_empty(LastVReg)) {
644 MachineOperand &MO = *MRI->use_begin(LastVReg);
645 MachineInstr &MI = *MO.getParent();
646
647 if (MI.isDebugValue()) {
648 // Replace DBG_VALUE instruction with modified version using the
649 // register from the replacing LEA and the address displacement
650 // between the LEA instructions.
651 replaceDebugValue(MI, LastVReg, FirstVReg, AddrDispShift);
652 continue;
653 }
654
655 // Get the number of the first memory operand.
656 const MCInstrDesc &Desc = MI.getDesc();
657 int MemOpNo =
660
661 // Update address base.
662 MO.setReg(FirstVReg);
663
664 // Update address disp.
665 MachineOperand &Op = MI.getOperand(MemOpNo + X86::AddrDisp);
666 if (Op.isImm())
667 Op.setImm(Op.getImm() + AddrDispShift);
668 else if (!Op.isJTI())
669 Op.setOffset(Op.getOffset() + AddrDispShift);
670 }
671
672 // Since we can possibly extend register lifetime, clear kill flags.
673 MRI->clearKillFlags(FirstVReg);
674
675 ++NumRedundantLEAs;
676 LLVM_DEBUG(dbgs() << "OptimizeLEAs: Remove redundant LEA: ";
677 Last.dump(););
678
679 // By this moment, all of the Last LEA's uses must be replaced. So we
680 // can freely remove it.
681 assert(MRI->use_empty(LastVReg) &&
682 "The LEA's def register must have no uses");
683 Last.eraseFromParent();
684
685 // Erase removed LEA from the list.
686 I2 = List.erase(I2);
687
688 Changed = true;
689 }
690 ++I1;
691 }
692 }
693
694 return Changed;
695}
696
697bool X86OptimizeLEAsImpl::runOnMachineFunction(
698 MachineFunction &MF, ProfileSummaryInfo *PSI,
699 MachineBlockFrequencyInfo *MBFI) {
700 bool Changed = false;
701
703 return false;
704
705 MRI = &MF.getRegInfo();
706 TII = MF.getSubtarget<X86Subtarget>().getInstrInfo();
707 TRI = MF.getSubtarget<X86Subtarget>().getRegisterInfo();
708
709 // Process all basic blocks.
710 for (auto &MBB : MF) {
711 MemOpMap LEAs;
712 InstrPos.clear();
713
714 // Find all LEA instructions in basic block.
715 findLEAs(MBB, LEAs);
716
717 // If current basic block has no LEAs, move on to the next one.
718 if (LEAs.empty())
719 continue;
720
721 // Remove redundant LEA instructions.
722 Changed |= removeRedundantLEAs(LEAs);
723
724 // Remove redundant address calculations. Do it only for -Os/-Oz since only
725 // a code size gain is expected from this part of the pass.
726 if (llvm::shouldOptimizeForSize(&MBB, PSI, MBFI))
727 Changed |= removeRedundantAddrCalc(LEAs);
728 }
729
730 return Changed;
731}
732
733bool X86OptimizeLEAsLegacy::runOnMachineFunction(MachineFunction &MF) {
734 if (skipFunction(MF.getFunction()))
735 return false;
736 ProfileSummaryInfo *PSI =
737 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
738 MachineBlockFrequencyInfo *MBFI =
739 (PSI && PSI->hasProfileSummary())
740 ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
741 : nullptr;
742 X86OptimizeLEAsImpl PassImpl;
743 return PassImpl.runOnMachineFunction(MF, PSI, MBFI);
744}
745
746PreservedAnalyses
749 ProfileSummaryInfo *PSI =
751 .getCachedResult<ProfileSummaryAnalysis>(
752 *MF.getFunction().getParent());
754 (PSI && PSI->hasProfileSummary())
756 : nullptr;
757 X86OptimizeLEAsImpl PassImpl;
758 bool Changed = PassImpl.runOnMachineFunction(MF, PSI, MBFI);
759 if (!Changed)
760 return PreservedAnalyses::all();
762}
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()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
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:77
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:166
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:305
#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...