LLVM 20.0.0git
RegBankSelect.h
Go to the documentation of this file.
1//=- llvm/CodeGen/GlobalISel/RegBankSelect.h - Reg Bank Selector --*- C++ -*-=//
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/// \file
10/// This file describes the interface of the MachineFunctionPass
11/// responsible for assigning the generic virtual registers to register bank.
12///
13/// By default, the reg bank selector relies on local decisions to
14/// assign the register bank. In other words, it looks at one instruction
15/// at a time to decide where the operand of that instruction should live.
16///
17/// At higher optimization level, we could imagine that the reg bank selector
18/// would use more global analysis and do crazier thing like duplicating
19/// instructions and so on. This is future work.
20///
21/// For now, the pass uses a greedy algorithm to decide where the operand
22/// of an instruction should live. It asks the target which banks may be
23/// used for each operand of the instruction and what is the cost. Then,
24/// it chooses the solution which minimize the cost of the instruction plus
25/// the cost of any move that may be needed to the values into the right
26/// register bank.
27/// In other words, the cost for an instruction on a register bank RegBank
28/// is: Cost of I on RegBank plus the sum of the cost for bringing the
29/// input operands from their current register bank to RegBank.
30/// Thus, the following formula:
31/// cost(I, RegBank) = cost(I.Opcode, RegBank) +
32/// sum(for each arg in I.arguments: costCrossCopy(arg.RegBank, RegBank))
33///
34/// E.g., Let say we are assigning the register bank for the instruction
35/// defining v2.
36/// v0(A_REGBANK) = ...
37/// v1(A_REGBANK) = ...
38/// v2 = G_ADD i32 v0, v1 <-- MI
39///
40/// The target may say it can generate G_ADD i32 on register bank A and B
41/// with a cost of respectively 5 and 1.
42/// Then, let say the cost of a cross register bank copies from A to B is 1.
43/// The reg bank selector would compare the following two costs:
44/// cost(MI, A_REGBANK) = cost(G_ADD, A_REGBANK) + cost(v0.RegBank, A_REGBANK) +
45/// cost(v1.RegBank, A_REGBANK)
46/// = 5 + cost(A_REGBANK, A_REGBANK) + cost(A_REGBANK,
47/// A_REGBANK)
48/// = 5 + 0 + 0 = 5
49/// cost(MI, B_REGBANK) = cost(G_ADD, B_REGBANK) + cost(v0.RegBank, B_REGBANK) +
50/// cost(v1.RegBank, B_REGBANK)
51/// = 1 + cost(A_REGBANK, B_REGBANK) + cost(A_REGBANK,
52/// B_REGBANK)
53/// = 1 + 1 + 1 = 3
54/// Therefore, in this specific example, the reg bank selector would choose
55/// bank B for MI.
56/// v0(A_REGBANK) = ...
57/// v1(A_REGBANK) = ...
58/// tmp0(B_REGBANK) = COPY v0
59/// tmp1(B_REGBANK) = COPY v1
60/// v2(B_REGBANK) = G_ADD i32 tmp0, tmp1
61//
62//===----------------------------------------------------------------------===//
63
64#ifndef LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H
65#define LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H
66
73#include <cassert>
74#include <cstdint>
75#include <memory>
76
77namespace llvm {
78
79class BlockFrequency;
80class MachineBlockFrequencyInfo;
81class MachineBranchProbabilityInfo;
82class MachineOperand;
83class MachineRegisterInfo;
84class Pass;
85class raw_ostream;
86class TargetPassConfig;
87class TargetRegisterInfo;
88
89/// This pass implements the reg bank selector pass used in the GlobalISel
90/// pipeline. At the end of this pass, all register operands have been assigned
92public:
93 static char ID;
94
95 /// List of the modes supported by the RegBankSelect pass.
96 enum Mode {
97 /// Assign the register banks as fast as possible (default).
99 /// Greedily minimize the cost of assigning register banks.
100 /// This should produce code of greater quality, but will
101 /// require more compile time.
102 Greedy
103 };
104
105 /// Abstract class used to represent an insertion point in a CFG.
106 /// This class records an insertion point and materializes it on
107 /// demand.
108 /// It allows to reason about the frequency of this insertion point,
109 /// without having to logically materialize it (e.g., on an edge),
110 /// before we actually need to insert something.
112 protected:
113 /// Tell if the insert point has already been materialized.
114 bool WasMaterialized = false;
115
116 /// Materialize the insertion point.
117 ///
118 /// If isSplit() is true, this involves actually splitting
119 /// the block or edge.
120 ///
121 /// \post getPointImpl() returns a valid iterator.
122 /// \post getInsertMBBImpl() returns a valid basic block.
123 /// \post isSplit() == false ; no more splitting should be required.
124 virtual void materialize() = 0;
125
126 /// Return the materialized insertion basic block.
127 /// Code will be inserted into that basic block.
128 ///
129 /// \pre ::materialize has been called.
131
132 /// Return the materialized insertion point.
133 /// Code will be inserted before that point.
134 ///
135 /// \pre ::materialize has been called.
137
138 public:
139 virtual ~InsertPoint() = default;
140
141 /// The first call to this method will cause the splitting to
142 /// happen if need be, then sub sequent calls just return
143 /// the iterator to that point. I.e., no more splitting will
144 /// occur.
145 ///
146 /// \return The iterator that should be used with
147 /// MachineBasicBlock::insert. I.e., additional code happens
148 /// before that point.
150 if (!WasMaterialized) {
151 WasMaterialized = true;
152 assert(canMaterialize() && "Impossible to materialize this point");
153 materialize();
154 }
155 // When we materialized the point we should have done the splitting.
156 assert(!isSplit() && "Wrong pre-condition");
157 return getPointImpl();
158 }
159
160 /// The first call to this method will cause the splitting to
161 /// happen if need be, then sub sequent calls just return
162 /// the basic block that contains the insertion point.
163 /// I.e., no more splitting will occur.
164 ///
165 /// \return The basic block should be used with
166 /// MachineBasicBlock::insert and ::getPoint. The new code should
167 /// happen before that point.
169 if (!WasMaterialized) {
170 WasMaterialized = true;
171 assert(canMaterialize() && "Impossible to materialize this point");
172 materialize();
173 }
174 // When we materialized the point we should have done the splitting.
175 assert(!isSplit() && "Wrong pre-condition");
176 return getInsertMBBImpl();
177 }
178
179 /// Insert \p MI in the just before ::getPoint()
181 return getInsertMBB().insert(getPoint(), &MI);
182 }
183
184 /// Does this point involve splitting an edge or block?
185 /// As soon as ::getPoint is called and thus, the point
186 /// materialized, the point will not require splitting anymore,
187 /// i.e., this will return false.
188 virtual bool isSplit() const { return false; }
189
190 /// Frequency of the insertion point.
191 /// \p P is used to access the various analysis that will help to
192 /// get that information, like MachineBlockFrequencyInfo. If \p P
193 /// does not contain enough to return the actual frequency,
194 /// this returns 1.
195 virtual uint64_t frequency(const Pass &P) const { return 1; }
196
197 /// Check whether this insertion point can be materialized.
198 /// As soon as ::getPoint is called and thus, the point materialized
199 /// calling this method does not make sense.
200 virtual bool canMaterialize() const { return false; }
201 };
202
203 /// Insertion point before or after an instruction.
205 private:
206 /// Insertion point.
207 MachineInstr &Instr;
208
209 /// Does the insertion point is before or after Instr.
210 bool Before;
211
212 void materialize() override;
213
214 MachineBasicBlock::iterator getPointImpl() override {
215 if (Before)
216 return Instr;
217 return Instr.getNextNode() ? *Instr.getNextNode()
218 : Instr.getParent()->end();
219 }
220
221 MachineBasicBlock &getInsertMBBImpl() override {
222 return *Instr.getParent();
223 }
224
225 public:
226 /// Create an insertion point before (\p Before=true) or after \p Instr.
227 InstrInsertPoint(MachineInstr &Instr, bool Before = true);
228
229 bool isSplit() const override;
230 uint64_t frequency(const Pass &P) const override;
231
232 // Worst case, we need to slice the basic block, but that is still doable.
233 bool canMaterialize() const override { return true; }
234 };
235
236 /// Insertion point at the beginning or end of a basic block.
238 private:
239 /// Insertion point.
241
242 /// Does the insertion point is at the beginning or end of MBB.
243 bool Beginning;
244
245 void materialize() override { /*Nothing to do to materialize*/
246 }
247
248 MachineBasicBlock::iterator getPointImpl() override {
249 return Beginning ? MBB.begin() : MBB.end();
250 }
251
252 MachineBasicBlock &getInsertMBBImpl() override { return MBB; }
253
254 public:
255 MBBInsertPoint(MachineBasicBlock &MBB, bool Beginning = true)
256 : MBB(MBB), Beginning(Beginning) {
257 // If we try to insert before phis, we should use the insertion
258 // points on the incoming edges.
259 assert((!Beginning || MBB.getFirstNonPHI() == MBB.begin()) &&
260 "Invalid beginning point");
261 // If we try to insert after the terminators, we should use the
262 // points on the outcoming edges.
263 assert((Beginning || MBB.getFirstTerminator() == MBB.end()) &&
264 "Invalid end point");
265 }
266
267 bool isSplit() const override { return false; }
268 uint64_t frequency(const Pass &P) const override;
269 bool canMaterialize() const override { return true; };
270 };
271
272 /// Insertion point on an edge.
274 private:
275 /// Source of the edge.
277
278 /// Destination of the edge.
279 /// After the materialization is done, this hold the basic block
280 /// that resulted from the splitting.
281 MachineBasicBlock *DstOrSplit;
282
283 /// P is used to update the analysis passes as applicable.
284 Pass &P;
285
286 void materialize() override;
287
288 MachineBasicBlock::iterator getPointImpl() override {
289 // DstOrSplit should be the Split block at this point.
290 // I.e., it should have one predecessor, Src, and one successor,
291 // the original Dst.
292 assert(DstOrSplit && DstOrSplit->isPredecessor(&Src) &&
293 DstOrSplit->pred_size() == 1 && DstOrSplit->succ_size() == 1 &&
294 "Did not split?!");
295 return DstOrSplit->begin();
296 }
297
298 MachineBasicBlock &getInsertMBBImpl() override { return *DstOrSplit; }
299
300 public:
302 : Src(Src), DstOrSplit(&Dst), P(P) {}
303
304 bool isSplit() const override {
305 return Src.succ_size() > 1 && DstOrSplit->pred_size() > 1;
306 }
307
308 uint64_t frequency(const Pass &P) const override;
309 bool canMaterialize() const override;
310 };
311
312 /// Struct used to represent the placement of a repairing point for
313 /// a given operand.
315 public:
316 /// Define the kind of action this repairing needs.
318 /// Nothing to repair, just drop this action.
320 /// Reparing code needs to happen before InsertPoints.
322 /// (Re)assign the register bank of the operand.
324 /// Mark this repairing placement as impossible.
326 };
327
328 /// \name Convenient types for a list of insertion points.
329 /// @{
333 /// @}
334
335 private:
336 /// Kind of repairing.
337 RepairingKind Kind;
338 /// Index of the operand that will be repaired.
339 unsigned OpIdx;
340 /// Are all the insert points materializeable?
341 bool CanMaterialize;
342 /// Is there any of the insert points needing splitting?
343 bool HasSplit = false;
344 /// Insertion point for the repair code.
345 /// The repairing code needs to happen just before these points.
346 InsertionPoints InsertPoints;
347 /// Some insertion points may need to update the liveness and such.
348 Pass &P;
349
350 public:
351 /// Create a repairing placement for the \p OpIdx-th operand of
352 /// \p MI. \p TRI is used to make some checks on the register aliases
353 /// if the machine operand is a physical register. \p P is used to
354 /// to update liveness information and such when materializing the
355 /// points.
356 RepairingPlacement(MachineInstr &MI, unsigned OpIdx,
357 const TargetRegisterInfo &TRI, Pass &P,
359
360 /// \name Getters.
361 /// @{
362 RepairingKind getKind() const { return Kind; }
363 unsigned getOpIdx() const { return OpIdx; }
364 bool canMaterialize() const { return CanMaterialize; }
365 bool hasSplit() { return HasSplit; }
366 /// @}
367
368 /// \name Overloaded methods to add an insertion point.
369 /// @{
370 /// Add a MBBInsertionPoint to the list of InsertPoints.
371 void addInsertPoint(MachineBasicBlock &MBB, bool Beginning);
372 /// Add a InstrInsertionPoint to the list of InsertPoints.
374 /// Add an EdgeInsertionPoint (\p Src, \p Dst) to the list of InsertPoints.
376 /// Add an InsertPoint to the list of insert points.
377 /// This method takes the ownership of &\p Point.
378 void addInsertPoint(InsertPoint &Point);
379 /// @}
380
381 /// \name Accessors related to the insertion points.
382 /// @{
383 insertpt_iterator begin() { return InsertPoints.begin(); }
384 insertpt_iterator end() { return InsertPoints.end(); }
385
386 const_insertpt_iterator begin() const { return InsertPoints.begin(); }
387 const_insertpt_iterator end() const { return InsertPoints.end(); }
388
389 unsigned getNumInsertPoints() const { return InsertPoints.size(); }
390 /// @}
391
392 /// Change the type of this repairing placement to \p NewKind.
393 /// It is not possible to switch a repairing placement to the
394 /// RepairingKind::Insert. There is no fundamental problem with
395 /// that, but no uses as well, so do not support it for now.
396 ///
397 /// \pre NewKind != RepairingKind::Insert
398 /// \post getKind() == NewKind
399 void switchTo(RepairingKind NewKind) {
400 assert(NewKind != Kind && "Already of the right Kind");
401 Kind = NewKind;
402 InsertPoints.clear();
403 CanMaterialize = NewKind != RepairingKind::Impossible;
404 HasSplit = false;
405 assert(NewKind != RepairingKind::Insert &&
406 "We would need more MI to switch to Insert");
407 }
408 };
409
410protected:
411 /// Helper class used to represent the cost for mapping an instruction.
412 /// When mapping an instruction, we may introduce some repairing code.
413 /// In most cases, the repairing code is local to the instruction,
414 /// thus, we can omit the basic block frequency from the cost.
415 /// However, some alternatives may produce non-local cost, e.g., when
416 /// repairing a phi, and thus we then need to scale the local cost
417 /// to the non-local cost. This class does this for us.
418 /// \note: We could simply always scale the cost. The problem is that
419 /// there are higher chances that we saturate the cost easier and end
420 /// up having the same cost for actually different alternatives.
421 /// Another option would be to use APInt everywhere.
423 private:
424 /// Cost of the local instructions.
425 /// This cost is free of basic block frequency.
426 uint64_t LocalCost = 0;
427 /// Cost of the non-local instructions.
428 /// This cost should include the frequency of the related blocks.
429 uint64_t NonLocalCost = 0;
430 /// Frequency of the block where the local instructions live.
431 uint64_t LocalFreq;
432
433 MappingCost(uint64_t LocalCost, uint64_t NonLocalCost, uint64_t LocalFreq)
434 : LocalCost(LocalCost), NonLocalCost(NonLocalCost),
435 LocalFreq(LocalFreq) {}
436
437 /// Check if this cost is saturated.
438 bool isSaturated() const;
439
440 public:
441 /// Create a MappingCost assuming that most of the instructions
442 /// will occur in a basic block with \p LocalFreq frequency.
443 MappingCost(BlockFrequency LocalFreq);
444
445 /// Add \p Cost to the local cost.
446 /// \return true if this cost is saturated, false otherwise.
448
449 /// Add \p Cost to the non-local cost.
450 /// Non-local cost should reflect the frequency of their placement.
451 /// \return true if this cost is saturated, false otherwise.
453
454 /// Saturate the cost to the maximal representable value.
455 void saturate();
456
457 /// Return an instance of MappingCost that represents an
458 /// impossible mapping.
460
461 /// Check if this is less than \p Cost.
462 bool operator<(const MappingCost &Cost) const;
463 /// Check if this is equal to \p Cost.
464 bool operator==(const MappingCost &Cost) const;
465 /// Check if this is not equal to \p Cost.
466 bool operator!=(const MappingCost &Cost) const { return !(*this == Cost); }
467 /// Check if this is greater than \p Cost.
468 bool operator>(const MappingCost &Cost) const {
469 return *this != Cost && Cost < *this;
470 }
471
472 /// Print this on dbgs() stream.
473 void dump() const;
474
475 /// Print this on \p OS;
476 void print(raw_ostream &OS) const;
477
478 /// Overload the stream operator for easy debug printing.
480 Cost.print(OS);
481 return OS;
482 }
483 };
484
485 /// Interface to the target lowering info related
486 /// to register banks.
487 const RegisterBankInfo *RBI = nullptr;
488
489 /// MRI contains all the register class/bank information that this
490 /// pass uses and updates.
492
493 /// Information on the register classes for the current function.
494 const TargetRegisterInfo *TRI = nullptr;
495
496 /// Get the frequency of blocks.
497 /// This is required for non-fast mode.
499
500 /// Get the frequency of the edges.
501 /// This is required for non-fast mode.
503
504 /// Current optimization remark emitter. Used to report failures.
505 std::unique_ptr<MachineOptimizationRemarkEmitter> MORE;
506
507 /// Helper class used for every code morphing.
509
510 /// Optimization mode of the pass.
512
513 /// Current target configuration. Controls how the pass handles errors.
515
516 /// Assign the register bank of each operand of \p MI.
517 /// \return True on success, false otherwise.
519
520 /// Initialize the field members using \p MF.
521 void init(MachineFunction &MF);
522
523 /// Check if \p Reg is already assigned what is described by \p ValMapping.
524 /// \p OnlyAssign == true means that \p Reg just needs to be assigned a
525 /// register bank. I.e., no repairing is necessary to have the
526 /// assignment match.
528 const RegisterBankInfo::ValueMapping &ValMapping,
529 bool &OnlyAssign) const;
530
531 /// Insert repairing code for \p Reg as specified by \p ValMapping.
532 /// The repairing placement is specified by \p RepairPt.
533 /// \p NewVRegs contains all the registers required to remap \p Reg.
534 /// In other words, the number of registers in NewVRegs must be equal
535 /// to ValMapping.BreakDown.size().
536 ///
537 /// The transformation could be sketched as:
538 /// \code
539 /// ... = op Reg
540 /// \endcode
541 /// Becomes
542 /// \code
543 /// <NewRegs> = COPY or extract Reg
544 /// ... = op Reg
545 /// \endcode
546 ///
547 /// and
548 /// \code
549 /// Reg = op ...
550 /// \endcode
551 /// Becomes
552 /// \code
553 /// Reg = op ...
554 /// Reg = COPY or build_sequence <NewRegs>
555 /// \endcode
556 ///
557 /// \pre NewVRegs.size() == ValMapping.BreakDown.size()
558 ///
559 /// \note The caller is supposed to do the rewriting of op if need be.
560 /// I.e., Reg = op ... => <NewRegs> = NewOp ...
561 ///
562 /// \return True if the repairing worked, false otherwise.
563 bool repairReg(MachineOperand &MO,
564 const RegisterBankInfo::ValueMapping &ValMapping,
567 &NewVRegs);
568
569 /// Return the cost of the instruction needed to map \p MO to \p ValMapping.
570 /// The cost is free of basic block frequencies.
571 /// \pre MO.isReg()
572 /// \pre MO is assigned to a register bank.
573 /// \pre ValMapping is a valid mapping for MO.
576 const RegisterBankInfo::ValueMapping &ValMapping) const;
577
578 /// Find the best mapping for \p MI from \p PossibleMappings.
579 /// \return a reference on the best mapping in \p PossibleMappings.
584
585 /// Compute the cost of mapping \p MI with \p InstrMapping and
586 /// compute the repairing placement for such mapping in \p
587 /// RepairPts.
588 /// \p BestCost is used to specify when the cost becomes too high
589 /// and thus it is not worth computing the RepairPts. Moreover if
590 /// \p BestCost == nullptr, the mapping cost is actually not
591 /// computed.
594 const RegisterBankInfo::InstructionMapping &InstrMapping,
596 const MappingCost *BestCost = nullptr);
597
598 /// When \p RepairPt involves splitting to repair \p MO for the
599 /// given \p ValMapping, try to change the way we repair such that
600 /// the splitting is not required anymore.
601 ///
602 /// \pre \p RepairPt.hasSplit()
603 /// \pre \p MO == MO.getParent()->getOperand(\p RepairPt.getOpIdx())
604 /// \pre \p ValMapping is the mapping of \p MO for MO.getParent()
605 /// that implied \p RepairPt.
607 const MachineOperand &MO,
608 const RegisterBankInfo::ValueMapping &ValMapping) const;
609
610 /// Apply \p Mapping to \p MI. \p RepairPts represents the different
611 /// mapping action that need to happen for the mapping to be
612 /// applied.
613 /// \return True if the mapping was applied sucessfully, false otherwise.
615 const RegisterBankInfo::InstructionMapping &InstrMapping,
617
618public:
619 /// Create a RegBankSelect pass with the specified \p RunningMode.
620 RegBankSelect(char &PassID = ID, Mode RunningMode = Fast);
621
622 StringRef getPassName() const override { return "RegBankSelect"; }
623
624 void getAnalysisUsage(AnalysisUsage &AU) const override;
625
630 }
631
635 }
636
640 }
641
642 /// Check that our input is fully legal: we require the function to have the
643 /// Legalized property, so it should be.
644 ///
645 /// FIXME: This should be in the MachineVerifier.
647
648 /// Walk through \p MF and assign a register bank to every virtual register
649 /// that are still mapped to nothing.
650 /// The target needs to provide a RegisterBankInfo and in particular
651 /// override RegisterBankInfo::getInstrMapping.
652 ///
653 /// Simplified algo:
654 /// \code
655 /// RBI = MF.subtarget.getRegBankInfo()
656 /// MIRBuilder.setMF(MF)
657 /// for each bb in MF
658 /// for each inst in bb
659 /// MIRBuilder.setInstr(inst)
660 /// MappingCosts = RBI.getMapping(inst);
661 /// Idx = findIdxOfMinCost(MappingCosts)
662 /// CurRegBank = MappingCosts[Idx].RegBank
663 /// MRI.setRegBank(inst.getOperand(0).getReg(), CurRegBank)
664 /// for each argument in inst
665 /// if (CurRegBank != argument.RegBank)
666 /// ArgReg = argument.getReg()
667 /// Tmp = MRI.createNewVirtual(MRI.getSize(ArgReg), CurRegBank)
668 /// MIRBuilder.buildInstr(COPY, Tmp, ArgReg)
669 /// inst.getOperand(argument.getOperandNo()).setReg(Tmp)
670 /// \endcode
672
673 bool runOnMachineFunction(MachineFunction &MF) override;
674};
675
676} // end namespace llvm
677
678#endif // LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H
aarch64 AArch64 CCMP Pass
MachineBasicBlock & MBB
IRTranslator LLVM IR MI
This file declares the MachineIRBuilder class.
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
unsigned Reg
#define P(N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
void print(raw_ostream &OS) const
unsigned pred_size() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
unsigned succ_size() const
bool isPredecessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a predecessor of this block.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
Helper class to build MachineInstr.
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:94
Insertion point on an edge.
uint64_t frequency(const Pass &P) const override
Frequency of the insertion point.
EdgeInsertPoint(MachineBasicBlock &Src, MachineBasicBlock &Dst, Pass &P)
bool isSplit() const override
Does this point involve splitting an edge or block? As soon as getPoint is called and thus,...
bool canMaterialize() const override
Check whether this insertion point can be materialized.
Abstract class used to represent an insertion point in a CFG.
virtual uint64_t frequency(const Pass &P) const
Frequency of the insertion point.
MachineBasicBlock & getInsertMBB()
The first call to this method will cause the splitting to happen if need be, then sub sequent calls j...
virtual MachineBasicBlock & getInsertMBBImpl()=0
Return the materialized insertion basic block.
MachineBasicBlock::iterator getPoint()
The first call to this method will cause the splitting to happen if need be, then sub sequent calls j...
bool WasMaterialized
Tell if the insert point has already been materialized.
MachineBasicBlock::iterator insert(MachineInstr &MI)
Insert MI in the just before getPoint()
virtual void materialize()=0
Materialize the insertion point.
virtual bool canMaterialize() const
Check whether this insertion point can be materialized.
virtual bool isSplit() const
Does this point involve splitting an edge or block? As soon as getPoint is called and thus,...
virtual MachineBasicBlock::iterator getPointImpl()=0
Return the materialized insertion point.
Insertion point before or after an instruction.
bool canMaterialize() const override
Check whether this insertion point can be materialized.
bool isSplit() const override
Does this point involve splitting an edge or block? As soon as getPoint is called and thus,...
uint64_t frequency(const Pass &P) const override
Frequency of the insertion point.
Insertion point at the beginning or end of a basic block.
bool canMaterialize() const override
Check whether this insertion point can be materialized.
MBBInsertPoint(MachineBasicBlock &MBB, bool Beginning=true)
bool isSplit() const override
Does this point involve splitting an edge or block? As soon as getPoint is called and thus,...
uint64_t frequency(const Pass &P) const override
Frequency of the insertion point.
Helper class used to represent the cost for mapping an instruction.
bool operator!=(const MappingCost &Cost) const
Check if this is not equal to Cost.
void saturate()
Saturate the cost to the maximal representable value.
bool operator==(const MappingCost &Cost) const
Check if this is equal to Cost.
bool addLocalCost(uint64_t Cost)
Add Cost to the local cost.
void dump() const
Print this on dbgs() stream.
static MappingCost ImpossibleCost()
Return an instance of MappingCost that represents an impossible mapping.
bool addNonLocalCost(uint64_t Cost)
Add Cost to the non-local cost.
bool operator<(const MappingCost &Cost) const
Check if this is less than Cost.
friend raw_ostream & operator<<(raw_ostream &OS, const MappingCost &Cost)
Overload the stream operator for easy debug printing.
void print(raw_ostream &OS) const
Print this on OS;.
bool operator>(const MappingCost &Cost) const
Check if this is greater than Cost.
Struct used to represent the placement of a repairing point for a given operand.
RepairingKind
Define the kind of action this repairing needs.
@ Insert
Reparing code needs to happen before InsertPoints.
@ None
Nothing to repair, just drop this action.
@ Reassign
(Re)assign the register bank of the operand.
@ Impossible
Mark this repairing placement as impossible.
const_insertpt_iterator begin() const
const_insertpt_iterator end() const
void switchTo(RepairingKind NewKind)
Change the type of this repairing placement to NewKind.
void addInsertPoint(MachineBasicBlock &MBB, bool Beginning)
This pass implements the reg bank selector pass used in the GlobalISel pipeline.
Definition: RegBankSelect.h:91
Mode
List of the modes supported by the RegBankSelect pass.
Definition: RegBankSelect.h:96
@ Fast
Assign the register banks as fast as possible (default).
Definition: RegBankSelect.h:98
@ Greedy
Greedily minimize the cost of assigning register banks.
bool checkFunctionIsLegal(MachineFunction &MF) const
Check that our input is fully legal: we require the function to have the Legalized property,...
MachineIRBuilder MIRBuilder
Helper class used for every code morphing.
MachineBlockFrequencyInfo * MBFI
Get the frequency of blocks.
MachineFunctionProperties getClearedProperties() const override
MachineFunctionProperties getSetProperties() const override
Mode OptMode
Optimization mode of the pass.
const RegisterBankInfo::InstructionMapping & findBestMapping(MachineInstr &MI, RegisterBankInfo::InstructionMappings &PossibleMappings, SmallVectorImpl< RepairingPlacement > &RepairPts)
Find the best mapping for MI from PossibleMappings.
MachineFunctionProperties getRequiredProperties() const override
bool assignInstr(MachineInstr &MI)
Assign the register bank of each operand of MI.
bool assignRegisterBanks(MachineFunction &MF)
Walk through MF and assign a register bank to every virtual register that are still mapped to nothing...
void init(MachineFunction &MF)
Initialize the field members using MF.
void tryAvoidingSplit(RegBankSelect::RepairingPlacement &RepairPt, const MachineOperand &MO, const RegisterBankInfo::ValueMapping &ValMapping) const
When RepairPt involves splitting to repair MO for the given ValMapping, try to change the way we repa...
RegBankSelect(char &PassID=ID, Mode RunningMode=Fast)
Create a RegBankSelect pass with the specified RunningMode.
const TargetRegisterInfo * TRI
Information on the register classes for the current function.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
MachineBranchProbabilityInfo * MBPI
Get the frequency of the edges.
bool assignmentMatch(Register Reg, const RegisterBankInfo::ValueMapping &ValMapping, bool &OnlyAssign) const
Check if Reg is already assigned what is described by ValMapping.
uint64_t getRepairCost(const MachineOperand &MO, const RegisterBankInfo::ValueMapping &ValMapping) const
Return the cost of the instruction needed to map MO to ValMapping.
MappingCost computeMapping(MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, SmallVectorImpl< RepairingPlacement > &RepairPts, const MappingCost *BestCost=nullptr)
Compute the cost of mapping MI with InstrMapping and compute the repairing placement for such mapping...
bool repairReg(MachineOperand &MO, const RegisterBankInfo::ValueMapping &ValMapping, RegBankSelect::RepairingPlacement &RepairPt, const iterator_range< SmallVectorImpl< Register >::const_iterator > &NewVRegs)
Insert repairing code for Reg as specified by ValMapping.
StringRef getPassName() const override
getPassName - Return a nice clean name for a pass.
MachineRegisterInfo * MRI
MRI contains all the register class/bank information that this pass uses and updates.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetPassConfig * TPC
Current target configuration. Controls how the pass handles errors.
const RegisterBankInfo * RBI
Interface to the target lowering info related to register banks.
std::unique_ptr< MachineOptimizationRemarkEmitter > MORE
Current optimization remark emitter. Used to report failures.
bool applyMapping(MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, SmallVectorImpl< RepairingPlacement > &RepairPts)
Apply Mapping to MI.
Helper class that represents how the value of an instruction may be mapped and what is the related co...
Holds all the information related to register banks.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
typename SuperClass::const_iterator const_iterator
Definition: SmallVector.h:591
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
InstructionCost Cost
Helper struct that represents how a value is mapped through different register banks.