LLVM 23.0.0git
AArch64ConditionOptimizer.cpp
Go to the documentation of this file.
1//=- AArch64ConditionOptimizer.cpp - Remove useless comparisons for AArch64 -=//
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 pass tries to make consecutive comparisons of values use the same
10// operands to allow the CSE pass to remove duplicate instructions.
11//
12// For two producer-consumer pairs P1 = (v, N1, CC1) and P2 = (v, N2, CC2) over
13// F where:
14// - v is a shared operand
15// - Nx are the immediates being compared such that 1 <= |N1 - N2| <= 2
16// - CCx are ordered conditions tested by the consumers (GT/LT/GE/LE)
17// - (Nx, CCx) are predicates over v
18// - F is a flag register, implicitly defined by the producers and tested by the
19// consumers
20// - No instruction between P1 and P2 reads or writes F
21//
22// Apply the following transformation:
23// 1. Find an immediate N' reachable from N1 and N2 via +-1 adjustment
24// 2. Derive CC1' and CC2' such that P1' = (v, N', CC1') and P2' = (v, N', CC2')
25// are semantically equivalent to the originals
26// 3. Modify the producers to compare against N'
27// 4. Modify the consumers to test CC1' and CC2', respectively
28//
29// This enables CSE to eliminate one of the compares.
30//
31// Consider the following example in C:
32//
33// if ((a < 5 && ...) || (a > 5 && ...)) {
34// ~~~~~ ~~~~~
35// ^ ^
36// x y
37//
38// Here both "x" and "y" expressions compare "a" with "5". When "x" evaluates
39// to "false", "y" can just check flags set by the first comparison. As a
40// result of the canonicalization employed by
41// SelectionDAGBuilder::visitSwitchCase, DAGCombine, and other target-specific
42// code, assembly ends up in the form that is not CSE friendly:
43//
44// ...
45// cmp w8, #4
46// b.gt .LBB0_3
47// ...
48// .LBB0_3:
49// cmp w8, #6
50// b.lt .LBB0_6
51// ...
52//
53// Same assembly after the pass:
54//
55// ...
56// cmp w8, #5
57// b.ge .LBB0_3
58// ...
59// .LBB0_3:
60// cmp w8, #5 // <-- CSE pass removes this instruction
61// b.le .LBB0_6
62// ...
63//
64// See optimizeBlock() for implementation details.
65//
66// TODO: maybe handle TBNZ/TBZ the same way as CMP when used instead for "a < 0"
67//
68//===----------------------------------------------------------------------===//
69
70#include "AArch64.h"
71#include "AArch64Subtarget.h"
75#include "llvm/ADT/Statistic.h"
87#include "llvm/Pass.h"
88#include "llvm/Support/Debug.h"
91#include <cassert>
92#include <cstdlib>
93
94using namespace llvm;
95
96#define DEBUG_TYPE "aarch64-condopt"
97
98STATISTIC(NumConditionsAdjusted, "Number of conditions adjusted");
99
100namespace {
101
102/// Bundles the parameters needed to adjust a comparison instruction.
103struct CmpInfo {
104 int Imm;
105 unsigned Opc;
107};
108
109class AArch64ConditionOptimizerImpl {
110 /// Represents a comparison instruction paired with its consuming
111 /// conditional instruction
112 struct CmpCondPair {
113 MachineInstr *CmpMI = nullptr;
114 MachineInstr *CondMI = nullptr;
116
117 int getImm() const { return CmpMI->getOperand(2).getImm(); }
118 unsigned getOpc() const { return CmpMI->getOpcode(); }
119 };
120
121 using PairSHT = ScopedHashTable<Register, CmpCondPair>;
122
123 const AArch64InstrInfo *TII;
124 const TargetRegisterInfo *TRI;
125 MachineDominatorTree *DomTree;
126 const MachineRegisterInfo *MRI;
127 PairSHT BlockPairs;
128
129public:
130 bool run(MachineFunction &MF, MachineDominatorTree &MDT);
131
132private:
133 bool canAdjustCmp(MachineInstr &CmpMI);
134 bool nzcvLivesOut(MachineBasicBlock *MBB);
135 CmpInfo getAdjustedCmpInfo(MachineInstr *CmpMI, AArch64CC::CondCode Cmp);
136 void updateCmpInstr(MachineInstr *CmpMI, int NewImm, unsigned NewOpc);
137 void updateCondInstr(MachineInstr *CondMI, AArch64CC::CondCode NewCC);
138 void applyCmpAdjustment(CmpCondPair &Pair, const CmpInfo &Info);
139 bool commitPendingPair(std::optional<CmpCondPair> &PendingPair);
140 bool tryOptimizePair(CmpCondPair &First, CmpCondPair &Second);
141 bool optimizeBlock(MachineBasicBlock &MBB);
142 void visitBlock(MachineDomTreeNode *Node, bool &Changed);
143};
144
145class AArch64ConditionOptimizerLegacy : public MachineFunctionPass {
146public:
147 static char ID;
148 AArch64ConditionOptimizerLegacy() : MachineFunctionPass(ID) {}
149
150 void getAnalysisUsage(AnalysisUsage &AU) const override;
151 bool runOnMachineFunction(MachineFunction &MF) override;
152
153 StringRef getPassName() const override {
154 return "AArch64 Condition Optimizer";
155 }
156};
157
158} // end anonymous namespace
159
160char AArch64ConditionOptimizerLegacy::ID = 0;
161
162INITIALIZE_PASS_BEGIN(AArch64ConditionOptimizerLegacy, "aarch64-condopt",
163 "AArch64 CondOpt Pass", false, false)
165INITIALIZE_PASS_END(AArch64ConditionOptimizerLegacy, "aarch64-condopt",
166 "AArch64 CondOpt Pass", false, false)
167
169 return new AArch64ConditionOptimizerLegacy();
170}
171
172void AArch64ConditionOptimizerLegacy::getAnalysisUsage(
173 AnalysisUsage &AU) const {
177}
178
179// Verify that the MI's immediate is adjustable and it only sets flags (pure
180// cmp)
181bool AArch64ConditionOptimizerImpl::canAdjustCmp(MachineInstr &CmpMI) {
182 unsigned ShiftAmt = AArch64_AM::getShiftValue(CmpMI.getOperand(3).getImm());
183 if (!CmpMI.getOperand(2).isImm()) {
184 LLVM_DEBUG(dbgs() << "Immediate of cmp is symbolic, " << CmpMI << '\n');
185 return false;
186 } else if (CmpMI.getOperand(2).getImm() << ShiftAmt >= 0xfff) {
187 LLVM_DEBUG(dbgs() << "Immediate of cmp may be out of range, " << CmpMI
188 << '\n');
189 return false;
190 } else if (!MRI->use_nodbg_empty(CmpMI.getOperand(0).getReg())) {
191 LLVM_DEBUG(dbgs() << "Destination of cmp is not dead, " << CmpMI << '\n');
192 return false;
193 }
194
195 return true;
196}
197
198// Check if NZCV lives out to any successor block.
199bool AArch64ConditionOptimizerImpl::nzcvLivesOut(MachineBasicBlock *MBB) {
200 for (auto *SuccBB : MBB->successors()) {
201 if (SuccBB->isLiveIn(AArch64::NZCV)) {
202 LLVM_DEBUG(dbgs() << "NZCV live into successor "
203 << printMBBReference(*SuccBB) << " from "
204 << printMBBReference(*MBB) << '\n');
205 return true;
206 }
207 }
208 return false;
209}
210
211// Returns true if the opcode is a comparison instruction (CMP/CMN).
212static bool isCmpInstruction(unsigned Opc) {
213 switch (Opc) {
214 // cmp is an alias for SUBS with a dead destination register.
215 case AArch64::SUBSWri:
216 case AArch64::SUBSXri:
217 // cmp is an alias for ADDS with a dead destination register.
218 case AArch64::ADDSWri:
219 case AArch64::ADDSXri:
220 return true;
221 default:
222 return false;
223 }
224}
225
226// Changes opcode adds <-> subs considering register operand width.
227static int getComplementOpc(int Opc) {
228 switch (Opc) {
229 case AArch64::ADDSWri: return AArch64::SUBSWri;
230 case AArch64::ADDSXri: return AArch64::SUBSXri;
231 case AArch64::SUBSWri: return AArch64::ADDSWri;
232 case AArch64::SUBSXri: return AArch64::ADDSXri;
233 default:
234 llvm_unreachable("Unexpected opcode");
235 }
236}
237
238// Changes form of comparison inclusive <-> exclusive.
240 switch (Cmp) {
241 case AArch64CC::GT:
242 return AArch64CC::GE;
243 case AArch64CC::GE:
244 return AArch64CC::GT;
245 case AArch64CC::LT:
246 return AArch64CC::LE;
247 case AArch64CC::LE:
248 return AArch64CC::LT;
249 case AArch64CC::HI:
250 return AArch64CC::HS;
251 case AArch64CC::HS:
252 return AArch64CC::HI;
253 case AArch64CC::LO:
254 return AArch64CC::LS;
255 case AArch64CC::LS:
256 return AArch64CC::LO;
257 default:
258 llvm_unreachable("Unexpected condition code");
259 }
260}
261
262// Returns the adjusted immediate, opcode, and condition code for switching
263// between inclusive/exclusive forms (GT <-> GE, LT <-> LE).
264CmpInfo
265AArch64ConditionOptimizerImpl::getAdjustedCmpInfo(MachineInstr *CmpMI,
267 unsigned Opc = CmpMI->getOpcode();
268
269 bool IsSigned = Cmp == AArch64CC::GT || Cmp == AArch64CC::GE ||
271
272 // CMN (compare with negative immediate) is an alias to ADDS (as
273 // "operand - negative" == "operand + positive")
274 bool Negative = (Opc == AArch64::ADDSWri || Opc == AArch64::ADDSXri);
275
276 int Correction = (Cmp == AArch64CC::GT || Cmp == AArch64CC::HI) ? 1 : -1;
277 // Negate Correction value for comparison with negative immediate (CMN).
278 if (Negative) {
279 Correction = -Correction;
280 }
281
282 const int OldImm = (int)CmpMI->getOperand(2).getImm();
283 const int NewImm = std::abs(OldImm + Correction);
284
285 // Bail out on cmn 0 (ADDS with immediate 0). It is a valid instruction but
286 // doesn't set flags in a way we can safely transform, so skip optimization.
287 if (OldImm == 0 && Negative)
288 return {OldImm, Opc, Cmp};
289
290 if ((OldImm == 1 && Negative && Correction == -1) ||
291 (OldImm == 0 && Correction == -1)) {
292 // If we change opcodes for unsigned comparisons, this means we did an
293 // unsigned wrap (e.g., 0 wrapping to 0xFFFFFFFF), so return the old cmp.
294 // Note: For signed comparisons, opcode changes (cmn 1 ↔ cmp 0) are valid.
295 if (!IsSigned)
296 return {OldImm, Opc, Cmp};
298 }
299
300 return {NewImm, Opc, getAdjustedCmp(Cmp)};
301}
302
303// Modifies a comparison instruction's immediate and opcode.
304void AArch64ConditionOptimizerImpl::updateCmpInstr(MachineInstr *CmpMI,
305 int NewImm,
306 unsigned NewOpc) {
307 CmpMI->getOperand(2).setImm(NewImm);
308 CmpMI->setDesc(TII->get(NewOpc));
309}
310
311// Modifies the condition code of a conditional instruction.
312void AArch64ConditionOptimizerImpl::updateCondInstr(MachineInstr *CondMI,
313 AArch64CC::CondCode NewCC) {
314 int CCOpIdx =
315 AArch64InstrInfo::findCondCodeUseOperandIdxForBranchOrSelect(*CondMI);
316 assert(CCOpIdx >= 0 && "Unsupported conditional instruction");
317 CondMI->getOperand(CCOpIdx).setImm(NewCC);
318 ++NumConditionsAdjusted;
319}
320
321// Applies a comparison adjustment to a cmp/cond instruction pair.
322void AArch64ConditionOptimizerImpl::applyCmpAdjustment(CmpCondPair &Pair,
323 const CmpInfo &Info) {
324 updateCmpInstr(Pair.CmpMI, Info.Imm, Info.Opc);
325 updateCondInstr(Pair.CondMI, Info.CC);
326 Pair.CC = Info.CC;
327}
328
330 return Cmp == AArch64CC::GT || Cmp == AArch64CC::HI;
331}
332
334 return Cmp == AArch64CC::LT || Cmp == AArch64CC::LO;
335}
336
337bool AArch64ConditionOptimizerImpl::tryOptimizePair(CmpCondPair &First,
338 CmpCondPair &Second) {
339 if (!((isGreaterThan(First.CC) || isLessThan(First.CC)) &&
340 (isGreaterThan(Second.CC) || isLessThan(Second.CC))))
341 return false;
342
343 int FirstImmTrueValue = First.getImm();
344 int SecondImmTrueValue = Second.getImm();
345
346 // Normalize immediate of CMN (ADDS) instructions
347 if (First.getOpc() == AArch64::ADDSWri || First.getOpc() == AArch64::ADDSXri)
348 FirstImmTrueValue = -FirstImmTrueValue;
349 if (Second.getOpc() == AArch64::ADDSWri ||
350 Second.getOpc() == AArch64::ADDSXri)
351 SecondImmTrueValue = -SecondImmTrueValue;
352
353 CmpInfo FirstAdj = getAdjustedCmpInfo(First.CmpMI, First.CC);
354 CmpInfo SecondAdj = getAdjustedCmpInfo(Second.CmpMI, Second.CC);
355
356 if (((isGreaterThan(First.CC) && isLessThan(Second.CC)) ||
357 (isLessThan(First.CC) && isGreaterThan(Second.CC))) &&
358 std::abs(SecondImmTrueValue - FirstImmTrueValue) == 2) {
359 // This branch transforms machine instructions that correspond to
360 //
361 // 1) (a > {SecondImm} && ...) || (a < {FirstImm} && ...)
362 // 2) (a < {SecondImm} && ...) || (a > {FirstImm} && ...)
363 //
364 // into
365 //
366 // 1) (a >= {NewImm} && ...) || (a <= {NewImm} && ...)
367 // 2) (a <= {NewImm} && ...) || (a >= {NewImm} && ...)
368
369 // Verify both adjustments converge to identical comparisons (same
370 // immediate and opcode). This ensures CSE can eliminate the duplicate.
371 if (FirstAdj.Imm != SecondAdj.Imm || FirstAdj.Opc != SecondAdj.Opc)
372 return false;
373
374 LLVM_DEBUG(dbgs() << "Optimized (opposite): "
375 << AArch64CC::getCondCodeName(First.CC) << " #"
376 << First.getImm() << ", "
377 << AArch64CC::getCondCodeName(Second.CC) << " #"
378 << Second.getImm() << " -> "
379 << AArch64CC::getCondCodeName(FirstAdj.CC) << " #"
380 << FirstAdj.Imm << ", "
381 << AArch64CC::getCondCodeName(SecondAdj.CC) << " #"
382 << SecondAdj.Imm << '\n');
383 applyCmpAdjustment(First, FirstAdj);
384 applyCmpAdjustment(Second, SecondAdj);
385 return true;
386
387 } else if (((isGreaterThan(First.CC) && isGreaterThan(Second.CC)) ||
388 (isLessThan(First.CC) && isLessThan(Second.CC))) &&
389 std::abs(SecondImmTrueValue - FirstImmTrueValue) == 1) {
390 // This branch transforms machine instructions that correspond to
391 //
392 // 1) (a > {SecondImm} && ...) || (a > {FirstImm} && ...)
393 // 2) (a < {SecondImm} && ...) || (a < {FirstImm} && ...)
394 //
395 // into
396 //
397 // 1) (a <= {NewImm} && ...) || (a > {NewImm} && ...)
398 // 2) (a < {NewImm} && ...) || (a >= {NewImm} && ...)
399
400 // GT -> GE transformation increases immediate value, so picking the
401 // smaller one; LT -> LE decreases immediate value so invert the choice.
402 bool AdjustFirst = (FirstImmTrueValue < SecondImmTrueValue);
403 if (isLessThan(First.CC))
404 AdjustFirst = !AdjustFirst;
405
406 CmpCondPair &Target = AdjustFirst ? Second : First;
407 CmpCondPair &ToChange = AdjustFirst ? First : Second;
408 CmpInfo &Adj = AdjustFirst ? FirstAdj : SecondAdj;
409
410 // Verify the adjustment converges to the target's comparison (same
411 // immediate and opcode). This ensures CSE can eliminate the duplicate.
412 if (Adj.Imm != Target.getImm() || Adj.Opc != Target.getOpc())
413 return false;
414
415 LLVM_DEBUG(dbgs() << "Optimized (same-direction): "
416 << AArch64CC::getCondCodeName(ToChange.CC) << " #"
417 << ToChange.getImm() << " -> "
418 << AArch64CC::getCondCodeName(Adj.CC) << " #" << Adj.Imm
419 << '\n');
420 applyCmpAdjustment(ToChange, Adj);
421 return true;
422 }
423
424 // Other transformation cases almost never occur due to generation of < or >
425 // comparisons instead of <= and >=.
426 return false;
427}
428
429bool AArch64ConditionOptimizerImpl::commitPendingPair(
430 std::optional<CmpCondPair> &PendingPair) {
431 if (!PendingPair)
432 return false;
433
434 Register Reg = PendingPair->CmpMI->getOperand(1).getReg();
435 Register Key = Reg.isVirtual() ? TRI->lookThruCopyLike(Reg, MRI) : Reg;
436
437 CmpCondPair Prior = BlockPairs.lookup(Key);
438 bool Changed = Prior.CmpMI && tryOptimizePair(Prior, *PendingPair);
439
440 BlockPairs.insert(Key, *PendingPair);
441 PendingPair = std::nullopt;
442 return Changed;
443}
444
445// This function transforms cmps and their consuming conditionals (CmpCondPairs)
446// 1. Same direction: when both conditions are the same (e.g. GT/GT or LT/LT)
447// and immediates differ by 1
448// 2. Opposite direction: when both conditions are adjustable to a common middle
449// (e.g., GT/LT) and immediates differ by 2.
450// The compare instructions are made to match to enable CSE.
451// All cmp/cond pairs within a basic block are examined
452//
453// Example transformation:
454// cmp w8, #10
455// csinc w9, w0, w1, gt ; w9 = (w8 > 10) ? w0 : w1+1
456// cmp w8, #9
457// csinc w10, w0, w1, gt ; w10 = (w8 > 9) ? w0 : w1+1
458//
459// Into:
460// cmp w8, #10
461// csinc w9, w0, w1, gt ; w9 = (w8 > 10) ? w0 : w1+1
462// cmp w8, #10 ; <- CSE can remove the redundant cmp
463// csinc w10, w0, w1, ge ; w10 = (w8 >= 10) ? w0 : w1+1
464//
465bool AArch64ConditionOptimizerImpl::optimizeBlock(MachineBasicBlock &MBB) {
466 std::optional<CmpCondPair> PendingPair;
467 MachineInstr *ActiveCmp = nullptr;
468 bool Changed = false;
469
470 for (MachineInstr &MI : MBB) {
471 if (MI.isDebugInstr())
472 continue;
473
474 if (isCmpInstruction(MI.getOpcode()) && canAdjustCmp(MI)) {
475 Changed |= commitPendingPair(PendingPair);
476 ActiveCmp = &MI;
477 continue;
478 }
479
480 if (MI.modifiesRegister(AArch64::NZCV, /*TRI=*/nullptr)) {
481 // Non-CMP clobber: commit any pending pair and reset local state.
482 Changed |= commitPendingPair(PendingPair);
483 ActiveCmp = nullptr;
484 continue;
485 }
486
487 if (AArch64InstrInfo::findCondCodeUseOperandIdxForBranchOrSelect(MI) >= 0) {
488 if (PendingPair) {
489 // A second conditional consuming the same CMP would invalidate any
490 // optimization: modifying the CMP would silently change what both
491 // consumers compare against. Mark the CMP spent.
492 PendingPair = std::nullopt;
493 ActiveCmp = nullptr;
494 } else if (ActiveCmp) {
495 int CCOpIdx =
496 AArch64InstrInfo::findCondCodeUseOperandIdxForBranchOrSelect(MI);
497 assert(CCOpIdx >= 0 && "Unsupported conditional instruction");
499 (AArch64CC::CondCode)(int)MI.getOperand(CCOpIdx).getImm();
500 PendingPair = CmpCondPair{ActiveCmp, &MI, CC};
501 }
502 continue;
503 }
504
505 if (MI.readsRegister(AArch64::NZCV, /*TRI=*/nullptr)) {
506 ActiveCmp = nullptr;
507 PendingPair = std::nullopt;
508 continue;
509 }
510 }
511
512 // Only commit the final pending pair if NZCV doesn't live out: a cross-block
513 // consumer would be affected by any CMP adjustment we make.
514 if (!nzcvLivesOut(&MBB))
515 Changed |= commitPendingPair(PendingPair);
516
517 return Changed;
518}
519
520bool AArch64ConditionOptimizerLegacy::runOnMachineFunction(
521 MachineFunction &MF) {
522 if (skipFunction(MF.getFunction()))
523 return false;
524 MachineDominatorTree &MDT =
525 getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
526 return AArch64ConditionOptimizerImpl().run(MF, MDT);
527}
528
529void AArch64ConditionOptimizerImpl::visitBlock(MachineDomTreeNode *Node,
530 bool &Changed) {
531 ScopedHashTableScope<Register, CmpCondPair> Scope(BlockPairs);
532 Changed |= optimizeBlock(*Node->getBlock());
533 for (auto *Child : Node->children())
534 visitBlock(Child, Changed);
535}
536
537bool AArch64ConditionOptimizerImpl::run(MachineFunction &MF,
538 MachineDominatorTree &MDT) {
539 LLVM_DEBUG(dbgs() << "********** AArch64 Conditional Compares **********\n"
540 << "********** Function: " << MF.getName() << '\n');
541
542 TII = static_cast<const AArch64InstrInfo *>(MF.getSubtarget().getInstrInfo());
544 DomTree = &MDT;
545 MRI = &MF.getRegInfo();
546
547 bool Changed = false;
548 visitBlock(DomTree->getRootNode(), Changed);
549 return Changed;
550}
551
552PreservedAnalyses
555 auto &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
556 bool Changed = AArch64ConditionOptimizerImpl().run(MF, MDT);
557 if (!Changed)
558 return PreservedAnalyses::all();
561 return PA;
562}
static int getComplementOpc(int Opc)
static bool isGreaterThan(AArch64CC::CondCode Cmp)
static AArch64CC::CondCode getAdjustedCmp(AArch64CC::CondCode Cmp)
static bool isLessThan(AArch64CC::CondCode Cmp)
static bool isCmpInstruction(unsigned Opc)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
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
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
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
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
iterator_range< succ_iterator > successors()
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
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.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
const MachineOperand & getOperand(unsigned i) const
void setImm(int64_t immVal)
int64_t getImm() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
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
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
void insert(const K &Key, const V &Val)
V lookup(const K &Key) const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static const char * getCondCodeName(CondCode Code)
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
DXILDebugInfoMap run(Module &M)
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createAArch64ConditionOptimizerLegacyPass()
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.