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