LLVM 24.0.0git
MachineCombiner.cpp
Go to the documentation of this file.
1//===---- MachineCombiner.cpp - Instcombining on SSA form machine code ----===//
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// The machine combiner pass uses machine trace metrics to ensure the combined
10// instructions do not lengthen the critical path or the resource depth.
11//===----------------------------------------------------------------------===//
12
13#include "llvm/ADT/DenseMap.h"
14#include "llvm/ADT/Statistic.h"
32#include "llvm/Support/Debug.h"
34
35using namespace llvm;
36
37#define DEBUG_TYPE "machine-combiner"
38
39STATISTIC(NumInstCombined, "Number of machineinst combined");
40
42inc_threshold("machine-combiner-inc-threshold", cl::Hidden,
43 cl::desc("Incremental depth computation will be used for basic "
44 "blocks with more instructions."), cl::init(500));
45
46static cl::opt<bool> dump_intrs("machine-combiner-dump-subst-intrs", cl::Hidden,
47 cl::desc("Dump all substituted intrs"),
48 cl::init(false));
49
50#ifdef EXPENSIVE_CHECKS
52 "machine-combiner-verify-pattern-order", cl::Hidden,
54 "Verify that the generated patterns are ordered by increasing latency"),
55 cl::init(true));
56#else
58 "machine-combiner-verify-pattern-order", cl::Hidden,
60 "Verify that the generated patterns are ordered by increasing latency"),
61 cl::init(false));
62#endif
63
64namespace {
65class MachineCombiner : public MachineFunctionPass {
66 const TargetSubtargetInfo *STI = nullptr;
67 const TargetInstrInfo *TII = nullptr;
68 const TargetRegisterInfo *TRI = nullptr;
69 MCSchedModel SchedModel;
70 MachineRegisterInfo *MRI = nullptr;
71 MachineLoopInfo *MLI = nullptr; // Current MachineLoopInfo
72 MachineTraceMetrics *Traces = nullptr;
73 MachineTraceMetrics::Ensemble *TraceEnsemble = nullptr;
74 MachineBlockFrequencyInfo *MBFI = nullptr;
75 ProfileSummaryInfo *PSI = nullptr;
76 RegisterClassInfo *RegClassInfo = nullptr;
77
78 TargetSchedModel TSchedModel;
79
80public:
81 static char ID;
82 MachineCombiner() : MachineFunctionPass(ID) {}
83 void getAnalysisUsage(AnalysisUsage &AU) const override;
84 bool runOnMachineFunction(MachineFunction &MF) override;
85 StringRef getPassName() const override { return "Machine InstCombiner"; }
86
87private:
88 bool combineInstructions(MachineBasicBlock *);
89 MachineInstr *getOperandDef(const MachineOperand &MO);
90 bool isTransientMI(const MachineInstr *MI);
91 unsigned getDepth(SmallVectorImpl<MachineInstr *> &InsInstrs,
92 DenseMap<Register, unsigned> &InstrIdxForVirtReg,
94 const MachineBasicBlock &MBB);
95 unsigned getLatency(MachineInstr *Root, MachineInstr *NewRoot,
97 bool improvesCriticalPathLen(MachineBasicBlock *MBB, MachineInstr *Root,
99 SmallVectorImpl<MachineInstr *> &InsInstrs,
100 SmallVectorImpl<MachineInstr *> &DelInstrs,
101 DenseMap<Register, unsigned> &InstrIdxForVirtReg,
102 unsigned Pattern, bool SlackIsAccurate);
103 bool reduceRegisterPressure(MachineInstr &Root, MachineBasicBlock *MBB,
104 SmallVectorImpl<MachineInstr *> &InsInstrs,
105 SmallVectorImpl<MachineInstr *> &DelInstrs,
106 unsigned Pattern);
107 bool preservesResourceLen(MachineBasicBlock *MBB,
109 SmallVectorImpl<MachineInstr *> &InsInstrs,
110 SmallVectorImpl<MachineInstr *> &DelInstrs);
111 void instr2instrSC(SmallVectorImpl<MachineInstr *> &Instrs,
112 SmallVectorImpl<const MCSchedClassDesc *> &InstrsSC);
113 std::pair<unsigned, unsigned>
114 getLatenciesForInstrSequences(MachineInstr &MI,
115 SmallVectorImpl<MachineInstr *> &InsInstrs,
116 SmallVectorImpl<MachineInstr *> &DelInstrs,
117 MachineTraceMetrics::Trace BlockTrace);
118
119 CombinerObjective getCombinerObjective(unsigned Pattern);
120};
121}
122
123char MachineCombiner::ID = 0;
124char &llvm::MachineCombinerID = MachineCombiner::ID;
125
127 "Machine InstCombiner", false, false)
131INITIALIZE_PASS_END(MachineCombiner, DEBUG_TYPE, "Machine InstCombiner",
133
134void MachineCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
135 AU.setPreservesCFG();
136 AU.addPreserved<MachineDominatorTreeWrapperPass>();
137 AU.addRequired<MachineLoopInfoWrapperPass>();
138 AU.addPreserved<MachineLoopInfoWrapperPass>();
139 AU.addRequired<MachineRegisterClassInfoWrapperPass>();
140 AU.addPreserved<MachineRegisterClassInfoWrapperPass>();
141 AU.addRequired<MachineTraceMetricsWrapperPass>();
142 AU.addPreserved<MachineTraceMetricsWrapperPass>();
143 AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
144 AU.addRequired<ProfileSummaryInfoWrapperPass>();
146}
147
149MachineCombiner::getOperandDef(const MachineOperand &MO) {
150 MachineInstr *DefInstr = nullptr;
151 // We need a virtual register definition.
152 if (MO.isReg() && MO.getReg().isVirtual())
153 DefInstr = MRI->getUniqueVRegDef(MO.getReg());
154 return DefInstr;
155}
156
157/// Return true if MI is unlikely to generate an actual target instruction.
158bool MachineCombiner::isTransientMI(const MachineInstr *MI) {
159 if (!MI->isCopy())
160 return MI->isTransient();
161
162 // If MI is a COPY, check if its src and dst registers can be coalesced.
163 Register Dst = MI->getOperand(0).getReg();
164 Register Src = MI->getOperand(1).getReg();
165
166 if (!MI->isFullCopy()) {
167 // If src RC contains super registers of dst RC, it can also be coalesced.
168 if (MI->getOperand(0).getSubReg() || Src.isPhysical() || Dst.isPhysical())
169 return false;
170
171 auto SrcSub = MI->getOperand(1).getSubReg();
172 auto SrcRC = MRI->getRegClass(Src);
173 auto DstRC = MRI->getRegClass(Dst);
174 return TRI->getMatchingSuperRegClass(SrcRC, DstRC, SrcSub) != nullptr;
175 }
176
177 if (Src.isPhysical() && Dst.isPhysical())
178 return Src == Dst;
179
180 if (Src.isVirtual() && Dst.isVirtual()) {
181 auto SrcRC = MRI->getRegClass(Src);
182 auto DstRC = MRI->getRegClass(Dst);
183 return SrcRC->hasSuperClassEq(DstRC) || SrcRC->hasSubClassEq(DstRC);
184 }
185
186 if (Src.isVirtual())
187 std::swap(Src, Dst);
188
189 // Now Src is physical register, Dst is virtual register.
190 auto DstRC = MRI->getRegClass(Dst);
191 return DstRC->contains(Src);
192}
193
194/// Computes depth of instructions in vector \InsInstr.
195///
196/// \param InsInstrs is a vector of machine instructions
197/// \param InstrIdxForVirtReg is a dense map of virtual register to index
198/// of defining machine instruction in \p InsInstrs
199/// \param BlockTrace is a trace of machine instructions
200///
201/// \returns Depth of last instruction in \InsInstrs ("NewRoot")
202unsigned
203MachineCombiner::getDepth(SmallVectorImpl<MachineInstr *> &InsInstrs,
204 DenseMap<Register, unsigned> &InstrIdxForVirtReg,
206 const MachineBasicBlock &MBB) {
207 SmallVector<unsigned, 16> InstrDepth;
208 // For each instruction in the new sequence compute the depth based on the
209 // operands. Use the trace information when possible. For new operands which
210 // are tracked in the InstrIdxForVirtReg map depth is looked up in InstrDepth
211 for (auto *InstrPtr : InsInstrs) { // for each Use
212 unsigned IDepth = 0;
213 for (const MachineOperand &MO : InstrPtr->all_uses()) {
214 // Check for virtual register operand.
215 if (!MO.getReg().isVirtual())
216 continue;
217 unsigned DepthOp = 0;
218 unsigned LatencyOp = 0;
219 auto II = InstrIdxForVirtReg.find(MO.getReg());
220 if (II != InstrIdxForVirtReg.end()) {
221 // Operand is new virtual register not in trace
222 assert(II->second < InstrDepth.size() && "Bad Index");
223 MachineInstr *DefInstr = InsInstrs[II->second];
224 assert(DefInstr &&
225 "There must be a definition for a new virtual register");
226 DepthOp = InstrDepth[II->second];
227 int DefIdx =
228 DefInstr->findRegisterDefOperandIdx(MO.getReg(), /*TRI=*/nullptr);
229 int UseIdx =
230 InstrPtr->findRegisterUseOperandIdx(MO.getReg(), /*TRI=*/nullptr);
231 LatencyOp = TSchedModel.computeOperandLatency(DefInstr, DefIdx,
232 InstrPtr, UseIdx);
233 } else {
234 MachineInstr *DefInstr = getOperandDef(MO);
235 if (DefInstr && (TII->getMachineCombinerTraceStrategy() !=
236 MachineTraceStrategy::TS_Local ||
237 DefInstr->getParent() == &MBB)) {
238 DepthOp = BlockTrace.getInstrCycles(*DefInstr).Depth;
239 if (!isTransientMI(DefInstr))
240 LatencyOp = TSchedModel.computeOperandLatency(
241 DefInstr,
242 DefInstr->findRegisterDefOperandIdx(MO.getReg(),
243 /*TRI=*/nullptr),
244 InstrPtr,
245 InstrPtr->findRegisterUseOperandIdx(MO.getReg(),
246 /*TRI=*/nullptr));
247 }
248 }
249 IDepth = std::max(IDepth, DepthOp + LatencyOp);
250 }
251 InstrDepth.push_back(IDepth);
252 }
253 unsigned NewRootIdx = InsInstrs.size() - 1;
254 return InstrDepth[NewRootIdx];
255}
256
257/// Computes instruction latency as max of latency of defined operands.
258///
259/// \param Root is a machine instruction that could be replaced by NewRoot.
260/// It is used to compute a more accurate latency information for NewRoot in
261/// case there is a dependent instruction in the same trace (\p BlockTrace)
262/// \param NewRoot is the instruction for which the latency is computed
263/// \param BlockTrace is a trace of machine instructions
264///
265/// \returns Latency of \p NewRoot
266unsigned MachineCombiner::getLatency(MachineInstr *Root, MachineInstr *NewRoot,
267 MachineTraceMetrics::Trace BlockTrace) {
268 // Check each definition in NewRoot and compute the latency
269 unsigned NewRootLatency = 0;
270
271 for (const MachineOperand &MO : NewRoot->all_defs()) {
272 // Check for virtual register operand.
273 if (!MO.getReg().isVirtual())
274 continue;
275 // Get the first instruction that uses MO
277 RI++;
278 if (RI == MRI->reg_end())
279 continue;
280 MachineInstr *UseMO = RI->getParent();
281 unsigned LatencyOp = 0;
282 if (UseMO && BlockTrace.isDepInTrace(*Root, *UseMO)) {
283 LatencyOp = TSchedModel.computeOperandLatency(
284 NewRoot,
285 NewRoot->findRegisterDefOperandIdx(MO.getReg(), /*TRI=*/nullptr),
286 UseMO,
287 UseMO->findRegisterUseOperandIdx(MO.getReg(), /*TRI=*/nullptr));
288 } else {
289 LatencyOp = TSchedModel.computeInstrLatency(NewRoot);
290 }
291 NewRootLatency = std::max(NewRootLatency, LatencyOp);
292 }
293 return NewRootLatency;
294}
295
296CombinerObjective MachineCombiner::getCombinerObjective(unsigned Pattern) {
297 // TODO: If C++ ever gets a real enum class, make this part of the
298 // MachineCombinerPattern class.
299 switch (Pattern) {
300 case MachineCombinerPattern::REASSOC_AX_BY:
301 case MachineCombinerPattern::REASSOC_AX_YB:
302 case MachineCombinerPattern::REASSOC_XA_BY:
303 case MachineCombinerPattern::REASSOC_XA_YB:
304 return CombinerObjective::MustReduceDepth;
305 default:
306 return TII->getCombinerObjective(Pattern);
307 }
308}
309
310/// Estimate the latency of the new and original instruction sequence by summing
311/// up the latencies of the inserted and deleted instructions. This assumes
312/// that the inserted and deleted instructions are dependent instruction chains,
313/// which might not hold in all cases.
314std::pair<unsigned, unsigned> MachineCombiner::getLatenciesForInstrSequences(
315 MachineInstr &MI, SmallVectorImpl<MachineInstr *> &InsInstrs,
316 SmallVectorImpl<MachineInstr *> &DelInstrs,
317 MachineTraceMetrics::Trace BlockTrace) {
318 assert(!InsInstrs.empty() && "Only support sequences that insert instrs.");
319 unsigned NewRootLatency = 0;
320 // NewRoot is the last instruction in the \p InsInstrs vector.
321 MachineInstr *NewRoot = InsInstrs.back();
322 for (unsigned i = 0; i < InsInstrs.size() - 1; i++)
323 NewRootLatency += TSchedModel.computeInstrLatency(InsInstrs[i]);
324 NewRootLatency += getLatency(&MI, NewRoot, BlockTrace);
325
326 unsigned RootLatency = 0;
327 for (auto *I : DelInstrs)
328 RootLatency += TSchedModel.computeInstrLatency(I);
329
330 return {NewRootLatency, RootLatency};
331}
332
333bool MachineCombiner::reduceRegisterPressure(
334 MachineInstr &Root, MachineBasicBlock *MBB,
335 SmallVectorImpl<MachineInstr *> &InsInstrs,
336 SmallVectorImpl<MachineInstr *> &DelInstrs, unsigned Pattern) {
337 // FIXME: for now, we don't do any check for the register pressure patterns.
338 // We treat them as always profitable. But we can do better if we make
339 // RegPressureTracker class be aware of TIE attribute. Then we can get an
340 // accurate compare of register pressure with DelInstrs or InsInstrs.
341 return true;
342}
343
344/// The DAGCombine code sequence ends in MI (Machine Instruction) Root.
345/// The new code sequence ends in MI NewRoot. A necessary condition for the new
346/// sequence to replace the old sequence is that it cannot lengthen the critical
347/// path. The definition of "improve" may be restricted by specifying that the
348/// new path improves the data dependency chain (MustReduceDepth).
349bool MachineCombiner::improvesCriticalPathLen(
350 MachineBasicBlock *MBB, MachineInstr *Root,
352 SmallVectorImpl<MachineInstr *> &InsInstrs,
353 SmallVectorImpl<MachineInstr *> &DelInstrs,
354 DenseMap<Register, unsigned> &InstrIdxForVirtReg, unsigned Pattern,
355 bool SlackIsAccurate) {
356 // Get depth and latency of NewRoot and Root.
357 unsigned NewRootDepth =
358 getDepth(InsInstrs, InstrIdxForVirtReg, BlockTrace, *MBB);
359 unsigned RootDepth = BlockTrace.getInstrCycles(*Root).Depth;
360
361 LLVM_DEBUG(dbgs() << " Dependence data for " << *Root << "\tNewRootDepth: "
362 << NewRootDepth << "\tRootDepth: " << RootDepth);
363
364 // For a transform such as reassociation, the cost equation is
365 // conservatively calculated so that we must improve the depth (data
366 // dependency cycles) in the critical path to proceed with the transform.
367 // Being conservative also protects against inaccuracies in the underlying
368 // machine trace metrics and CPU models.
369 if (getCombinerObjective(Pattern) == CombinerObjective::MustReduceDepth) {
370 LLVM_DEBUG(dbgs() << "\tIt MustReduceDepth ");
371 LLVM_DEBUG(NewRootDepth < RootDepth
372 ? dbgs() << "\t and it does it\n"
373 : dbgs() << "\t but it does NOT do it\n");
374 return NewRootDepth < RootDepth;
375 }
376
377 // A more flexible cost calculation for the critical path includes the slack
378 // of the original code sequence. This may allow the transform to proceed
379 // even if the instruction depths (data dependency cycles) become worse.
380
381 // Account for the latency of the inserted and deleted instructions by
382 unsigned NewRootLatency, RootLatency;
383 if (TII->accumulateInstrSeqToRootLatency(*Root)) {
384 std::tie(NewRootLatency, RootLatency) =
385 getLatenciesForInstrSequences(*Root, InsInstrs, DelInstrs, BlockTrace);
386 } else {
387 NewRootLatency = TSchedModel.computeInstrLatency(InsInstrs.back());
388 RootLatency = TSchedModel.computeInstrLatency(Root);
389 }
390
391 unsigned RootSlack = BlockTrace.getInstrSlack(*Root);
392 unsigned NewCycleCount = NewRootDepth + NewRootLatency;
393 unsigned OldCycleCount =
394 RootDepth + RootLatency + (SlackIsAccurate ? RootSlack : 0);
395 LLVM_DEBUG(dbgs() << "\n\tNewRootLatency: " << NewRootLatency
396 << "\tRootLatency: " << RootLatency << "\n\tRootSlack: "
397 << RootSlack << " SlackIsAccurate=" << SlackIsAccurate
398 << "\n\tNewRootDepth + NewRootLatency = " << NewCycleCount
399 << "\n\tRootDepth + RootLatency + RootSlack = "
400 << OldCycleCount);
401 LLVM_DEBUG(NewCycleCount <= OldCycleCount
402 ? dbgs() << "\n\t It IMPROVES PathLen because"
403 : dbgs() << "\n\t It DOES NOT improve PathLen because");
404 LLVM_DEBUG(dbgs() << "\n\t\tNewCycleCount = " << NewCycleCount
405 << ", OldCycleCount = " << OldCycleCount << "\n");
406
407 return NewCycleCount <= OldCycleCount;
408}
409
410/// helper routine to convert instructions into SC
411void MachineCombiner::instr2instrSC(
412 SmallVectorImpl<MachineInstr *> &Instrs,
413 SmallVectorImpl<const MCSchedClassDesc *> &InstrsSC) {
414 for (auto *InstrPtr : Instrs) {
415 unsigned Opc = InstrPtr->getOpcode();
416 unsigned Idx = TII->get(Opc).getSchedClass();
417 const MCSchedClassDesc *SC = SchedModel.getSchedClassDesc(Idx);
418 InstrsSC.push_back(SC);
419 }
420}
421
422/// True when the new instructions do not increase resource length
423bool MachineCombiner::preservesResourceLen(
424 MachineBasicBlock *MBB, MachineTraceMetrics::Trace BlockTrace,
425 SmallVectorImpl<MachineInstr *> &InsInstrs,
426 SmallVectorImpl<MachineInstr *> &DelInstrs) {
427 if (!TSchedModel.hasInstrSchedModel())
428 return true;
429
430 // Compute current resource length
431
432 //ArrayRef<const MachineBasicBlock *> MBBarr(MBB);
434 MBBarr.push_back(MBB);
435 unsigned ResLenBeforeCombine = BlockTrace.getResourceLength(MBBarr);
436
437 // Deal with SC rather than Instructions.
440
441 instr2instrSC(InsInstrs, InsInstrsSC);
442 instr2instrSC(DelInstrs, DelInstrsSC);
443
444 ArrayRef<const MCSchedClassDesc *> MSCInsArr{InsInstrsSC};
445 ArrayRef<const MCSchedClassDesc *> MSCDelArr{DelInstrsSC};
446
447 // Compute new resource length.
448 unsigned ResLenAfterCombine =
449 BlockTrace.getResourceLength(MBBarr, MSCInsArr, MSCDelArr);
450
451 LLVM_DEBUG(dbgs() << "\t\tResource length before replacement: "
452 << ResLenBeforeCombine
453 << " and after: " << ResLenAfterCombine << "\n");
455 ResLenAfterCombine <=
456 ResLenBeforeCombine + TII->getExtendResourceLenLimit()
457 ? dbgs() << "\t\t As result it IMPROVES/PRESERVES Resource Length\n"
458 : dbgs() << "\t\t As result it DOES NOT improve/preserve Resource "
459 "Length\n");
460
461 return ResLenAfterCombine <=
462 ResLenBeforeCombine + TII->getExtendResourceLenLimit();
463}
464
465/// Inserts InsInstrs and deletes DelInstrs. Incrementally updates instruction
466/// depths if requested.
467///
468/// \param MBB basic block to insert instructions in
469/// \param MI current machine instruction
470/// \param InsInstrs new instructions to insert in \p MBB
471/// \param DelInstrs instruction to delete from \p MBB
472/// \param TraceEnsemble is a pointer to the machine trace information
473/// \param RegUnits set of live registers, needed to compute instruction depths
474/// \param TII is target instruction info, used to call target hook
475/// \param Pattern is used to call target hook finalizeInsInstrs
476/// \param IncrementalUpdate if true, compute instruction depths incrementally,
477/// otherwise invalidate the trace
478static void
482 MachineTraceMetrics::Ensemble *TraceEnsemble,
483 LiveRegUnitSet &RegUnits, const TargetInstrInfo *TII,
484 unsigned Pattern, bool IncrementalUpdate) {
485 // If we want to fix up some placeholder for some target, do it now.
486 // We need this because in genAlternativeCodeSequence, we have not decided the
487 // better pattern InsInstrs or DelInstrs, so we don't want generate some
488 // sideeffect to the function. For example we need to delay the constant pool
489 // entry creation here after InsInstrs is selected as better pattern.
490 // Otherwise the constant pool entry created for InsInstrs will not be deleted
491 // even if InsInstrs is not the better pattern.
492 TII->finalizeInsInstrs(MI, Pattern, InsInstrs);
493
494 for (auto *InstrPtr : InsInstrs)
495 MBB->insert((MachineBasicBlock::iterator)&MI, InstrPtr);
496
497 for (auto *InstrPtr : DelInstrs) {
498 InstrPtr->eraseFromParent();
499 // Erase all LiveRegs defined by the removed instruction
500 for (auto *I = RegUnits.begin(); I != RegUnits.end();) {
501 if (I->MI == InstrPtr)
502 I = RegUnits.erase(I);
503 else
504 I++;
505 }
506 }
507
508 if (IncrementalUpdate)
509 for (auto *InstrPtr : InsInstrs)
510 TraceEnsemble->updateDepth(MBB, *InstrPtr, RegUnits);
511 else
512 TraceEnsemble->invalidate(MBB);
513
514 NumInstCombined++;
515}
516
517/// Substitute a slow code sequence with a faster one by
518/// evaluating instruction combining pattern.
519/// The prototype of such a pattern is MUl + ADD -> MADD. Performs instruction
520/// combining based on machine trace metrics. Only combine a sequence of
521/// instructions when this neither lengthens the critical path nor increases
522/// resource pressure. When optimizing for codesize always combine when the new
523/// sequence is shorter.
524bool MachineCombiner::combineInstructions(MachineBasicBlock *MBB) {
525 bool Changed = false;
526 LLVM_DEBUG(dbgs() << "Combining MBB " << MBB->getName() << "\n");
527
528 bool IncrementalUpdate = false;
529 auto BlockIter = MBB->begin();
530 decltype(BlockIter) LastUpdate;
531 // Check if the block is in a loop.
532 const MachineLoop *ML = MLI->getLoopFor(MBB);
533 if (!TraceEnsemble)
534 TraceEnsemble = Traces->getEnsemble(TII->getMachineCombinerTraceStrategy());
535
536 LiveRegUnitSet RegUnits;
537 RegUnits.setUniverse(TRI->getNumRegUnits());
538
539 bool OptForSize = llvm::shouldOptimizeForSize(MBB, PSI, MBFI);
540
541 bool DoRegPressureReduce =
542 TII->shouldReduceRegisterPressure(MBB, RegClassInfo);
543
544 while (BlockIter != MBB->end()) {
545 auto &MI = *BlockIter++;
546 SmallVector<unsigned, 16> Patterns;
547 // The motivating example is:
548 //
549 // MUL Other MUL_op1 MUL_op2 Other
550 // \ / \ | /
551 // ADD/SUB => MADD/MSUB
552 // (=Root) (=NewRoot)
553
554 // The DAGCombine code always replaced MUL + ADD/SUB by MADD. While this is
555 // usually beneficial for code size it unfortunately can hurt performance
556 // when the ADD is on the critical path, but the MUL is not. With the
557 // substitution the MUL becomes part of the critical path (in form of the
558 // MADD) and can lengthen it on architectures where the MADD latency is
559 // longer than the ADD latency.
560 //
561 // For each instruction we check if it can be the root of a combiner
562 // pattern. Then for each pattern the new code sequence in form of MI is
563 // generated and evaluated. When the efficiency criteria (don't lengthen
564 // critical path, don't use more resources) is met the new sequence gets
565 // hooked up into the basic block before the old sequence is removed.
566 //
567 // The algorithm does not try to evaluate all patterns and pick the best.
568 // This is only an artificial restriction though. In practice there is
569 // mostly one pattern, and getMachineCombinerPatterns() can order patterns
570 // based on an internal cost heuristic. If
571 // machine-combiner-verify-pattern-order is enabled, all patterns are
572 // checked to ensure later patterns do not provide better latency savings.
573
574 if (!TII->getMachineCombinerPatterns(MI, Patterns, DoRegPressureReduce))
575 continue;
576
577 // Only used when VerifyPatternOrder is enabled.
578 [[maybe_unused]] long PrevLatencyDiff = std::numeric_limits<long>::max();
579
580 for (const auto P : Patterns) {
583 DenseMap<Register, unsigned> InstrIdxForVirtReg;
584 TII->genAlternativeCodeSequence(MI, P, InsInstrs, DelInstrs,
585 InstrIdxForVirtReg);
586 // Found pattern, but did not generate alternative sequence.
587 // This can happen e.g. when an immediate could not be materialized
588 // in a single instruction.
589 if (InsInstrs.empty())
590 continue;
591
593 dbgs() << "\tFor the Pattern (" << (int)P
594 << ") these instructions could be removed\n";
595 for (auto const *InstrPtr : DelInstrs)
596 InstrPtr->print(dbgs(), /*IsStandalone*/false, /*SkipOpers*/false,
597 /*SkipDebugLoc*/false, /*AddNewLine*/true, TII);
598 dbgs() << "\tThese instructions could replace the removed ones\n";
599 for (auto const *InstrPtr : InsInstrs)
600 InstrPtr->print(dbgs(), /*IsStandalone*/false, /*SkipOpers*/false,
601 /*SkipDebugLoc*/false, /*AddNewLine*/true, TII);
602 });
603
604 // Check that the difference between original and new latency is
605 // decreasing for later patterns. This helps to discover sub-optimal
606 // pattern orderings.
608 auto [NewRootLatency, RootLatency] = getLatenciesForInstrSequences(
609 MI, InsInstrs, DelInstrs, TraceEnsemble->getTrace(MBB));
610 long CurrentLatencyDiff = ((long)RootLatency) - ((long)NewRootLatency);
611 assert(CurrentLatencyDiff <= PrevLatencyDiff &&
612 "Current pattern is expected to be better than the previous "
613 "pattern.");
614 PrevLatencyDiff = CurrentLatencyDiff;
615 }
616
617 if (IncrementalUpdate && LastUpdate != BlockIter) {
618 // Update depths since the last incremental update.
619 TraceEnsemble->updateDepths(LastUpdate, BlockIter, RegUnits);
620 LastUpdate = BlockIter;
621 }
622
623 if (DoRegPressureReduce &&
624 getCombinerObjective(P) ==
625 CombinerObjective::MustReduceRegisterPressure) {
626 if (MBB->size() > inc_threshold) {
627 // Use incremental depth updates for basic blocks above threshold
628 IncrementalUpdate = true;
629 LastUpdate = BlockIter;
630 }
631 if (reduceRegisterPressure(MI, MBB, InsInstrs, DelInstrs, P)) {
632 // Replace DelInstrs with InsInstrs.
633 insertDeleteInstructions(MBB, MI, InsInstrs, DelInstrs, TraceEnsemble,
634 RegUnits, TII, P, IncrementalUpdate);
635 Changed |= true;
636
637 // Go back to previous instruction as it may have ILP reassociation
638 // opportunity.
639 BlockIter--;
640 break;
641 }
642 }
643
644 if (ML && TII->isThroughputPattern(P)) {
645 LLVM_DEBUG(dbgs() << "\t Replacing due to throughput pattern in loop\n");
646 insertDeleteInstructions(MBB, MI, InsInstrs, DelInstrs, TraceEnsemble,
647 RegUnits, TII, P, IncrementalUpdate);
648 // Eagerly stop after the first pattern fires.
649 Changed = true;
650 break;
651 } else if (OptForSize && InsInstrs.size() < DelInstrs.size()) {
652 LLVM_DEBUG(dbgs() << "\t Replacing due to OptForSize ("
653 << InsInstrs.size() << " < "
654 << DelInstrs.size() << ")\n");
655 insertDeleteInstructions(MBB, MI, InsInstrs, DelInstrs, TraceEnsemble,
656 RegUnits, TII, P, IncrementalUpdate);
657 // Eagerly stop after the first pattern fires.
658 Changed = true;
659 break;
660 } else {
661 // For big basic blocks, we only compute the full trace the first time
662 // we hit this. We do not invalidate the trace, but instead update the
663 // instruction depths incrementally.
664 // NOTE: Only the instruction depths up to MI are accurate. All other
665 // trace information is not updated.
666 MachineTraceMetrics::Trace BlockTrace = TraceEnsemble->getTrace(MBB);
667 Traces->verifyAnalysis();
668 if (improvesCriticalPathLen(MBB, &MI, BlockTrace, InsInstrs, DelInstrs,
669 InstrIdxForVirtReg, P,
670 !IncrementalUpdate) &&
671 preservesResourceLen(MBB, BlockTrace, InsInstrs, DelInstrs)) {
672 if (MBB->size() > inc_threshold) {
673 // Use incremental depth updates for basic blocks above treshold
674 IncrementalUpdate = true;
675 LastUpdate = BlockIter;
676 }
677
678 insertDeleteInstructions(MBB, MI, InsInstrs, DelInstrs, TraceEnsemble,
679 RegUnits, TII, P, IncrementalUpdate);
680
681 // Eagerly stop after the first pattern fires.
682 Changed = true;
683 break;
684 }
685 // Cleanup instructions of the alternative code sequence. There is no
686 // use for them.
687 MachineFunction *MF = MBB->getParent();
688 for (auto *InstrPtr : InsInstrs)
689 MF->deleteMachineInstr(InstrPtr);
690 }
691 InstrIdxForVirtReg.clear();
692 }
693 }
694
695 if (Changed && IncrementalUpdate)
696 Traces->invalidate(MBB);
697 return Changed;
698}
699
700bool MachineCombiner::runOnMachineFunction(MachineFunction &MF) {
701 STI = &MF.getSubtarget();
702 TII = STI->getInstrInfo();
703 TRI = STI->getRegisterInfo();
704 SchedModel = STI->getSchedModel();
705 TSchedModel.init(STI);
706 MRI = &MF.getRegInfo();
707 MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
708 Traces = &getAnalysis<MachineTraceMetricsWrapperPass>().getMTM();
709 PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
710 MBFI = (PSI && PSI->hasProfileSummary()) ?
711 &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI() :
712 nullptr;
713 TraceEnsemble = nullptr;
714 RegClassInfo = &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
715
716 LLVM_DEBUG(dbgs() << getPassName() << ": " << MF.getName() << '\n');
717 if (!TII->useMachineCombiner()) {
719 dbgs()
720 << " Skipping pass: Target does not support machine combiner\n");
721 return false;
722 }
723
724 bool Changed = false;
725
726 // Try to combine instructions.
727 for (auto &MBB : MF)
728 Changed |= combineInstructions(&MBB);
729
730 return Changed;
731}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
This file defines the DenseMap class.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
===- LazyMachineBlockFrequencyInfo.h - Lazy Block Frequency -*- C++ -*–===//
#define I(x, y, z)
Definition MD5.cpp:57
static void insertDeleteInstructions(MachineBasicBlock *MBB, MachineInstr &MI, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, MachineTraceMetrics::Ensemble *TraceEnsemble, LiveRegUnitSet &RegUnits, const TargetInstrInfo *TII, unsigned Pattern, bool IncrementalUpdate)
Inserts InsInstrs and deletes DelInstrs.
static cl::opt< bool > VerifyPatternOrder("machine-combiner-verify-pattern-order", cl::Hidden, cl::desc("Verify that the generated patterns are ordered by increasing latency"), cl::init(false))
static cl::opt< unsigned > inc_threshold("machine-combiner-inc-threshold", cl::Hidden, cl::desc("Incremental depth computation will be used for basic " "blocks with more instructions."), cl::init(500))
static cl::opt< bool > dump_intrs("machine-combiner-dump-subst-intrs", cl::Hidden, cl::desc("Dump all substituted intrs"), cl::init(false))
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
uint64_t IntrinsicInst * II
#define P(N)
#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
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
Represent the analysis usage information of a pass.
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
iterator end()
Definition DenseMap.h:141
bool useMachineCombiner() const override
This is an alternative analysis pass to MachineBlockFrequencyInfo.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
bool hasSuperClassEq(const MCRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
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.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
filtered_mop_range all_defs()
Returns an iterator range over all operands that are (explicit or implicit) register defs.
LLVM_ABI int findRegisterUseOperandIdx(Register Reg, const TargetRegisterInfo *TRI, bool isKill=false) const
Returns the operand index that is a use of the specific register or -1 if it is not found.
LLVM_ABI int findRegisterDefOperandIdx(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false) const
Returns the operand index that is a def of the specified register or -1 if it is not found.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static reg_iterator reg_end()
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
reg_iterator reg_begin(Register RegNo) const
defusechain_iterator< true, true, false, true, false > reg_iterator
reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified register.
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
A trace ensemble is a collection of traces selected using the same strategy, for example 'minimum res...
void invalidate(const MachineBasicBlock *MBB)
Invalidate traces through BadMBB.
void updateDepth(TraceBlockInfo &TBI, const MachineInstr &, LiveRegUnitSet &RegUnits)
Updates the depth of an machine instruction, given RegUnits.
void updateDepths(MachineBasicBlock::iterator Start, MachineBasicBlock::iterator End, LiveRegUnitSet &RegUnits)
Updates the depth of the instructions from Start to End.
Trace getTrace(const MachineBasicBlock *MBB)
Get the trace that passes through MBB.
LLVM_ABI unsigned getResourceLength(ArrayRef< const MachineBasicBlock * > Extrablocks={}, ArrayRef< const MCSchedClassDesc * > ExtraInstrs={}, ArrayRef< const MCSchedClassDesc * > RemoveInstrs={}) const
Return the resource length of the trace.
InstrCycles getInstrCycles(const MachineInstr &MI) const
Return the depth and height of MI.
LLVM_ABI unsigned getInstrSlack(const MachineInstr &MI) const
Return the slack of MI.
LLVM_ABI bool isDepInTrace(const MachineInstr &DefMI, const MachineInstr &UseMI) const
A dependence is useful if the basic block of the defining instruction is part of the trace of the use...
LLVM_ABI Ensemble * getEnsemble(MachineTraceStrategy)
Get the trace ensemble representing the given trace selection strategy.
LLVM_ABI void verifyAnalysis() const
LLVM_ABI void invalidate(const MachineBasicBlock *MBB)
Invalidate cached information about MBB.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
bool hasProfileSummary() const
Returns true if profile summary is available.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
iterator erase(iterator I)
erase - Erases an existing element identified by a valid iterator.
Definition SparseSet.h:287
const_iterator begin() const
Definition SparseSet.h:170
const_iterator end() const
Definition SparseSet.h:171
void setUniverse(unsigned U)
setUniverse - Set the universe size which determines the largest key the set can hold.
Definition SparseSet.h:152
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Provide an instruction scheduling machine model to CodeGen passes.
LLVM_ABI bool hasInstrSchedModel() const
Return true if this machine model includes an instruction-level scheduling model.
LLVM_ABI void init(const TargetSubtargetInfo *TSInfo, bool EnableSModel=true, bool EnableSItins=true)
Initialize the machine model for instruction scheduling.
LLVM_ABI unsigned computeOperandLatency(const MachineInstr *DefMI, unsigned DefOperIdx, const MachineInstr *UseMI, unsigned UseOperIdx) const
Compute operand latency based on the available machine model.
bool hasInstrSchedModelOrItineraries() const
Return true if this machine model includes an instruction-level scheduling model or cycle-to-cycle it...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Changed
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
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.
LLVM_ABI char & MachineCombinerID
This pass performs instruction combining using trace metrics to estimate critical-path and resource d...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
SparseSet< LiveRegUnit, MCRegUnit, MCRegUnitToIndex > LiveRegUnitSet
ArrayRef(const T &OneElt) -> ArrayRef< T >
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
Machine model for scheduling, bundling, and heuristics.
Definition MCSchedule.h:273
const MCSchedClassDesc * getSchedClassDesc(unsigned SchedClassIdx) const
Definition MCSchedule.h:381
unsigned Depth
Earliest issue cycle as determined by data dependencies and instruction latencies from the beginning ...