LLVM 20.0.0git
CSKYConstantIslandPass.cpp
Go to the documentation of this file.
1//===- CSKYConstantIslandPass.cpp - Emit PC Relative loads ----------------===//
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//
10// Loading constants inline is expensive on CSKY and it's in general better
11// to place the constant nearby in code space and then it can be loaded with a
12// simple 16/32 bit load instruction like lrw.
13//
14// The constants can be not just numbers but addresses of functions and labels.
15// This can be particularly helpful in static relocation mode for embedded
16// non-linux targets.
17//
18//===----------------------------------------------------------------------===//
19
20#include "CSKY.h"
23#include "CSKYSubtarget.h"
24#include "llvm/ADT/STLExtras.h"
25#include "llvm/ADT/SmallSet.h"
27#include "llvm/ADT/Statistic.h"
28#include "llvm/ADT/StringRef.h"
38#include "llvm/Config/llvm-config.h"
39#include "llvm/IR/Constants.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/DebugLoc.h"
42#include "llvm/IR/Function.h"
43#include "llvm/IR/Type.h"
46#include "llvm/Support/Debug.h"
48#include "llvm/Support/Format.h"
51#include <algorithm>
52#include <cassert>
53#include <cstdint>
54#include <iterator>
55#include <vector>
56
57using namespace llvm;
58
59#define DEBUG_TYPE "CSKY-constant-islands"
60
61STATISTIC(NumCPEs, "Number of constpool entries");
62STATISTIC(NumSplit, "Number of uncond branches inserted");
63STATISTIC(NumCBrFixed, "Number of cond branches fixed");
64STATISTIC(NumUBrFixed, "Number of uncond branches fixed");
65
66namespace {
67
69using ReverseIter = MachineBasicBlock::reverse_iterator;
70
71/// CSKYConstantIslands - Due to limited PC-relative displacements, CSKY
72/// requires constant pool entries to be scattered among the instructions
73/// inside a function. To do this, it completely ignores the normal LLVM
74/// constant pool; instead, it places constants wherever it feels like with
75/// special instructions.
76///
77/// The terminology used in this pass includes:
78/// Islands - Clumps of constants placed in the function.
79/// Water - Potential places where an island could be formed.
80/// CPE - A constant pool entry that has been placed somewhere, which
81/// tracks a list of users.
82
83class CSKYConstantIslands : public MachineFunctionPass {
84 /// BasicBlockInfo - Information about the offset and size of a single
85 /// basic block.
86 struct BasicBlockInfo {
87 /// Offset - Distance from the beginning of the function to the beginning
88 /// of this basic block.
89 ///
90 /// Offsets are computed assuming worst case padding before an aligned
91 /// block. This means that subtracting basic block offsets always gives a
92 /// conservative estimate of the real distance which may be smaller.
93 ///
94 /// Because worst case padding is used, the computed offset of an aligned
95 /// block may not actually be aligned.
96 unsigned Offset = 0;
97
98 /// Size - Size of the basic block in bytes. If the block contains
99 /// inline assembly, this is a worst case estimate.
100 ///
101 /// The size does not include any alignment padding whether from the
102 /// beginning of the block, or from an aligned jump table at the end.
103 unsigned Size = 0;
104
105 BasicBlockInfo() = default;
106
107 unsigned postOffset() const { return Offset + Size; }
108 };
109
110 std::vector<BasicBlockInfo> BBInfo;
111
112 /// WaterList - A sorted list of basic blocks where islands could be placed
113 /// (i.e. blocks that don't fall through to the following block, due
114 /// to a return, unreachable, or unconditional branch).
115 std::vector<MachineBasicBlock *> WaterList;
116
117 /// NewWaterList - The subset of WaterList that was created since the
118 /// previous iteration by inserting unconditional branches.
120
121 using water_iterator = std::vector<MachineBasicBlock *>::iterator;
122
123 /// CPUser - One user of a constant pool, keeping the machine instruction
124 /// pointer, the constant pool being referenced, and the max displacement
125 /// allowed from the instruction to the CP. The HighWaterMark records the
126 /// highest basic block where a new CPEntry can be placed. To ensure this
127 /// pass terminates, the CP entries are initially placed at the end of the
128 /// function and then move monotonically to lower addresses. The
129 /// exception to this rule is when the current CP entry for a particular
130 /// CPUser is out of range, but there is another CP entry for the same
131 /// constant value in range. We want to use the existing in-range CP
132 /// entry, but if it later moves out of range, the search for new water
133 /// should resume where it left off. The HighWaterMark is used to record
134 /// that point.
135 struct CPUser {
137 MachineInstr *CPEMI;
138 MachineBasicBlock *HighWaterMark;
139
140 private:
141 unsigned MaxDisp;
142
143 public:
144 bool NegOk;
145
146 CPUser(MachineInstr *Mi, MachineInstr *Cpemi, unsigned Maxdisp, bool Neg)
147 : MI(Mi), CPEMI(Cpemi), MaxDisp(Maxdisp), NegOk(Neg) {
148 HighWaterMark = CPEMI->getParent();
149 }
150
151 /// getMaxDisp - Returns the maximum displacement supported by MI.
152 unsigned getMaxDisp() const { return MaxDisp - 16; }
153
154 void setMaxDisp(unsigned Val) { MaxDisp = Val; }
155 };
156
157 /// CPUsers - Keep track of all of the machine instructions that use various
158 /// constant pools and their max displacement.
159 std::vector<CPUser> CPUsers;
160
161 /// CPEntry - One per constant pool entry, keeping the machine instruction
162 /// pointer, the constpool index, and the number of CPUser's which
163 /// reference this entry.
164 struct CPEntry {
165 MachineInstr *CPEMI;
166 unsigned CPI;
167 unsigned RefCount;
168
169 CPEntry(MachineInstr *Cpemi, unsigned Cpi, unsigned Rc = 0)
170 : CPEMI(Cpemi), CPI(Cpi), RefCount(Rc) {}
171 };
172
173 /// CPEntries - Keep track of all of the constant pool entry machine
174 /// instructions. For each original constpool index (i.e. those that
175 /// existed upon entry to this pass), it keeps a vector of entries.
176 /// Original elements are cloned as we go along; the clones are
177 /// put in the vector of the original element, but have distinct CPIs.
178 std::vector<std::vector<CPEntry>> CPEntries;
179
180 /// ImmBranch - One per immediate branch, keeping the machine instruction
181 /// pointer, conditional or unconditional, the max displacement,
182 /// and (if isCond is true) the corresponding unconditional branch
183 /// opcode.
184 struct ImmBranch {
186 unsigned MaxDisp : 31;
187 bool IsCond : 1;
188 int UncondBr;
189
190 ImmBranch(MachineInstr *Mi, unsigned Maxdisp, bool Cond, int Ubr)
191 : MI(Mi), MaxDisp(Maxdisp), IsCond(Cond), UncondBr(Ubr) {}
192 };
193
194 /// ImmBranches - Keep track of all the immediate branch instructions.
195 ///
196 std::vector<ImmBranch> ImmBranches;
197
198 const CSKYSubtarget *STI = nullptr;
199 const CSKYInstrInfo *TII;
201 MachineFunction *MF = nullptr;
202 MachineConstantPool *MCP = nullptr;
203
204 unsigned PICLabelUId;
205
206 void initPICLabelUId(unsigned UId) { PICLabelUId = UId; }
207
208 unsigned createPICLabelUId() { return PICLabelUId++; }
209
210public:
211 static char ID;
212
213 CSKYConstantIslands() : MachineFunctionPass(ID) {}
214
215 StringRef getPassName() const override { return "CSKY Constant Islands"; }
216
217 bool runOnMachineFunction(MachineFunction &F) override;
218
221 MachineFunctionProperties::Property::NoVRegs);
222 }
223
224 void doInitialPlacement(std::vector<MachineInstr *> &CPEMIs);
225 CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI);
226 Align getCPEAlign(const MachineInstr &CPEMI);
227 void initializeFunctionInfo(const std::vector<MachineInstr *> &CPEMIs);
228 unsigned getOffsetOf(MachineInstr *MI) const;
229 unsigned getUserOffset(CPUser &) const;
230 void dumpBBs();
231
232 bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset, unsigned Disp,
233 bool NegativeOK);
234 bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,
235 const CPUser &U);
236
237 void computeBlockSize(MachineBasicBlock *MBB);
238 MachineBasicBlock *splitBlockBeforeInstr(MachineInstr &MI);
239 void updateForInsertedWaterBlock(MachineBasicBlock *NewBB);
240 void adjustBBOffsetsAfter(MachineBasicBlock *BB);
241 bool decrementCPEReferenceCount(unsigned CPI, MachineInstr *CPEMI);
242 int findInRangeCPEntry(CPUser &U, unsigned UserOffset);
243 bool findAvailableWater(CPUser &U, unsigned UserOffset,
244 water_iterator &WaterIter);
245 void createNewWater(unsigned CPUserIndex, unsigned UserOffset,
246 MachineBasicBlock *&NewMBB);
247 bool handleConstantPoolUser(unsigned CPUserIndex);
248 void removeDeadCPEMI(MachineInstr *CPEMI);
249 bool removeUnusedCPEntries();
250 bool isCPEntryInRange(MachineInstr *MI, unsigned UserOffset,
251 MachineInstr *CPEMI, unsigned Disp, bool NegOk,
252 bool DoDump = false);
253 bool isWaterInRange(unsigned UserOffset, MachineBasicBlock *Water, CPUser &U,
254 unsigned &Growth);
255 bool isBBInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp);
256 bool fixupImmediateBr(ImmBranch &Br);
257 bool fixupConditionalBr(ImmBranch &Br);
258 bool fixupUnconditionalBr(ImmBranch &Br);
259};
260} // end anonymous namespace
261
262char CSKYConstantIslands::ID = 0;
263
264bool CSKYConstantIslands::isOffsetInRange(unsigned UserOffset,
265 unsigned TrialOffset,
266 const CPUser &U) {
267 return isOffsetInRange(UserOffset, TrialOffset, U.getMaxDisp(), U.NegOk);
268}
269
270#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
271/// print block size and offset information - debugging
272LLVM_DUMP_METHOD void CSKYConstantIslands::dumpBBs() {
273 for (unsigned J = 0, E = BBInfo.size(); J != E; ++J) {
274 const BasicBlockInfo &BBI = BBInfo[J];
275 dbgs() << format("%08x %bb.%u\t", BBI.Offset, J)
276 << format(" size=%#x\n", BBInfo[J].Size);
277 }
278}
279#endif
280
281bool CSKYConstantIslands::runOnMachineFunction(MachineFunction &Mf) {
282 MF = &Mf;
283 MCP = Mf.getConstantPool();
284 STI = &Mf.getSubtarget<CSKYSubtarget>();
285
286 LLVM_DEBUG(dbgs() << "***** CSKYConstantIslands: "
287 << MCP->getConstants().size() << " CP entries, aligned to "
288 << MCP->getConstantPoolAlign().value() << " bytes *****\n");
289
290 TII = STI->getInstrInfo();
291 MFI = MF->getInfo<CSKYMachineFunctionInfo>();
292
293 // This pass invalidates liveness information when it splits basic blocks.
294 MF->getRegInfo().invalidateLiveness();
295
296 // Renumber all of the machine basic blocks in the function, guaranteeing that
297 // the numbers agree with the position of the block in the function.
298 MF->RenumberBlocks();
299
300 bool MadeChange = false;
301
302 // Perform the initial placement of the constant pool entries. To start with,
303 // we put them all at the end of the function.
304 std::vector<MachineInstr *> CPEMIs;
305 if (!MCP->isEmpty())
306 doInitialPlacement(CPEMIs);
307
308 /// The next UID to take is the first unused one.
309 initPICLabelUId(CPEMIs.size());
310
311 // Do the initial scan of the function, building up information about the
312 // sizes of each block, the location of all the water, and finding all of the
313 // constant pool users.
314 initializeFunctionInfo(CPEMIs);
315 CPEMIs.clear();
316 LLVM_DEBUG(dumpBBs());
317
318 /// Remove dead constant pool entries.
319 MadeChange |= removeUnusedCPEntries();
320
321 // Iteratively place constant pool entries and fix up branches until there
322 // is no change.
323 unsigned NoCPIters = 0, NoBRIters = 0;
324 (void)NoBRIters;
325 while (true) {
326 LLVM_DEBUG(dbgs() << "Beginning CP iteration #" << NoCPIters << '\n');
327 bool CPChange = false;
328 for (unsigned I = 0, E = CPUsers.size(); I != E; ++I)
329 CPChange |= handleConstantPoolUser(I);
330 if (CPChange && ++NoCPIters > 30)
331 report_fatal_error("Constant Island pass failed to converge!");
332 LLVM_DEBUG(dumpBBs());
333
334 // Clear NewWaterList now. If we split a block for branches, it should
335 // appear as "new water" for the next iteration of constant pool placement.
336 NewWaterList.clear();
337
338 LLVM_DEBUG(dbgs() << "Beginning BR iteration #" << NoBRIters << '\n');
339 bool BRChange = false;
340 for (unsigned I = 0, E = ImmBranches.size(); I != E; ++I)
341 BRChange |= fixupImmediateBr(ImmBranches[I]);
342 if (BRChange && ++NoBRIters > 30)
343 report_fatal_error("Branch Fix Up pass failed to converge!");
344 LLVM_DEBUG(dumpBBs());
345 if (!CPChange && !BRChange)
346 break;
347 MadeChange = true;
348 }
349
350 LLVM_DEBUG(dbgs() << '\n'; dumpBBs());
351
352 BBInfo.clear();
353 WaterList.clear();
354 CPUsers.clear();
355 CPEntries.clear();
356 ImmBranches.clear();
357 return MadeChange;
358}
359
360/// doInitialPlacement - Perform the initial placement of the constant pool
361/// entries. To start with, we put them all at the end of the function.
362void CSKYConstantIslands::doInitialPlacement(
363 std::vector<MachineInstr *> &CPEMIs) {
364 // Create the basic block to hold the CPE's.
365 MachineBasicBlock *BB = MF->CreateMachineBasicBlock();
366 MF->push_back(BB);
367
368 // MachineConstantPool measures alignment in bytes. We measure in log2(bytes).
369 const Align MaxAlign = MCP->getConstantPoolAlign();
370
371 // Mark the basic block as required by the const-pool.
372 BB->setAlignment(Align(2));
373
374 // The function needs to be as aligned as the basic blocks. The linker may
375 // move functions around based on their alignment.
376 MF->ensureAlignment(BB->getAlignment());
377
378 // Order the entries in BB by descending alignment. That ensures correct
379 // alignment of all entries as long as BB is sufficiently aligned. Keep
380 // track of the insertion point for each alignment. We are going to bucket
381 // sort the entries as they are created.
383 BB->end());
384
385 // Add all of the constants from the constant pool to the end block, use an
386 // identity mapping of CPI's to CPE's.
387 const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
388
389 const DataLayout &TD = MF->getDataLayout();
390 for (unsigned I = 0, E = CPs.size(); I != E; ++I) {
391 unsigned Size = CPs[I].getSizeInBytes(TD);
392 assert(Size >= 4 && "Too small constant pool entry");
393 Align Alignment = CPs[I].getAlign();
394 // Verify that all constant pool entries are a multiple of their alignment.
395 // If not, we would have to pad them out so that instructions stay aligned.
396 assert(isAligned(Alignment, Size) && "CP Entry not multiple of 4 bytes!");
397
398 // Insert CONSTPOOL_ENTRY before entries with a smaller alignment.
399 unsigned LogAlign = Log2(Alignment);
400 MachineBasicBlock::iterator InsAt = InsPoint[LogAlign];
401
402 MachineInstr *CPEMI =
403 BuildMI(*BB, InsAt, DebugLoc(), TII->get(CSKY::CONSTPOOL_ENTRY))
404 .addImm(I)
406 .addImm(Size);
407
408 CPEMIs.push_back(CPEMI);
409
410 // Ensure that future entries with higher alignment get inserted before
411 // CPEMI. This is bucket sort with iterators.
412 for (unsigned A = LogAlign + 1; A <= Log2(MaxAlign); ++A)
413 if (InsPoint[A] == InsAt)
414 InsPoint[A] = CPEMI;
415 // Add a new CPEntry, but no corresponding CPUser yet.
416 CPEntries.emplace_back(1, CPEntry(CPEMI, I));
417 ++NumCPEs;
418 LLVM_DEBUG(dbgs() << "Moved CPI#" << I << " to end of function, size = "
419 << Size << ", align = " << Alignment.value() << '\n');
420 }
421 LLVM_DEBUG(BB->dump());
422}
423
424/// BBHasFallthrough - Return true if the specified basic block can fallthrough
425/// into the block immediately after it.
427 // Get the next machine basic block in the function.
429 // Can't fall off end of function.
430 if (std::next(MBBI) == MBB->getParent()->end())
431 return false;
432
433 MachineBasicBlock *NextBB = &*std::next(MBBI);
435 E = MBB->succ_end();
436 I != E; ++I)
437 if (*I == NextBB)
438 return true;
439
440 return false;
441}
442
443/// findConstPoolEntry - Given the constpool index and CONSTPOOL_ENTRY MI,
444/// look up the corresponding CPEntry.
445CSKYConstantIslands::CPEntry *
446CSKYConstantIslands::findConstPoolEntry(unsigned CPI,
447 const MachineInstr *CPEMI) {
448 std::vector<CPEntry> &CPEs = CPEntries[CPI];
449 // Number of entries per constpool index should be small, just do a
450 // linear search.
451 for (unsigned I = 0, E = CPEs.size(); I != E; ++I) {
452 if (CPEs[I].CPEMI == CPEMI)
453 return &CPEs[I];
454 }
455 return nullptr;
456}
457
458/// getCPEAlign - Returns the required alignment of the constant pool entry
459/// represented by CPEMI. Alignment is measured in log2(bytes) units.
460Align CSKYConstantIslands::getCPEAlign(const MachineInstr &CPEMI) {
461 assert(CPEMI.getOpcode() == CSKY::CONSTPOOL_ENTRY);
462
463 unsigned CPI = CPEMI.getOperand(1).getIndex();
464 assert(CPI < MCP->getConstants().size() && "Invalid constant pool index.");
465 return MCP->getConstants()[CPI].getAlign();
466}
467
468/// initializeFunctionInfo - Do the initial scan of the function, building up
469/// information about the sizes of each block, the location of all the water,
470/// and finding all of the constant pool users.
471void CSKYConstantIslands::initializeFunctionInfo(
472 const std::vector<MachineInstr *> &CPEMIs) {
473 BBInfo.clear();
474 BBInfo.resize(MF->getNumBlockIDs());
475
476 // First thing, compute the size of all basic blocks, and see if the function
477 // has any inline assembly in it. If so, we have to be conservative about
478 // alignment assumptions, as we don't know for sure the size of any
479 // instructions in the inline assembly.
480 for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I)
481 computeBlockSize(&*I);
482
483 // Compute block offsets.
484 adjustBBOffsetsAfter(&MF->front());
485
486 // Now go back through the instructions and build up our data structures.
487 for (MachineBasicBlock &MBB : *MF) {
488 // If this block doesn't fall through into the next MBB, then this is
489 // 'water' that a constant pool island could be placed.
490 if (!bbHasFallthrough(&MBB))
491 WaterList.push_back(&MBB);
492 for (MachineInstr &MI : MBB) {
493 if (MI.isDebugInstr())
494 continue;
495
496 int Opc = MI.getOpcode();
497 if (MI.isBranch() && !MI.isIndirectBranch()) {
498 bool IsCond = MI.isConditionalBranch();
499 unsigned Bits = 0;
500 unsigned Scale = 1;
501 int UOpc = CSKY::BR32;
502
503 switch (MI.getOpcode()) {
504 case CSKY::BR16:
505 case CSKY::BF16:
506 case CSKY::BT16:
507 Bits = 10;
508 Scale = 2;
509 break;
510 default:
511 Bits = 16;
512 Scale = 2;
513 break;
514 }
515
516 // Record this immediate branch.
517 unsigned MaxOffs = ((1 << (Bits - 1)) - 1) * Scale;
518 ImmBranches.push_back(ImmBranch(&MI, MaxOffs, IsCond, UOpc));
519 }
520
521 if (Opc == CSKY::CONSTPOOL_ENTRY)
522 continue;
523
524 // Scan the instructions for constant pool operands.
525 for (unsigned Op = 0, E = MI.getNumOperands(); Op != E; ++Op)
526 if (MI.getOperand(Op).isCPI()) {
527 // We found one. The addressing mode tells us the max displacement
528 // from the PC that this instruction permits.
529
530 // Basic size info comes from the TSFlags field.
531 unsigned Bits = 0;
532 unsigned Scale = 1;
533 bool NegOk = false;
534
535 switch (Opc) {
536 default:
537 llvm_unreachable("Unknown addressing mode for CP reference!");
538 case CSKY::MOVIH32:
539 case CSKY::ORI32:
540 continue;
541 case CSKY::PseudoTLSLA32:
542 case CSKY::JSRI32:
543 case CSKY::JMPI32:
544 case CSKY::LRW32:
545 case CSKY::LRW32_Gen:
546 Bits = 16;
547 Scale = 4;
548 break;
549 case CSKY::f2FLRW_S:
550 case CSKY::f2FLRW_D:
551 Bits = 8;
552 Scale = 4;
553 break;
554 case CSKY::GRS32:
555 Bits = 17;
556 Scale = 2;
557 NegOk = true;
558 break;
559 }
560 // Remember that this is a user of a CP entry.
561 unsigned CPI = MI.getOperand(Op).getIndex();
562 MachineInstr *CPEMI = CPEMIs[CPI];
563 unsigned MaxOffs = ((1 << Bits) - 1) * Scale;
564 CPUsers.push_back(CPUser(&MI, CPEMI, MaxOffs, NegOk));
565
566 // Increment corresponding CPEntry reference count.
567 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
568 assert(CPE && "Cannot find a corresponding CPEntry!");
569 CPE->RefCount++;
570 }
571 }
572 }
573}
574
575/// computeBlockSize - Compute the size and some alignment information for MBB.
576/// This function updates BBInfo directly.
577void CSKYConstantIslands::computeBlockSize(MachineBasicBlock *MBB) {
578 BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];
579 BBI.Size = 0;
580
581 for (const MachineInstr &MI : *MBB)
582 BBI.Size += TII->getInstSizeInBytes(MI);
583}
584
585/// getOffsetOf - Return the current offset of the specified machine instruction
586/// from the start of the function. This offset changes as stuff is moved
587/// around inside the function.
588unsigned CSKYConstantIslands::getOffsetOf(MachineInstr *MI) const {
589 MachineBasicBlock *MBB = MI->getParent();
590
591 // The offset is composed of two things: the sum of the sizes of all MBB's
592 // before this instruction's block, and the offset from the start of the block
593 // it is in.
594 unsigned Offset = BBInfo[MBB->getNumber()].Offset;
595
596 // Sum instructions before MI in MBB.
597 for (MachineBasicBlock::iterator I = MBB->begin(); &*I != MI; ++I) {
598 assert(I != MBB->end() && "Didn't find MI in its own basic block?");
599 Offset += TII->getInstSizeInBytes(*I);
600 }
601 return Offset;
602}
603
604/// CompareMBBNumbers - Little predicate function to sort the WaterList by MBB
605/// ID.
607 const MachineBasicBlock *RHS) {
608 return LHS->getNumber() < RHS->getNumber();
609}
610
611/// updateForInsertedWaterBlock - When a block is newly inserted into the
612/// machine function, it upsets all of the block numbers. Renumber the blocks
613/// and update the arrays that parallel this numbering.
614void CSKYConstantIslands::updateForInsertedWaterBlock(
615 MachineBasicBlock *NewBB) {
616 // Renumber the MBB's to keep them consecutive.
617 NewBB->getParent()->RenumberBlocks(NewBB);
618
619 // Insert an entry into BBInfo to align it properly with the (newly
620 // renumbered) block numbers.
621 BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
622
623 // Next, update WaterList. Specifically, we need to add NewMBB as having
624 // available water after it.
625 water_iterator IP = llvm::lower_bound(WaterList, NewBB, compareMbbNumbers);
626 WaterList.insert(IP, NewBB);
627}
628
629unsigned CSKYConstantIslands::getUserOffset(CPUser &U) const {
630 unsigned UserOffset = getOffsetOf(U.MI);
631
632 UserOffset &= ~3u;
633
634 return UserOffset;
635}
636
637/// Split the basic block containing MI into two blocks, which are joined by
638/// an unconditional branch. Update data structures and renumber blocks to
639/// account for this change and returns the newly created block.
641CSKYConstantIslands::splitBlockBeforeInstr(MachineInstr &MI) {
642 MachineBasicBlock *OrigBB = MI.getParent();
643
644 // Create a new MBB for the code after the OrigBB.
645 MachineBasicBlock *NewBB =
646 MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());
648 MF->insert(MBBI, NewBB);
649
650 // Splice the instructions starting with MI over to NewBB.
651 NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end());
652
653 // Add an unconditional branch from OrigBB to NewBB.
654 // Note the new unconditional branch is not being recorded.
655 // There doesn't seem to be meaningful DebugInfo available; this doesn't
656 // correspond to anything in the source.
657
658 // TODO: Add support for 16bit instr.
659 BuildMI(OrigBB, DebugLoc(), TII->get(CSKY::BR32)).addMBB(NewBB);
660 ++NumSplit;
661
662 // Update the CFG. All succs of OrigBB are now succs of NewBB.
663 NewBB->transferSuccessors(OrigBB);
664
665 // OrigBB branches to NewBB.
666 OrigBB->addSuccessor(NewBB);
667
668 // Update internal data structures to account for the newly inserted MBB.
669 // This is almost the same as updateForInsertedWaterBlock, except that
670 // the Water goes after OrigBB, not NewBB.
671 MF->RenumberBlocks(NewBB);
672
673 // Insert an entry into BBInfo to align it properly with the (newly
674 // renumbered) block numbers.
675 BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
676
677 // Next, update WaterList. Specifically, we need to add OrigMBB as having
678 // available water after it (but not if it's already there, which happens
679 // when splitting before a conditional branch that is followed by an
680 // unconditional branch - in that case we want to insert NewBB).
681 water_iterator IP = llvm::lower_bound(WaterList, OrigBB, compareMbbNumbers);
682 MachineBasicBlock *WaterBB = *IP;
683 if (WaterBB == OrigBB)
684 WaterList.insert(std::next(IP), NewBB);
685 else
686 WaterList.insert(IP, OrigBB);
687 NewWaterList.insert(OrigBB);
688
689 // Figure out how large the OrigBB is. As the first half of the original
690 // block, it cannot contain a tablejump. The size includes
691 // the new jump we added. (It should be possible to do this without
692 // recounting everything, but it's very confusing, and this is rarely
693 // executed.)
694 computeBlockSize(OrigBB);
695
696 // Figure out how large the NewMBB is. As the second half of the original
697 // block, it may contain a tablejump.
698 computeBlockSize(NewBB);
699
700 // All BBOffsets following these blocks must be modified.
701 adjustBBOffsetsAfter(OrigBB);
702
703 return NewBB;
704}
705
706/// isOffsetInRange - Checks whether UserOffset (the location of a constant pool
707/// reference) is within MaxDisp of TrialOffset (a proposed location of a
708/// constant pool entry).
709bool CSKYConstantIslands::isOffsetInRange(unsigned UserOffset,
710 unsigned TrialOffset,
711 unsigned MaxDisp, bool NegativeOK) {
712 if (UserOffset <= TrialOffset) {
713 // User before the Trial.
714 if (TrialOffset - UserOffset <= MaxDisp)
715 return true;
716 } else if (NegativeOK) {
717 if (UserOffset - TrialOffset <= MaxDisp)
718 return true;
719 }
720 return false;
721}
722
723/// isWaterInRange - Returns true if a CPE placed after the specified
724/// Water (a basic block) will be in range for the specific MI.
725///
726/// Compute how much the function will grow by inserting a CPE after Water.
727bool CSKYConstantIslands::isWaterInRange(unsigned UserOffset,
728 MachineBasicBlock *Water, CPUser &U,
729 unsigned &Growth) {
730 unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset();
731 unsigned NextBlockOffset;
732 Align NextBlockAlignment;
733 MachineFunction::const_iterator NextBlock = ++Water->getIterator();
734 if (NextBlock == MF->end()) {
735 NextBlockOffset = BBInfo[Water->getNumber()].postOffset();
736 NextBlockAlignment = Align(4);
737 } else {
738 NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
739 NextBlockAlignment = NextBlock->getAlignment();
740 }
741 unsigned Size = U.CPEMI->getOperand(2).getImm();
742 unsigned CPEEnd = CPEOffset + Size;
743
744 // The CPE may be able to hide in the alignment padding before the next
745 // block. It may also cause more padding to be required if it is more aligned
746 // that the next block.
747 if (CPEEnd > NextBlockOffset) {
748 Growth = CPEEnd - NextBlockOffset;
749 // Compute the padding that would go at the end of the CPE to align the next
750 // block.
751 Growth += offsetToAlignment(CPEEnd, NextBlockAlignment);
752
753 // If the CPE is to be inserted before the instruction, that will raise
754 // the offset of the instruction. Also account for unknown alignment padding
755 // in blocks between CPE and the user.
756 if (CPEOffset < UserOffset)
757 UserOffset += Growth;
758 } else
759 // CPE fits in existing padding.
760 Growth = 0;
761
762 return isOffsetInRange(UserOffset, CPEOffset, U);
763}
764
765/// isCPEntryInRange - Returns true if the distance between specific MI and
766/// specific ConstPool entry instruction can fit in MI's displacement field.
767bool CSKYConstantIslands::isCPEntryInRange(MachineInstr *MI,
768 unsigned UserOffset,
769 MachineInstr *CPEMI,
770 unsigned MaxDisp, bool NegOk,
771 bool DoDump) {
772 unsigned CPEOffset = getOffsetOf(CPEMI);
773
774 if (DoDump) {
775 LLVM_DEBUG({
776 unsigned Block = MI->getParent()->getNumber();
777 const BasicBlockInfo &BBI = BBInfo[Block];
778 dbgs() << "User of CPE#" << CPEMI->getOperand(0).getImm()
779 << " max delta=" << MaxDisp
780 << format(" insn address=%#x", UserOffset) << " in "
781 << printMBBReference(*MI->getParent()) << ": "
782 << format("%#x-%x\t", BBI.Offset, BBI.postOffset()) << *MI
783 << format("CPE address=%#x offset=%+d: ", CPEOffset,
784 int(CPEOffset - UserOffset));
785 });
786 }
787
788 return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
789}
790
791#ifndef NDEBUG
792/// BBIsJumpedOver - Return true of the specified basic block's only predecessor
793/// unconditionally branches to its only successor.
795 if (MBB->pred_size() != 1 || MBB->succ_size() != 1)
796 return false;
797 MachineBasicBlock *Succ = *MBB->succ_begin();
798 MachineBasicBlock *Pred = *MBB->pred_begin();
799 MachineInstr *PredMI = &Pred->back();
800 if (PredMI->getOpcode() == CSKY::BR32 /*TODO: change to 16bit instr. */)
801 return PredMI->getOperand(0).getMBB() == Succ;
802 return false;
803}
804#endif
805
806void CSKYConstantIslands::adjustBBOffsetsAfter(MachineBasicBlock *BB) {
807 unsigned BBNum = BB->getNumber();
808 for (unsigned I = BBNum + 1, E = MF->getNumBlockIDs(); I < E; ++I) {
809 // Get the offset and known bits at the end of the layout predecessor.
810 // Include the alignment of the current block.
811 unsigned Offset = BBInfo[I - 1].Offset + BBInfo[I - 1].Size;
812 BBInfo[I].Offset = Offset;
813 }
814}
815
816/// decrementCPEReferenceCount - find the constant pool entry with index CPI
817/// and instruction CPEMI, and decrement its refcount. If the refcount
818/// becomes 0 remove the entry and instruction. Returns true if we removed
819/// the entry, false if we didn't.
820bool CSKYConstantIslands::decrementCPEReferenceCount(unsigned CPI,
821 MachineInstr *CPEMI) {
822 // Find the old entry. Eliminate it if it is no longer used.
823 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
824 assert(CPE && "Unexpected!");
825 if (--CPE->RefCount == 0) {
826 removeDeadCPEMI(CPEMI);
827 CPE->CPEMI = nullptr;
828 --NumCPEs;
829 return true;
830 }
831 return false;
832}
833
834/// LookForCPEntryInRange - see if the currently referenced CPE is in range;
835/// if not, see if an in-range clone of the CPE is in range, and if so,
836/// change the data structures so the user references the clone. Returns:
837/// 0 = no existing entry found
838/// 1 = entry found, and there were no code insertions or deletions
839/// 2 = entry found, and there were code insertions or deletions
840int CSKYConstantIslands::findInRangeCPEntry(CPUser &U, unsigned UserOffset) {
841 MachineInstr *UserMI = U.MI;
842 MachineInstr *CPEMI = U.CPEMI;
843
844 // Check to see if the CPE is already in-range.
845 if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk,
846 true)) {
847 LLVM_DEBUG(dbgs() << "In range\n");
848 return 1;
849 }
850
851 // No. Look for previously created clones of the CPE that are in range.
852 unsigned CPI = CPEMI->getOperand(1).getIndex();
853 std::vector<CPEntry> &CPEs = CPEntries[CPI];
854 for (unsigned I = 0, E = CPEs.size(); I != E; ++I) {
855 // We already tried this one
856 if (CPEs[I].CPEMI == CPEMI)
857 continue;
858 // Removing CPEs can leave empty entries, skip
859 if (CPEs[I].CPEMI == nullptr)
860 continue;
861 if (isCPEntryInRange(UserMI, UserOffset, CPEs[I].CPEMI, U.getMaxDisp(),
862 U.NegOk)) {
863 LLVM_DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#"
864 << CPEs[I].CPI << "\n");
865 // Point the CPUser node to the replacement
866 U.CPEMI = CPEs[I].CPEMI;
867 // Change the CPI in the instruction operand to refer to the clone.
868 for (unsigned J = 0, E = UserMI->getNumOperands(); J != E; ++J)
869 if (UserMI->getOperand(J).isCPI()) {
870 UserMI->getOperand(J).setIndex(CPEs[I].CPI);
871 break;
872 }
873 // Adjust the refcount of the clone...
874 CPEs[I].RefCount++;
875 // ...and the original. If we didn't remove the old entry, none of the
876 // addresses changed, so we don't need another pass.
877 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
878 }
879 }
880 return 0;
881}
882
883/// getUnconditionalBrDisp - Returns the maximum displacement that can fit in
884/// the specific unconditional branch instruction.
885static inline unsigned getUnconditionalBrDisp(int Opc) {
886 unsigned Bits, Scale;
887
888 switch (Opc) {
889 case CSKY::BR16:
890 Bits = 10;
891 Scale = 2;
892 break;
893 case CSKY::BR32:
894 Bits = 16;
895 Scale = 2;
896 break;
897 default:
899 }
900
901 unsigned MaxOffs = ((1 << (Bits - 1)) - 1) * Scale;
902 return MaxOffs;
903}
904
905/// findAvailableWater - Look for an existing entry in the WaterList in which
906/// we can place the CPE referenced from U so it's within range of U's MI.
907/// Returns true if found, false if not. If it returns true, WaterIter
908/// is set to the WaterList entry.
909/// To ensure that this pass
910/// terminates, the CPE location for a particular CPUser is only allowed to
911/// move to a lower address, so search backward from the end of the list and
912/// prefer the first water that is in range.
913bool CSKYConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset,
914 water_iterator &WaterIter) {
915 if (WaterList.empty())
916 return false;
917
918 unsigned BestGrowth = ~0u;
919 for (water_iterator IP = std::prev(WaterList.end()), B = WaterList.begin();;
920 --IP) {
921 MachineBasicBlock *WaterBB = *IP;
922 // Check if water is in range and is either at a lower address than the
923 // current "high water mark" or a new water block that was created since
924 // the previous iteration by inserting an unconditional branch. In the
925 // latter case, we want to allow resetting the high water mark back to
926 // this new water since we haven't seen it before. Inserting branches
927 // should be relatively uncommon and when it does happen, we want to be
928 // sure to take advantage of it for all the CPEs near that block, so that
929 // we don't insert more branches than necessary.
930 unsigned Growth;
931 if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
932 (WaterBB->getNumber() < U.HighWaterMark->getNumber() ||
933 NewWaterList.count(WaterBB)) &&
934 Growth < BestGrowth) {
935 // This is the least amount of required padding seen so far.
936 BestGrowth = Growth;
937 WaterIter = IP;
938 LLVM_DEBUG(dbgs() << "Found water after " << printMBBReference(*WaterBB)
939 << " Growth=" << Growth << '\n');
940
941 // Keep looking unless it is perfect.
942 if (BestGrowth == 0)
943 return true;
944 }
945 if (IP == B)
946 break;
947 }
948 return BestGrowth != ~0u;
949}
950
951/// createNewWater - No existing WaterList entry will work for
952/// CPUsers[CPUserIndex], so create a place to put the CPE. The end of the
953/// block is used if in range, and the conditional branch munged so control
954/// flow is correct. Otherwise the block is split to create a hole with an
955/// unconditional branch around it. In either case NewMBB is set to a
956/// block following which the new island can be inserted (the WaterList
957/// is not adjusted).
958void CSKYConstantIslands::createNewWater(unsigned CPUserIndex,
959 unsigned UserOffset,
960 MachineBasicBlock *&NewMBB) {
961 CPUser &U = CPUsers[CPUserIndex];
962 MachineInstr *UserMI = U.MI;
963 MachineInstr *CPEMI = U.CPEMI;
964 MachineBasicBlock *UserMBB = UserMI->getParent();
965 const BasicBlockInfo &UserBBI = BBInfo[UserMBB->getNumber()];
966
967 // If the block does not end in an unconditional branch already, and if the
968 // end of the block is within range, make new water there.
969 if (bbHasFallthrough(UserMBB)) {
970 // Size of branch to insert.
971 unsigned Delta = 4;
972 // Compute the offset where the CPE will begin.
973 unsigned CPEOffset = UserBBI.postOffset() + Delta;
974
975 if (isOffsetInRange(UserOffset, CPEOffset, U)) {
976 LLVM_DEBUG(dbgs() << "Split at end of " << printMBBReference(*UserMBB)
977 << format(", expected CPE offset %#x\n", CPEOffset));
978 NewMBB = &*++UserMBB->getIterator();
979 // Add an unconditional branch from UserMBB to fallthrough block. Record
980 // it for branch lengthening; this new branch will not get out of range,
981 // but if the preceding conditional branch is out of range, the targets
982 // will be exchanged, and the altered branch may be out of range, so the
983 // machinery has to know about it.
984
985 // TODO: Add support for 16bit instr.
986 int UncondBr = CSKY::BR32;
987 auto *NewMI = BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr))
988 .addMBB(NewMBB)
989 .getInstr();
990 unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
991 ImmBranches.push_back(
992 ImmBranch(&UserMBB->back(), MaxDisp, false, UncondBr));
993 BBInfo[UserMBB->getNumber()].Size += TII->getInstSizeInBytes(*NewMI);
994 adjustBBOffsetsAfter(UserMBB);
995 return;
996 }
997 }
998
999 // What a big block. Find a place within the block to split it.
1000
1001 // Try to split the block so it's fully aligned. Compute the latest split
1002 // point where we can add a 4-byte branch instruction, and then align to
1003 // Align which is the largest possible alignment in the function.
1004 const Align Align = MF->getAlignment();
1005 unsigned BaseInsertOffset = UserOffset + U.getMaxDisp();
1006 LLVM_DEBUG(dbgs() << format("Split in middle of big block before %#x",
1007 BaseInsertOffset));
1008
1009 // The 4 in the following is for the unconditional branch we'll be inserting
1010 // Alignment of the island is handled
1011 // inside isOffsetInRange.
1012 BaseInsertOffset -= 4;
1013
1014 LLVM_DEBUG(dbgs() << format(", adjusted to %#x", BaseInsertOffset)
1015 << " la=" << Log2(Align) << '\n');
1016
1017 // This could point off the end of the block if we've already got constant
1018 // pool entries following this block; only the last one is in the water list.
1019 // Back past any possible branches (allow for a conditional and a maximally
1020 // long unconditional).
1021 if (BaseInsertOffset + 8 >= UserBBI.postOffset()) {
1022 BaseInsertOffset = UserBBI.postOffset() - 8;
1023 LLVM_DEBUG(dbgs() << format("Move inside block: %#x\n", BaseInsertOffset));
1024 }
1025 unsigned EndInsertOffset =
1026 BaseInsertOffset + 4 + CPEMI->getOperand(2).getImm();
1028 ++MI;
1029 unsigned CPUIndex = CPUserIndex + 1;
1030 unsigned NumCPUsers = CPUsers.size();
1031 for (unsigned Offset = UserOffset + TII->getInstSizeInBytes(*UserMI);
1032 Offset < BaseInsertOffset;
1033 Offset += TII->getInstSizeInBytes(*MI), MI = std::next(MI)) {
1034 assert(MI != UserMBB->end() && "Fell off end of block");
1035 if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {
1036 CPUser &U = CPUsers[CPUIndex];
1037 if (!isOffsetInRange(Offset, EndInsertOffset, U)) {
1038 // Shift intertion point by one unit of alignment so it is within reach.
1039 BaseInsertOffset -= Align.value();
1040 EndInsertOffset -= Align.value();
1041 }
1042 // This is overly conservative, as we don't account for CPEMIs being
1043 // reused within the block, but it doesn't matter much. Also assume CPEs
1044 // are added in order with alignment padding. We may eventually be able
1045 // to pack the aligned CPEs better.
1046 EndInsertOffset += U.CPEMI->getOperand(2).getImm();
1047 CPUIndex++;
1048 }
1049 }
1050
1051 NewMBB = splitBlockBeforeInstr(*--MI);
1052}
1053
1054/// handleConstantPoolUser - Analyze the specified user, checking to see if it
1055/// is out-of-range. If so, pick up the constant pool value and move it some
1056/// place in-range. Return true if we changed any addresses (thus must run
1057/// another pass of branch lengthening), false otherwise.
1058bool CSKYConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) {
1059 CPUser &U = CPUsers[CPUserIndex];
1060 MachineInstr *UserMI = U.MI;
1061 MachineInstr *CPEMI = U.CPEMI;
1062 unsigned CPI = CPEMI->getOperand(1).getIndex();
1063 unsigned Size = CPEMI->getOperand(2).getImm();
1064 // Compute this only once, it's expensive.
1065 unsigned UserOffset = getUserOffset(U);
1066
1067 // See if the current entry is within range, or there is a clone of it
1068 // in range.
1069 int result = findInRangeCPEntry(U, UserOffset);
1070 if (result == 1)
1071 return false;
1072 if (result == 2)
1073 return true;
1074
1075 // Look for water where we can place this CPE.
1076 MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock();
1077 MachineBasicBlock *NewMBB;
1078 water_iterator IP;
1079 if (findAvailableWater(U, UserOffset, IP)) {
1080 LLVM_DEBUG(dbgs() << "Found water in range\n");
1081 MachineBasicBlock *WaterBB = *IP;
1082
1083 // If the original WaterList entry was "new water" on this iteration,
1084 // propagate that to the new island. This is just keeping NewWaterList
1085 // updated to match the WaterList, which will be updated below.
1086 if (NewWaterList.erase(WaterBB))
1087 NewWaterList.insert(NewIsland);
1088
1089 // The new CPE goes before the following block (NewMBB).
1090 NewMBB = &*++WaterBB->getIterator();
1091 } else {
1092 LLVM_DEBUG(dbgs() << "No water found\n");
1093 createNewWater(CPUserIndex, UserOffset, NewMBB);
1094
1095 // splitBlockBeforeInstr adds to WaterList, which is important when it is
1096 // called while handling branches so that the water will be seen on the
1097 // next iteration for constant pools, but in this context, we don't want
1098 // it. Check for this so it will be removed from the WaterList.
1099 // Also remove any entry from NewWaterList.
1100 MachineBasicBlock *WaterBB = &*--NewMBB->getIterator();
1101 IP = llvm::find(WaterList, WaterBB);
1102 if (IP != WaterList.end())
1103 NewWaterList.erase(WaterBB);
1104
1105 // We are adding new water. Update NewWaterList.
1106 NewWaterList.insert(NewIsland);
1107 }
1108
1109 // Remove the original WaterList entry; we want subsequent insertions in
1110 // this vicinity to go after the one we're about to insert. This
1111 // considerably reduces the number of times we have to move the same CPE
1112 // more than once and is also important to ensure the algorithm terminates.
1113 if (IP != WaterList.end())
1114 WaterList.erase(IP);
1115
1116 // Okay, we know we can put an island before NewMBB now, do it!
1117 MF->insert(NewMBB->getIterator(), NewIsland);
1118
1119 // Update internal data structures to account for the newly inserted MBB.
1120 updateForInsertedWaterBlock(NewIsland);
1121
1122 // Decrement the old entry, and remove it if refcount becomes 0.
1123 decrementCPEReferenceCount(CPI, CPEMI);
1124
1125 // No existing clone of this CPE is within range.
1126 // We will be generating a new clone. Get a UID for it.
1127 unsigned ID = createPICLabelUId();
1128
1129 // Now that we have an island to add the CPE to, clone the original CPE and
1130 // add it to the island.
1131 U.HighWaterMark = NewIsland;
1132 U.CPEMI = BuildMI(NewIsland, DebugLoc(), TII->get(CSKY::CONSTPOOL_ENTRY))
1133 .addImm(ID)
1135 .addImm(Size);
1136 CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));
1137 ++NumCPEs;
1138
1139 // Mark the basic block as aligned as required by the const-pool entry.
1140 NewIsland->setAlignment(getCPEAlign(*U.CPEMI));
1141
1142 // Increase the size of the island block to account for the new entry.
1143 BBInfo[NewIsland->getNumber()].Size += Size;
1144 adjustBBOffsetsAfter(&*--NewIsland->getIterator());
1145
1146 // Finally, change the CPI in the instruction operand to be ID.
1147 for (unsigned I = 0, E = UserMI->getNumOperands(); I != E; ++I)
1148 if (UserMI->getOperand(I).isCPI()) {
1149 UserMI->getOperand(I).setIndex(ID);
1150 break;
1151 }
1152
1153 LLVM_DEBUG(
1154 dbgs() << " Moved CPE to #" << ID << " CPI=" << CPI
1155 << format(" offset=%#x\n", BBInfo[NewIsland->getNumber()].Offset));
1156
1157 return true;
1158}
1159
1160/// removeDeadCPEMI - Remove a dead constant pool entry instruction. Update
1161/// sizes and offsets of impacted basic blocks.
1162void CSKYConstantIslands::removeDeadCPEMI(MachineInstr *CPEMI) {
1163 MachineBasicBlock *CPEBB = CPEMI->getParent();
1164 unsigned Size = CPEMI->getOperand(2).getImm();
1165 CPEMI->eraseFromParent();
1166 BBInfo[CPEBB->getNumber()].Size -= Size;
1167 // All succeeding offsets have the current size value added in, fix this.
1168 if (CPEBB->empty()) {
1169 BBInfo[CPEBB->getNumber()].Size = 0;
1170
1171 // This block no longer needs to be aligned.
1172 CPEBB->setAlignment(Align(4));
1173 } else {
1174 // Entries are sorted by descending alignment, so realign from the front.
1175 CPEBB->setAlignment(getCPEAlign(*CPEBB->begin()));
1176 }
1177
1178 adjustBBOffsetsAfter(CPEBB);
1179 // An island has only one predecessor BB and one successor BB. Check if
1180 // this BB's predecessor jumps directly to this BB's successor. This
1181 // shouldn't happen currently.
1182 assert(!bbIsJumpedOver(CPEBB) && "How did this happen?");
1183 // FIXME: remove the empty blocks after all the work is done?
1184}
1185
1186/// removeUnusedCPEntries - Remove constant pool entries whose refcounts
1187/// are zero.
1188bool CSKYConstantIslands::removeUnusedCPEntries() {
1189 unsigned MadeChange = false;
1190 for (unsigned I = 0, E = CPEntries.size(); I != E; ++I) {
1191 std::vector<CPEntry> &CPEs = CPEntries[I];
1192 for (unsigned J = 0, Ee = CPEs.size(); J != Ee; ++J) {
1193 if (CPEs[J].RefCount == 0 && CPEs[J].CPEMI) {
1194 removeDeadCPEMI(CPEs[J].CPEMI);
1195 CPEs[J].CPEMI = nullptr;
1196 MadeChange = true;
1197 }
1198 }
1199 }
1200 return MadeChange;
1201}
1202
1203/// isBBInRange - Returns true if the distance between specific MI and
1204/// specific BB can fit in MI's displacement field.
1205bool CSKYConstantIslands::isBBInRange(MachineInstr *MI,
1206 MachineBasicBlock *DestBB,
1207 unsigned MaxDisp) {
1208 unsigned BrOffset = getOffsetOf(MI);
1209 unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
1210
1211 LLVM_DEBUG(dbgs() << "Branch of destination " << printMBBReference(*DestBB)
1212 << " from " << printMBBReference(*MI->getParent())
1213 << " max delta=" << MaxDisp << " from " << getOffsetOf(MI)
1214 << " to " << DestOffset << " offset "
1215 << int(DestOffset - BrOffset) << "\t" << *MI);
1216
1217 if (BrOffset <= DestOffset) {
1218 // Branch before the Dest.
1219 if (DestOffset - BrOffset <= MaxDisp)
1220 return true;
1221 } else {
1222 if (BrOffset - DestOffset <= MaxDisp)
1223 return true;
1224 }
1225 return false;
1226}
1227
1228/// fixupImmediateBr - Fix up an immediate branch whose destination is too far
1229/// away to fit in its displacement field.
1230bool CSKYConstantIslands::fixupImmediateBr(ImmBranch &Br) {
1231 MachineInstr *MI = Br.MI;
1232 MachineBasicBlock *DestBB = TII->getBranchDestBlock(*MI);
1233
1234 // Check to see if the DestBB is already in-range.
1235 if (isBBInRange(MI, DestBB, Br.MaxDisp))
1236 return false;
1237
1238 if (!Br.IsCond)
1239 return fixupUnconditionalBr(Br);
1240 return fixupConditionalBr(Br);
1241}
1242
1243/// fixupUnconditionalBr - Fix up an unconditional branch whose destination is
1244/// too far away to fit in its displacement field. If the LR register has been
1245/// spilled in the epilogue, then we can use BSR to implement a far jump.
1246/// Otherwise, add an intermediate branch instruction to a branch.
1247bool CSKYConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
1248 MachineInstr *MI = Br.MI;
1249 MachineBasicBlock *MBB = MI->getParent();
1250
1251 if (!MFI->isLRSpilled())
1252 report_fatal_error("underestimated function size");
1253
1254 // Use BSR to implement far jump.
1255 Br.MaxDisp = ((1 << (26 - 1)) - 1) * 2;
1256 MI->setDesc(TII->get(CSKY::BSR32_BR));
1257 BBInfo[MBB->getNumber()].Size += 4;
1258 adjustBBOffsetsAfter(MBB);
1259 ++NumUBrFixed;
1260
1261 LLVM_DEBUG(dbgs() << " Changed B to long jump " << *MI);
1262
1263 return true;
1264}
1265
1266/// fixupConditionalBr - Fix up a conditional branch whose destination is too
1267/// far away to fit in its displacement field. It is converted to an inverse
1268/// conditional branch + an unconditional branch to the destination.
1269bool CSKYConstantIslands::fixupConditionalBr(ImmBranch &Br) {
1270 MachineInstr *MI = Br.MI;
1271 MachineBasicBlock *DestBB = TII->getBranchDestBlock(*MI);
1272
1274 Cond.push_back(MachineOperand::CreateImm(MI->getOpcode()));
1275 Cond.push_back(MI->getOperand(0));
1277
1278 // Add an unconditional branch to the destination and invert the branch
1279 // condition to jump over it:
1280 // bteqz L1
1281 // =>
1282 // bnez L2
1283 // b L1
1284 // L2:
1285
1286 // If the branch is at the end of its MBB and that has a fall-through block,
1287 // direct the updated conditional branch to the fall-through block. Otherwise,
1288 // split the MBB before the next instruction.
1289 MachineBasicBlock *MBB = MI->getParent();
1290 MachineInstr *BMI = &MBB->back();
1291 bool NeedSplit = (BMI != MI) || !bbHasFallthrough(MBB);
1292
1293 ++NumCBrFixed;
1294 if (BMI != MI) {
1295 if (std::next(MachineBasicBlock::iterator(MI)) == std::prev(MBB->end()) &&
1296 BMI->isUnconditionalBranch()) {
1297 // Last MI in the BB is an unconditional branch. Can we simply invert the
1298 // condition and swap destinations:
1299 // beqz L1
1300 // b L2
1301 // =>
1302 // bnez L2
1303 // b L1
1304 MachineBasicBlock *NewDest = TII->getBranchDestBlock(*BMI);
1305 if (isBBInRange(MI, NewDest, Br.MaxDisp)) {
1306 LLVM_DEBUG(
1307 dbgs() << " Invert Bcc condition and swap its destination with "
1308 << *BMI);
1309 BMI->getOperand(BMI->getNumExplicitOperands() - 1).setMBB(DestBB);
1310 MI->getOperand(MI->getNumExplicitOperands() - 1).setMBB(NewDest);
1311
1312 MI->setDesc(TII->get(Cond[0].getImm()));
1313 return true;
1314 }
1315 }
1316 }
1317
1318 if (NeedSplit) {
1319 splitBlockBeforeInstr(*MI);
1320 // No need for the branch to the next block. We're adding an unconditional
1321 // branch to the destination.
1322 int Delta = TII->getInstSizeInBytes(MBB->back());
1323 BBInfo[MBB->getNumber()].Size -= Delta;
1325 // BBInfo[SplitBB].Offset is wrong temporarily, fixed below
1326
1327 // The conditional successor will be swapped between the BBs after this, so
1328 // update CFG.
1329 MBB->addSuccessor(DestBB);
1330 std::next(MBB->getIterator())->removeSuccessor(DestBB);
1331 }
1332 MachineBasicBlock *NextBB = &*++MBB->getIterator();
1333
1334 LLVM_DEBUG(dbgs() << " Insert B to " << printMBBReference(*DestBB)
1335 << " also invert condition and change dest. to "
1336 << printMBBReference(*NextBB) << "\n");
1337
1338 // Insert a new conditional branch and a new unconditional branch.
1339 // Also update the ImmBranch as well as adding a new entry for the new branch.
1340
1341 BuildMI(MBB, DebugLoc(), TII->get(Cond[0].getImm()))
1342 .addReg(MI->getOperand(0).getReg())
1343 .addMBB(NextBB);
1344
1345 Br.MI = &MBB->back();
1346 BBInfo[MBB->getNumber()].Size += TII->getInstSizeInBytes(MBB->back());
1347 BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB);
1348 BBInfo[MBB->getNumber()].Size += TII->getInstSizeInBytes(MBB->back());
1349 unsigned MaxDisp = getUnconditionalBrDisp(Br.UncondBr);
1350 ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr));
1351
1352 // Remove the old conditional branch. It may or may not still be in MBB.
1353 BBInfo[MI->getParent()->getNumber()].Size -= TII->getInstSizeInBytes(*MI);
1354 MI->eraseFromParent();
1355 adjustBBOffsetsAfter(MBB);
1356 return true;
1357}
1358
1359/// Returns a pass that converts branches to long branches.
1361 return new CSKYConstantIslands();
1362}
1363
1364INITIALIZE_PASS(CSKYConstantIslands, DEBUG_TYPE,
1365 "CSKY constant island placement and branch shortening pass",
1366 false, false)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static unsigned getUnconditionalBrDisp(int Opc)
getUnconditionalBrDisp - Returns the maximum displacement that can fit in the specific unconditional ...
static bool bbHasFallthrough(MachineBasicBlock *MBB)
BBHasFallthrough - Return true if the specified basic block can fallthrough into the block immediatel...
static bool bbIsJumpedOver(MachineBasicBlock *MBB)
BBIsJumpedOver - Return true of the specified basic block's only predecessor unconditionally branches...
static bool compareMbbNumbers(const MachineBasicBlock *LHS, const MachineBasicBlock *RHS)
CompareMBBNumbers - Little predicate function to sort the WaterList by MBB ID.
#define DEBUG_TYPE
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:533
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define LLVM_DEBUG(X)
Definition: Debug.h:101
uint64_t Size
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:166
Value * RHS
Value * LHS
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
A debug info location.
Definition: DebugLoc.h:33
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:310
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
unsigned pred_size() const
void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
void push_back(MachineInstr *MI)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
unsigned succ_size() const
void setAlignment(Align A)
Set alignment of the basic block.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
Align getAlignment() const
Return alignment of the basic block.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.
BasicBlockListType::const_iterator const_iterator
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
Definition: MachineInstr.h:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:569
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:346
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:572
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:579
int64_t getImm() const
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
void setMBB(MachineBasicBlock *MBB)
static MachineOperand CreateImm(int64_t Val)
void setIndex(int Idx)
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition: SmallSet.h:166
bool erase(const T &V)
Definition: SmallSet.h:207
void clear()
Definition: SmallSet.h:218
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:179
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
self_iterator getIterator()
Definition: ilist_node.h:132
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1742
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1680
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
Definition: Alignment.h:145
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:125
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition: Alignment.h:197
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1961
FunctionPass * createCSKYConstantIslandPass()
Returns a pass that converts branches to long branches.
DWARFExpression::Operation Op
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition: Alignment.h:208
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
BasicBlockInfo - Information about the offset and size of a single basic block.
unsigned Size
Size - Size of the basic block in bytes.
unsigned postOffset(Align Alignment=Align(1)) const
Compute the offset immediately following this block.
unsigned Offset
Offset - Distance from the beginning of the function to the beginning of this basic block.