Path: blob/main/contrib/llvm-project/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp
35266 views
//===- MipsConstantIslandPass.cpp - Emit Pc Relative loads ----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This pass is used to make Pc relative loads of constants.9// For now, only Mips16 will use this.10//11// Loading constants inline is expensive on Mips16 and it's in general better12// to place the constant nearby in code space and then it can be loaded with a13// simple 16 bit load instruction.14//15// The constants can be not just numbers but addresses of functions and labels.16// This can be particularly helpful in static relocation mode for embedded17// non-linux targets.18//19//===----------------------------------------------------------------------===//2021#include "Mips.h"22#include "Mips16InstrInfo.h"23#include "MipsMachineFunction.h"24#include "MipsSubtarget.h"25#include "llvm/ADT/STLExtras.h"26#include "llvm/ADT/SmallSet.h"27#include "llvm/ADT/SmallVector.h"28#include "llvm/ADT/Statistic.h"29#include "llvm/ADT/StringRef.h"30#include "llvm/CodeGen/MachineBasicBlock.h"31#include "llvm/CodeGen/MachineConstantPool.h"32#include "llvm/CodeGen/MachineFunction.h"33#include "llvm/CodeGen/MachineFunctionPass.h"34#include "llvm/CodeGen/MachineInstr.h"35#include "llvm/CodeGen/MachineInstrBuilder.h"36#include "llvm/CodeGen/MachineOperand.h"37#include "llvm/CodeGen/MachineRegisterInfo.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"44#include "llvm/Support/CommandLine.h"45#include "llvm/Support/Compiler.h"46#include "llvm/Support/Debug.h"47#include "llvm/Support/ErrorHandling.h"48#include "llvm/Support/Format.h"49#include "llvm/Support/MathExtras.h"50#include "llvm/Support/raw_ostream.h"51#include <algorithm>52#include <cassert>53#include <cstdint>54#include <iterator>55#include <vector>5657using namespace llvm;5859#define DEBUG_TYPE "mips-constant-islands"6061STATISTIC(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");6566// FIXME: This option should be removed once it has received sufficient testing.67static cl::opt<bool>68AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true),69cl::desc("Align constant islands in code"));7071// Rather than do make check tests with huge amounts of code, we force72// the test to use this amount.73static cl::opt<int> ConstantIslandsSmallOffset(74"mips-constant-islands-small-offset",75cl::init(0),76cl::desc("Make small offsets be this amount for testing purposes"),77cl::Hidden);7879// For testing purposes we tell it to not use relaxed load forms so that it80// will split blocks.81static cl::opt<bool> NoLoadRelaxation(82"mips-constant-islands-no-load-relaxation",83cl::init(false),84cl::desc("Don't relax loads to long loads - for testing purposes"),85cl::Hidden);8687static unsigned int branchTargetOperand(MachineInstr *MI) {88switch (MI->getOpcode()) {89case Mips::Bimm16:90case Mips::BimmX16:91case Mips::Bteqz16:92case Mips::BteqzX16:93case Mips::Btnez16:94case Mips::BtnezX16:95case Mips::JalB16:96return 0;97case Mips::BeqzRxImm16:98case Mips::BeqzRxImmX16:99case Mips::BnezRxImm16:100case Mips::BnezRxImmX16:101return 1;102}103llvm_unreachable("Unknown branch type");104}105106static unsigned int longformBranchOpcode(unsigned int Opcode) {107switch (Opcode) {108case Mips::Bimm16:109case Mips::BimmX16:110return Mips::BimmX16;111case Mips::Bteqz16:112case Mips::BteqzX16:113return Mips::BteqzX16;114case Mips::Btnez16:115case Mips::BtnezX16:116return Mips::BtnezX16;117case Mips::JalB16:118return Mips::JalB16;119case Mips::BeqzRxImm16:120case Mips::BeqzRxImmX16:121return Mips::BeqzRxImmX16;122case Mips::BnezRxImm16:123case Mips::BnezRxImmX16:124return Mips::BnezRxImmX16;125}126llvm_unreachable("Unknown branch type");127}128129// FIXME: need to go through this whole constant islands port and check130// the math for branch ranges and clean this up and make some functions131// to calculate things that are done many times identically.132// Need to refactor some of the code to call this routine.133static unsigned int branchMaxOffsets(unsigned int Opcode) {134unsigned Bits, Scale;135switch (Opcode) {136case Mips::Bimm16:137Bits = 11;138Scale = 2;139break;140case Mips::BimmX16:141Bits = 16;142Scale = 2;143break;144case Mips::BeqzRxImm16:145Bits = 8;146Scale = 2;147break;148case Mips::BeqzRxImmX16:149Bits = 16;150Scale = 2;151break;152case Mips::BnezRxImm16:153Bits = 8;154Scale = 2;155break;156case Mips::BnezRxImmX16:157Bits = 16;158Scale = 2;159break;160case Mips::Bteqz16:161Bits = 8;162Scale = 2;163break;164case Mips::BteqzX16:165Bits = 16;166Scale = 2;167break;168case Mips::Btnez16:169Bits = 8;170Scale = 2;171break;172case Mips::BtnezX16:173Bits = 16;174Scale = 2;175break;176default:177llvm_unreachable("Unknown branch type");178}179unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;180return MaxOffs;181}182183namespace {184185using Iter = MachineBasicBlock::iterator;186using ReverseIter = MachineBasicBlock::reverse_iterator;187188/// MipsConstantIslands - Due to limited PC-relative displacements, Mips189/// requires constant pool entries to be scattered among the instructions190/// inside a function. To do this, it completely ignores the normal LLVM191/// constant pool; instead, it places constants wherever it feels like with192/// special instructions.193///194/// The terminology used in this pass includes:195/// Islands - Clumps of constants placed in the function.196/// Water - Potential places where an island could be formed.197/// CPE - A constant pool entry that has been placed somewhere, which198/// tracks a list of users.199200class MipsConstantIslands : public MachineFunctionPass {201/// BasicBlockInfo - Information about the offset and size of a single202/// basic block.203struct BasicBlockInfo {204/// Offset - Distance from the beginning of the function to the beginning205/// of this basic block.206///207/// Offsets are computed assuming worst case padding before an aligned208/// block. This means that subtracting basic block offsets always gives a209/// conservative estimate of the real distance which may be smaller.210///211/// Because worst case padding is used, the computed offset of an aligned212/// block may not actually be aligned.213unsigned Offset = 0;214215/// Size - Size of the basic block in bytes. If the block contains216/// inline assembly, this is a worst case estimate.217///218/// The size does not include any alignment padding whether from the219/// beginning of the block, or from an aligned jump table at the end.220unsigned Size = 0;221222BasicBlockInfo() = default;223224unsigned postOffset() const { return Offset + Size; }225};226227std::vector<BasicBlockInfo> BBInfo;228229/// WaterList - A sorted list of basic blocks where islands could be placed230/// (i.e. blocks that don't fall through to the following block, due231/// to a return, unreachable, or unconditional branch).232std::vector<MachineBasicBlock*> WaterList;233234/// NewWaterList - The subset of WaterList that was created since the235/// previous iteration by inserting unconditional branches.236SmallSet<MachineBasicBlock*, 4> NewWaterList;237238using water_iterator = std::vector<MachineBasicBlock *>::iterator;239240/// CPUser - One user of a constant pool, keeping the machine instruction241/// pointer, the constant pool being referenced, and the max displacement242/// allowed from the instruction to the CP. The HighWaterMark records the243/// highest basic block where a new CPEntry can be placed. To ensure this244/// pass terminates, the CP entries are initially placed at the end of the245/// function and then move monotonically to lower addresses. The246/// exception to this rule is when the current CP entry for a particular247/// CPUser is out of range, but there is another CP entry for the same248/// constant value in range. We want to use the existing in-range CP249/// entry, but if it later moves out of range, the search for new water250/// should resume where it left off. The HighWaterMark is used to record251/// that point.252struct CPUser {253MachineInstr *MI;254MachineInstr *CPEMI;255MachineBasicBlock *HighWaterMark;256257private:258unsigned MaxDisp;259unsigned LongFormMaxDisp; // mips16 has 16/32 bit instructions260// with different displacements261unsigned LongFormOpcode;262263public:264bool NegOk;265266CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp,267bool neg,268unsigned longformmaxdisp, unsigned longformopcode)269: MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),270LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),271NegOk(neg){272HighWaterMark = CPEMI->getParent();273}274275/// getMaxDisp - Returns the maximum displacement supported by MI.276unsigned getMaxDisp() const {277unsigned xMaxDisp = ConstantIslandsSmallOffset?278ConstantIslandsSmallOffset: MaxDisp;279return xMaxDisp;280}281282void setMaxDisp(unsigned val) {283MaxDisp = val;284}285286unsigned getLongFormMaxDisp() const {287return LongFormMaxDisp;288}289290unsigned getLongFormOpcode() const {291return LongFormOpcode;292}293};294295/// CPUsers - Keep track of all of the machine instructions that use various296/// constant pools and their max displacement.297std::vector<CPUser> CPUsers;298299/// CPEntry - One per constant pool entry, keeping the machine instruction300/// pointer, the constpool index, and the number of CPUser's which301/// reference this entry.302struct CPEntry {303MachineInstr *CPEMI;304unsigned CPI;305unsigned RefCount;306307CPEntry(MachineInstr *cpemi, unsigned cpi, unsigned rc = 0)308: CPEMI(cpemi), CPI(cpi), RefCount(rc) {}309};310311/// CPEntries - Keep track of all of the constant pool entry machine312/// instructions. For each original constpool index (i.e. those that313/// existed upon entry to this pass), it keeps a vector of entries.314/// Original elements are cloned as we go along; the clones are315/// put in the vector of the original element, but have distinct CPIs.316std::vector<std::vector<CPEntry>> CPEntries;317318/// ImmBranch - One per immediate branch, keeping the machine instruction319/// pointer, conditional or unconditional, the max displacement,320/// and (if isCond is true) the corresponding unconditional branch321/// opcode.322struct ImmBranch {323MachineInstr *MI;324unsigned MaxDisp : 31;325bool isCond : 1;326int UncondBr;327328ImmBranch(MachineInstr *mi, unsigned maxdisp, bool cond, int ubr)329: MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}330};331332/// ImmBranches - Keep track of all the immediate branch instructions.333///334std::vector<ImmBranch> ImmBranches;335336/// HasFarJump - True if any far jump instruction has been emitted during337/// the branch fix up pass.338bool HasFarJump;339340const MipsSubtarget *STI = nullptr;341const Mips16InstrInfo *TII;342MipsFunctionInfo *MFI;343MachineFunction *MF = nullptr;344MachineConstantPool *MCP = nullptr;345346unsigned PICLabelUId;347bool PrescannedForConstants = false;348349void initPICLabelUId(unsigned UId) {350PICLabelUId = UId;351}352353unsigned createPICLabelUId() {354return PICLabelUId++;355}356357public:358static char ID;359360MipsConstantIslands() : MachineFunctionPass(ID) {}361362StringRef getPassName() const override { return "Mips Constant Islands"; }363364bool runOnMachineFunction(MachineFunction &F) override;365366MachineFunctionProperties getRequiredProperties() const override {367return MachineFunctionProperties().set(368MachineFunctionProperties::Property::NoVRegs);369}370371void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);372CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI);373Align getCPEAlign(const MachineInstr &CPEMI);374void initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs);375unsigned getOffsetOf(MachineInstr *MI) const;376unsigned getUserOffset(CPUser&) const;377void dumpBBs();378379bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,380unsigned Disp, bool NegativeOK);381bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,382const CPUser &U);383384void computeBlockSize(MachineBasicBlock *MBB);385MachineBasicBlock *splitBlockBeforeInstr(MachineInstr &MI);386void updateForInsertedWaterBlock(MachineBasicBlock *NewBB);387void adjustBBOffsetsAfter(MachineBasicBlock *BB);388bool decrementCPEReferenceCount(unsigned CPI, MachineInstr* CPEMI);389int findInRangeCPEntry(CPUser& U, unsigned UserOffset);390int findLongFormInRangeCPEntry(CPUser& U, unsigned UserOffset);391bool findAvailableWater(CPUser&U, unsigned UserOffset,392water_iterator &WaterIter);393void createNewWater(unsigned CPUserIndex, unsigned UserOffset,394MachineBasicBlock *&NewMBB);395bool handleConstantPoolUser(unsigned CPUserIndex);396void removeDeadCPEMI(MachineInstr *CPEMI);397bool removeUnusedCPEntries();398bool isCPEntryInRange(MachineInstr *MI, unsigned UserOffset,399MachineInstr *CPEMI, unsigned Disp, bool NegOk,400bool DoDump = false);401bool isWaterInRange(unsigned UserOffset, MachineBasicBlock *Water,402CPUser &U, unsigned &Growth);403bool isBBInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp);404bool fixupImmediateBr(ImmBranch &Br);405bool fixupConditionalBr(ImmBranch &Br);406bool fixupUnconditionalBr(ImmBranch &Br);407408void prescanForConstants();409};410411} // end anonymous namespace412413char MipsConstantIslands::ID = 0;414415bool MipsConstantIslands::isOffsetInRange416(unsigned UserOffset, unsigned TrialOffset,417const CPUser &U) {418return isOffsetInRange(UserOffset, TrialOffset,419U.getMaxDisp(), U.NegOk);420}421422#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)423/// print block size and offset information - debugging424LLVM_DUMP_METHOD void MipsConstantIslands::dumpBBs() {425for (unsigned J = 0, E = BBInfo.size(); J !=E; ++J) {426const BasicBlockInfo &BBI = BBInfo[J];427dbgs() << format("%08x %bb.%u\t", BBI.Offset, J)428<< format(" size=%#x\n", BBInfo[J].Size);429}430}431#endif432433bool MipsConstantIslands::runOnMachineFunction(MachineFunction &mf) {434// The intention is for this to be a mips16 only pass for now435// FIXME:436MF = &mf;437MCP = mf.getConstantPool();438STI = &mf.getSubtarget<MipsSubtarget>();439LLVM_DEBUG(dbgs() << "constant island machine function "440<< "\n");441if (!STI->inMips16Mode() || !MipsSubtarget::useConstantIslands()) {442return false;443}444TII = (const Mips16InstrInfo *)STI->getInstrInfo();445MFI = MF->getInfo<MipsFunctionInfo>();446LLVM_DEBUG(dbgs() << "constant island processing "447<< "\n");448//449// will need to make predermination if there is any constants we need to450// put in constant islands. TBD.451//452if (!PrescannedForConstants) prescanForConstants();453454HasFarJump = false;455// This pass invalidates liveness information when it splits basic blocks.456MF->getRegInfo().invalidateLiveness();457458// Renumber all of the machine basic blocks in the function, guaranteeing that459// the numbers agree with the position of the block in the function.460MF->RenumberBlocks();461462bool MadeChange = false;463464// Perform the initial placement of the constant pool entries. To start with,465// we put them all at the end of the function.466std::vector<MachineInstr*> CPEMIs;467if (!MCP->isEmpty())468doInitialPlacement(CPEMIs);469470/// The next UID to take is the first unused one.471initPICLabelUId(CPEMIs.size());472473// Do the initial scan of the function, building up information about the474// sizes of each block, the location of all the water, and finding all of the475// constant pool users.476initializeFunctionInfo(CPEMIs);477CPEMIs.clear();478LLVM_DEBUG(dumpBBs());479480/// Remove dead constant pool entries.481MadeChange |= removeUnusedCPEntries();482483// Iteratively place constant pool entries and fix up branches until there484// is no change.485unsigned NoCPIters = 0, NoBRIters = 0;486(void)NoBRIters;487while (true) {488LLVM_DEBUG(dbgs() << "Beginning CP iteration #" << NoCPIters << '\n');489bool CPChange = false;490for (unsigned i = 0, e = CPUsers.size(); i != e; ++i)491CPChange |= handleConstantPoolUser(i);492if (CPChange && ++NoCPIters > 30)493report_fatal_error("Constant Island pass failed to converge!");494LLVM_DEBUG(dumpBBs());495496// Clear NewWaterList now. If we split a block for branches, it should497// appear as "new water" for the next iteration of constant pool placement.498NewWaterList.clear();499500LLVM_DEBUG(dbgs() << "Beginning BR iteration #" << NoBRIters << '\n');501bool BRChange = false;502for (unsigned i = 0, e = ImmBranches.size(); i != e; ++i)503BRChange |= fixupImmediateBr(ImmBranches[i]);504if (BRChange && ++NoBRIters > 30)505report_fatal_error("Branch Fix Up pass failed to converge!");506LLVM_DEBUG(dumpBBs());507if (!CPChange && !BRChange)508break;509MadeChange = true;510}511512LLVM_DEBUG(dbgs() << '\n'; dumpBBs());513514BBInfo.clear();515WaterList.clear();516CPUsers.clear();517CPEntries.clear();518ImmBranches.clear();519return MadeChange;520}521522/// doInitialPlacement - Perform the initial placement of the constant pool523/// entries. To start with, we put them all at the end of the function.524void525MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {526// Create the basic block to hold the CPE's.527MachineBasicBlock *BB = MF->CreateMachineBasicBlock();528MF->push_back(BB);529530// MachineConstantPool measures alignment in bytes. We measure in log2(bytes).531const Align MaxAlign = MCP->getConstantPoolAlign();532533// Mark the basic block as required by the const-pool.534// If AlignConstantIslands isn't set, use 4-byte alignment for everything.535BB->setAlignment(AlignConstantIslands ? MaxAlign : Align(4));536537// The function needs to be as aligned as the basic blocks. The linker may538// move functions around based on their alignment.539MF->ensureAlignment(BB->getAlignment());540541// Order the entries in BB by descending alignment. That ensures correct542// alignment of all entries as long as BB is sufficiently aligned. Keep543// track of the insertion point for each alignment. We are going to bucket544// sort the entries as they are created.545SmallVector<MachineBasicBlock::iterator, 8> InsPoint(Log2(MaxAlign) + 1,546BB->end());547548// Add all of the constants from the constant pool to the end block, use an549// identity mapping of CPI's to CPE's.550const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();551552const DataLayout &TD = MF->getDataLayout();553for (unsigned i = 0, e = CPs.size(); i != e; ++i) {554unsigned Size = CPs[i].getSizeInBytes(TD);555assert(Size >= 4 && "Too small constant pool entry");556Align Alignment = CPs[i].getAlign();557// Verify that all constant pool entries are a multiple of their alignment.558// If not, we would have to pad them out so that instructions stay aligned.559assert(isAligned(Alignment, Size) && "CP Entry not multiple of 4 bytes!");560561// Insert CONSTPOOL_ENTRY before entries with a smaller alignment.562unsigned LogAlign = Log2(Alignment);563MachineBasicBlock::iterator InsAt = InsPoint[LogAlign];564565MachineInstr *CPEMI =566BuildMI(*BB, InsAt, DebugLoc(), TII->get(Mips::CONSTPOOL_ENTRY))567.addImm(i).addConstantPoolIndex(i).addImm(Size);568569CPEMIs.push_back(CPEMI);570571// Ensure that future entries with higher alignment get inserted before572// CPEMI. This is bucket sort with iterators.573for (unsigned a = LogAlign + 1; a <= Log2(MaxAlign); ++a)574if (InsPoint[a] == InsAt)575InsPoint[a] = CPEMI;576// Add a new CPEntry, but no corresponding CPUser yet.577CPEntries.emplace_back(1, CPEntry(CPEMI, i));578++NumCPEs;579LLVM_DEBUG(dbgs() << "Moved CPI#" << i << " to end of function, size = "580<< Size << ", align = " << Alignment.value() << '\n');581}582LLVM_DEBUG(BB->dump());583}584585/// BBHasFallthrough - Return true if the specified basic block can fallthrough586/// into the block immediately after it.587static bool BBHasFallthrough(MachineBasicBlock *MBB) {588// Get the next machine basic block in the function.589MachineFunction::iterator MBBI = MBB->getIterator();590// Can't fall off end of function.591if (std::next(MBBI) == MBB->getParent()->end())592return false;593594MachineBasicBlock *NextBB = &*std::next(MBBI);595return llvm::is_contained(MBB->successors(), NextBB);596}597598/// findConstPoolEntry - Given the constpool index and CONSTPOOL_ENTRY MI,599/// look up the corresponding CPEntry.600MipsConstantIslands::CPEntry601*MipsConstantIslands::findConstPoolEntry(unsigned CPI,602const MachineInstr *CPEMI) {603std::vector<CPEntry> &CPEs = CPEntries[CPI];604// Number of entries per constpool index should be small, just do a605// linear search.606for (CPEntry &CPE : CPEs) {607if (CPE.CPEMI == CPEMI)608return &CPE;609}610return nullptr;611}612613/// getCPEAlign - Returns the required alignment of the constant pool entry614/// represented by CPEMI. Alignment is measured in log2(bytes) units.615Align MipsConstantIslands::getCPEAlign(const MachineInstr &CPEMI) {616assert(CPEMI.getOpcode() == Mips::CONSTPOOL_ENTRY);617618// Everything is 4-byte aligned unless AlignConstantIslands is set.619if (!AlignConstantIslands)620return Align(4);621622unsigned CPI = CPEMI.getOperand(1).getIndex();623assert(CPI < MCP->getConstants().size() && "Invalid constant pool index.");624return MCP->getConstants()[CPI].getAlign();625}626627/// initializeFunctionInfo - Do the initial scan of the function, building up628/// information about the sizes of each block, the location of all the water,629/// and finding all of the constant pool users.630void MipsConstantIslands::631initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {632BBInfo.clear();633BBInfo.resize(MF->getNumBlockIDs());634635// First thing, compute the size of all basic blocks, and see if the function636// has any inline assembly in it. If so, we have to be conservative about637// alignment assumptions, as we don't know for sure the size of any638// instructions in the inline assembly.639for (MachineBasicBlock &MBB : *MF)640computeBlockSize(&MBB);641642// Compute block offsets.643adjustBBOffsetsAfter(&MF->front());644645// Now go back through the instructions and build up our data structures.646for (MachineBasicBlock &MBB : *MF) {647// If this block doesn't fall through into the next MBB, then this is648// 'water' that a constant pool island could be placed.649if (!BBHasFallthrough(&MBB))650WaterList.push_back(&MBB);651for (MachineInstr &MI : MBB) {652if (MI.isDebugInstr())653continue;654655int Opc = MI.getOpcode();656if (MI.isBranch()) {657bool isCond = false;658unsigned Bits = 0;659unsigned Scale = 1;660int UOpc = Opc;661switch (Opc) {662default:663continue; // Ignore other branches for now664case Mips::Bimm16:665Bits = 11;666Scale = 2;667isCond = false;668break;669case Mips::BimmX16:670Bits = 16;671Scale = 2;672isCond = false;673break;674case Mips::BeqzRxImm16:675UOpc=Mips::Bimm16;676Bits = 8;677Scale = 2;678isCond = true;679break;680case Mips::BeqzRxImmX16:681UOpc=Mips::Bimm16;682Bits = 16;683Scale = 2;684isCond = true;685break;686case Mips::BnezRxImm16:687UOpc=Mips::Bimm16;688Bits = 8;689Scale = 2;690isCond = true;691break;692case Mips::BnezRxImmX16:693UOpc=Mips::Bimm16;694Bits = 16;695Scale = 2;696isCond = true;697break;698case Mips::Bteqz16:699UOpc=Mips::Bimm16;700Bits = 8;701Scale = 2;702isCond = true;703break;704case Mips::BteqzX16:705UOpc=Mips::Bimm16;706Bits = 16;707Scale = 2;708isCond = true;709break;710case Mips::Btnez16:711UOpc=Mips::Bimm16;712Bits = 8;713Scale = 2;714isCond = true;715break;716case Mips::BtnezX16:717UOpc=Mips::Bimm16;718Bits = 16;719Scale = 2;720isCond = true;721break;722}723// Record this immediate branch.724unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;725ImmBranches.push_back(ImmBranch(&MI, MaxOffs, isCond, UOpc));726}727728if (Opc == Mips::CONSTPOOL_ENTRY)729continue;730731// Scan the instructions for constant pool operands.732for (const MachineOperand &MO : MI.operands())733if (MO.isCPI()) {734// We found one. The addressing mode tells us the max displacement735// from the PC that this instruction permits.736737// Basic size info comes from the TSFlags field.738unsigned Bits = 0;739unsigned Scale = 1;740bool NegOk = false;741unsigned LongFormBits = 0;742unsigned LongFormScale = 0;743unsigned LongFormOpcode = 0;744switch (Opc) {745default:746llvm_unreachable("Unknown addressing mode for CP reference!");747case Mips::LwRxPcTcp16:748Bits = 8;749Scale = 4;750LongFormOpcode = Mips::LwRxPcTcpX16;751LongFormBits = 14;752LongFormScale = 1;753break;754case Mips::LwRxPcTcpX16:755Bits = 14;756Scale = 1;757NegOk = true;758break;759}760// Remember that this is a user of a CP entry.761unsigned CPI = MO.getIndex();762MachineInstr *CPEMI = CPEMIs[CPI];763unsigned MaxOffs = ((1 << Bits)-1) * Scale;764unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;765CPUsers.push_back(CPUser(&MI, CPEMI, MaxOffs, NegOk, LongFormMaxOffs,766LongFormOpcode));767768// Increment corresponding CPEntry reference count.769CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);770assert(CPE && "Cannot find a corresponding CPEntry!");771CPE->RefCount++;772773// Instructions can only use one CP entry, don't bother scanning the774// rest of the operands.775break;776}777}778}779}780781/// computeBlockSize - Compute the size and some alignment information for MBB.782/// This function updates BBInfo directly.783void MipsConstantIslands::computeBlockSize(MachineBasicBlock *MBB) {784BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];785BBI.Size = 0;786787for (const MachineInstr &MI : *MBB)788BBI.Size += TII->getInstSizeInBytes(MI);789}790791/// getOffsetOf - Return the current offset of the specified machine instruction792/// from the start of the function. This offset changes as stuff is moved793/// around inside the function.794unsigned MipsConstantIslands::getOffsetOf(MachineInstr *MI) const {795MachineBasicBlock *MBB = MI->getParent();796797// The offset is composed of two things: the sum of the sizes of all MBB's798// before this instruction's block, and the offset from the start of the block799// it is in.800unsigned Offset = BBInfo[MBB->getNumber()].Offset;801802// Sum instructions before MI in MBB.803for (MachineBasicBlock::iterator I = MBB->begin(); &*I != MI; ++I) {804assert(I != MBB->end() && "Didn't find MI in its own basic block?");805Offset += TII->getInstSizeInBytes(*I);806}807return Offset;808}809810/// CompareMBBNumbers - Little predicate function to sort the WaterList by MBB811/// ID.812static bool CompareMBBNumbers(const MachineBasicBlock *LHS,813const MachineBasicBlock *RHS) {814return LHS->getNumber() < RHS->getNumber();815}816817/// updateForInsertedWaterBlock - When a block is newly inserted into the818/// machine function, it upsets all of the block numbers. Renumber the blocks819/// and update the arrays that parallel this numbering.820void MipsConstantIslands::updateForInsertedWaterBlock821(MachineBasicBlock *NewBB) {822// Renumber the MBB's to keep them consecutive.823NewBB->getParent()->RenumberBlocks(NewBB);824825// Insert an entry into BBInfo to align it properly with the (newly826// renumbered) block numbers.827BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());828829// Next, update WaterList. Specifically, we need to add NewMBB as having830// available water after it.831water_iterator IP = llvm::lower_bound(WaterList, NewBB, CompareMBBNumbers);832WaterList.insert(IP, NewBB);833}834835unsigned MipsConstantIslands::getUserOffset(CPUser &U) const {836return getOffsetOf(U.MI);837}838839/// Split the basic block containing MI into two blocks, which are joined by840/// an unconditional branch. Update data structures and renumber blocks to841/// account for this change and returns the newly created block.842MachineBasicBlock *843MipsConstantIslands::splitBlockBeforeInstr(MachineInstr &MI) {844MachineBasicBlock *OrigBB = MI.getParent();845846// Create a new MBB for the code after the OrigBB.847MachineBasicBlock *NewBB =848MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());849MachineFunction::iterator MBBI = ++OrigBB->getIterator();850MF->insert(MBBI, NewBB);851852// Splice the instructions starting with MI over to NewBB.853NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end());854855// Add an unconditional branch from OrigBB to NewBB.856// Note the new unconditional branch is not being recorded.857// There doesn't seem to be meaningful DebugInfo available; this doesn't858// correspond to anything in the source.859BuildMI(OrigBB, DebugLoc(), TII->get(Mips::Bimm16)).addMBB(NewBB);860++NumSplit;861862// Update the CFG. All succs of OrigBB are now succs of NewBB.863NewBB->transferSuccessors(OrigBB);864865// OrigBB branches to NewBB.866OrigBB->addSuccessor(NewBB);867868// Update internal data structures to account for the newly inserted MBB.869// This is almost the same as updateForInsertedWaterBlock, except that870// the Water goes after OrigBB, not NewBB.871MF->RenumberBlocks(NewBB);872873// Insert an entry into BBInfo to align it properly with the (newly874// renumbered) block numbers.875BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());876877// Next, update WaterList. Specifically, we need to add OrigMBB as having878// available water after it (but not if it's already there, which happens879// when splitting before a conditional branch that is followed by an880// unconditional branch - in that case we want to insert NewBB).881water_iterator IP = llvm::lower_bound(WaterList, OrigBB, CompareMBBNumbers);882MachineBasicBlock* WaterBB = *IP;883if (WaterBB == OrigBB)884WaterList.insert(std::next(IP), NewBB);885else886WaterList.insert(IP, OrigBB);887NewWaterList.insert(OrigBB);888889// Figure out how large the OrigBB is. As the first half of the original890// block, it cannot contain a tablejump. The size includes891// the new jump we added. (It should be possible to do this without892// recounting everything, but it's very confusing, and this is rarely893// executed.)894computeBlockSize(OrigBB);895896// Figure out how large the NewMBB is. As the second half of the original897// block, it may contain a tablejump.898computeBlockSize(NewBB);899900// All BBOffsets following these blocks must be modified.901adjustBBOffsetsAfter(OrigBB);902903return NewBB;904}905906/// isOffsetInRange - Checks whether UserOffset (the location of a constant pool907/// reference) is within MaxDisp of TrialOffset (a proposed location of a908/// constant pool entry).909bool MipsConstantIslands::isOffsetInRange(unsigned UserOffset,910unsigned TrialOffset, unsigned MaxDisp,911bool NegativeOK) {912if (UserOffset <= TrialOffset) {913// User before the Trial.914if (TrialOffset - UserOffset <= MaxDisp)915return true;916} else if (NegativeOK) {917if (UserOffset - TrialOffset <= MaxDisp)918return true;919}920return false;921}922923/// isWaterInRange - Returns true if a CPE placed after the specified924/// Water (a basic block) will be in range for the specific MI.925///926/// Compute how much the function will grow by inserting a CPE after Water.927bool MipsConstantIslands::isWaterInRange(unsigned UserOffset,928MachineBasicBlock* Water, CPUser &U,929unsigned &Growth) {930unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset();931unsigned NextBlockOffset;932Align NextBlockAlignment;933MachineFunction::const_iterator NextBlock = ++Water->getIterator();934if (NextBlock == MF->end()) {935NextBlockOffset = BBInfo[Water->getNumber()].postOffset();936NextBlockAlignment = Align(1);937} else {938NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;939NextBlockAlignment = NextBlock->getAlignment();940}941unsigned Size = U.CPEMI->getOperand(2).getImm();942unsigned CPEEnd = CPEOffset + Size;943944// The CPE may be able to hide in the alignment padding before the next945// block. It may also cause more padding to be required if it is more aligned946// that the next block.947if (CPEEnd > NextBlockOffset) {948Growth = CPEEnd - NextBlockOffset;949// Compute the padding that would go at the end of the CPE to align the next950// block.951Growth += offsetToAlignment(CPEEnd, NextBlockAlignment);952953// If the CPE is to be inserted before the instruction, that will raise954// the offset of the instruction. Also account for unknown alignment padding955// in blocks between CPE and the user.956if (CPEOffset < UserOffset)957UserOffset += Growth;958} else959// CPE fits in existing padding.960Growth = 0;961962return isOffsetInRange(UserOffset, CPEOffset, U);963}964965/// isCPEntryInRange - Returns true if the distance between specific MI and966/// specific ConstPool entry instruction can fit in MI's displacement field.967bool MipsConstantIslands::isCPEntryInRange968(MachineInstr *MI, unsigned UserOffset,969MachineInstr *CPEMI, unsigned MaxDisp,970bool NegOk, bool DoDump) {971unsigned CPEOffset = getOffsetOf(CPEMI);972973if (DoDump) {974LLVM_DEBUG({975unsigned Block = MI->getParent()->getNumber();976const BasicBlockInfo &BBI = BBInfo[Block];977dbgs() << "User of CPE#" << CPEMI->getOperand(0).getImm()978<< " max delta=" << MaxDisp979<< format(" insn address=%#x", UserOffset) << " in "980<< printMBBReference(*MI->getParent()) << ": "981<< format("%#x-%x\t", BBI.Offset, BBI.postOffset()) << *MI982<< format("CPE address=%#x offset=%+d: ", CPEOffset,983int(CPEOffset - UserOffset));984});985}986987return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);988}989990#ifndef NDEBUG991/// BBIsJumpedOver - Return true of the specified basic block's only predecessor992/// unconditionally branches to its only successor.993static bool BBIsJumpedOver(MachineBasicBlock *MBB) {994if (MBB->pred_size() != 1 || MBB->succ_size() != 1)995return false;996MachineBasicBlock *Succ = *MBB->succ_begin();997MachineBasicBlock *Pred = *MBB->pred_begin();998MachineInstr *PredMI = &Pred->back();999if (PredMI->getOpcode() == Mips::Bimm16)1000return PredMI->getOperand(0).getMBB() == Succ;1001return false;1002}1003#endif10041005void MipsConstantIslands::adjustBBOffsetsAfter(MachineBasicBlock *BB) {1006unsigned BBNum = BB->getNumber();1007for(unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++i) {1008// Get the offset and known bits at the end of the layout predecessor.1009// Include the alignment of the current block.1010unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;1011BBInfo[i].Offset = Offset;1012}1013}10141015/// decrementCPEReferenceCount - find the constant pool entry with index CPI1016/// and instruction CPEMI, and decrement its refcount. If the refcount1017/// becomes 0 remove the entry and instruction. Returns true if we removed1018/// the entry, false if we didn't.1019bool MipsConstantIslands::decrementCPEReferenceCount(unsigned CPI,1020MachineInstr *CPEMI) {1021// Find the old entry. Eliminate it if it is no longer used.1022CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);1023assert(CPE && "Unexpected!");1024if (--CPE->RefCount == 0) {1025removeDeadCPEMI(CPEMI);1026CPE->CPEMI = nullptr;1027--NumCPEs;1028return true;1029}1030return false;1031}10321033/// LookForCPEntryInRange - see if the currently referenced CPE is in range;1034/// if not, see if an in-range clone of the CPE is in range, and if so,1035/// change the data structures so the user references the clone. Returns:1036/// 0 = no existing entry found1037/// 1 = entry found, and there were no code insertions or deletions1038/// 2 = entry found, and there were code insertions or deletions1039int MipsConstantIslands::findInRangeCPEntry(CPUser& U, unsigned UserOffset)1040{1041MachineInstr *UserMI = U.MI;1042MachineInstr *CPEMI = U.CPEMI;10431044// Check to see if the CPE is already in-range.1045if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk,1046true)) {1047LLVM_DEBUG(dbgs() << "In range\n");1048return 1;1049}10501051// No. Look for previously created clones of the CPE that are in range.1052unsigned CPI = CPEMI->getOperand(1).getIndex();1053std::vector<CPEntry> &CPEs = CPEntries[CPI];1054for (CPEntry &CPE : CPEs) {1055// We already tried this one1056if (CPE.CPEMI == CPEMI)1057continue;1058// Removing CPEs can leave empty entries, skip1059if (CPE.CPEMI == nullptr)1060continue;1061if (isCPEntryInRange(UserMI, UserOffset, CPE.CPEMI, U.getMaxDisp(),1062U.NegOk)) {1063LLVM_DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#" << CPE.CPI1064<< "\n");1065// Point the CPUser node to the replacement1066U.CPEMI = CPE.CPEMI;1067// Change the CPI in the instruction operand to refer to the clone.1068for (MachineOperand &MO : UserMI->operands())1069if (MO.isCPI()) {1070MO.setIndex(CPE.CPI);1071break;1072}1073// Adjust the refcount of the clone...1074CPE.RefCount++;1075// ...and the original. If we didn't remove the old entry, none of the1076// addresses changed, so we don't need another pass.1077return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;1078}1079}1080return 0;1081}10821083/// LookForCPEntryInRange - see if the currently referenced CPE is in range;1084/// This version checks if the longer form of the instruction can be used to1085/// to satisfy things.1086/// if not, see if an in-range clone of the CPE is in range, and if so,1087/// change the data structures so the user references the clone. Returns:1088/// 0 = no existing entry found1089/// 1 = entry found, and there were no code insertions or deletions1090/// 2 = entry found, and there were code insertions or deletions1091int MipsConstantIslands::findLongFormInRangeCPEntry1092(CPUser& U, unsigned UserOffset)1093{1094MachineInstr *UserMI = U.MI;1095MachineInstr *CPEMI = U.CPEMI;10961097// Check to see if the CPE is already in-range.1098if (isCPEntryInRange(UserMI, UserOffset, CPEMI,1099U.getLongFormMaxDisp(), U.NegOk,1100true)) {1101LLVM_DEBUG(dbgs() << "In range\n");1102UserMI->setDesc(TII->get(U.getLongFormOpcode()));1103U.setMaxDisp(U.getLongFormMaxDisp());1104return 2; // instruction is longer length now1105}11061107// No. Look for previously created clones of the CPE that are in range.1108unsigned CPI = CPEMI->getOperand(1).getIndex();1109std::vector<CPEntry> &CPEs = CPEntries[CPI];1110for (CPEntry &CPE : CPEs) {1111// We already tried this one1112if (CPE.CPEMI == CPEMI)1113continue;1114// Removing CPEs can leave empty entries, skip1115if (CPE.CPEMI == nullptr)1116continue;1117if (isCPEntryInRange(UserMI, UserOffset, CPE.CPEMI, U.getLongFormMaxDisp(),1118U.NegOk)) {1119LLVM_DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#" << CPE.CPI1120<< "\n");1121// Point the CPUser node to the replacement1122U.CPEMI = CPE.CPEMI;1123// Change the CPI in the instruction operand to refer to the clone.1124for (MachineOperand &MO : UserMI->operands())1125if (MO.isCPI()) {1126MO.setIndex(CPE.CPI);1127break;1128}1129// Adjust the refcount of the clone...1130CPE.RefCount++;1131// ...and the original. If we didn't remove the old entry, none of the1132// addresses changed, so we don't need another pass.1133return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;1134}1135}1136return 0;1137}11381139/// getUnconditionalBrDisp - Returns the maximum displacement that can fit in1140/// the specific unconditional branch instruction.1141static inline unsigned getUnconditionalBrDisp(int Opc) {1142switch (Opc) {1143case Mips::Bimm16:1144return ((1<<10)-1)*2;1145case Mips::BimmX16:1146return ((1<<16)-1)*2;1147default:1148break;1149}1150return ((1<<16)-1)*2;1151}11521153/// findAvailableWater - Look for an existing entry in the WaterList in which1154/// we can place the CPE referenced from U so it's within range of U's MI.1155/// Returns true if found, false if not. If it returns true, WaterIter1156/// is set to the WaterList entry.1157/// To ensure that this pass1158/// terminates, the CPE location for a particular CPUser is only allowed to1159/// move to a lower address, so search backward from the end of the list and1160/// prefer the first water that is in range.1161bool MipsConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset,1162water_iterator &WaterIter) {1163if (WaterList.empty())1164return false;11651166unsigned BestGrowth = ~0u;1167for (water_iterator IP = std::prev(WaterList.end()), B = WaterList.begin();;1168--IP) {1169MachineBasicBlock* WaterBB = *IP;1170// Check if water is in range and is either at a lower address than the1171// current "high water mark" or a new water block that was created since1172// the previous iteration by inserting an unconditional branch. In the1173// latter case, we want to allow resetting the high water mark back to1174// this new water since we haven't seen it before. Inserting branches1175// should be relatively uncommon and when it does happen, we want to be1176// sure to take advantage of it for all the CPEs near that block, so that1177// we don't insert more branches than necessary.1178unsigned Growth;1179if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&1180(WaterBB->getNumber() < U.HighWaterMark->getNumber() ||1181NewWaterList.count(WaterBB)) && Growth < BestGrowth) {1182// This is the least amount of required padding seen so far.1183BestGrowth = Growth;1184WaterIter = IP;1185LLVM_DEBUG(dbgs() << "Found water after " << printMBBReference(*WaterBB)1186<< " Growth=" << Growth << '\n');11871188// Keep looking unless it is perfect.1189if (BestGrowth == 0)1190return true;1191}1192if (IP == B)1193break;1194}1195return BestGrowth != ~0u;1196}11971198/// createNewWater - No existing WaterList entry will work for1199/// CPUsers[CPUserIndex], so create a place to put the CPE. The end of the1200/// block is used if in range, and the conditional branch munged so control1201/// flow is correct. Otherwise the block is split to create a hole with an1202/// unconditional branch around it. In either case NewMBB is set to a1203/// block following which the new island can be inserted (the WaterList1204/// is not adjusted).1205void MipsConstantIslands::createNewWater(unsigned CPUserIndex,1206unsigned UserOffset,1207MachineBasicBlock *&NewMBB) {1208CPUser &U = CPUsers[CPUserIndex];1209MachineInstr *UserMI = U.MI;1210MachineInstr *CPEMI = U.CPEMI;1211MachineBasicBlock *UserMBB = UserMI->getParent();1212const BasicBlockInfo &UserBBI = BBInfo[UserMBB->getNumber()];12131214// If the block does not end in an unconditional branch already, and if the1215// end of the block is within range, make new water there.1216if (BBHasFallthrough(UserMBB)) {1217// Size of branch to insert.1218unsigned Delta = 2;1219// Compute the offset where the CPE will begin.1220unsigned CPEOffset = UserBBI.postOffset() + Delta;12211222if (isOffsetInRange(UserOffset, CPEOffset, U)) {1223LLVM_DEBUG(dbgs() << "Split at end of " << printMBBReference(*UserMBB)1224<< format(", expected CPE offset %#x\n", CPEOffset));1225NewMBB = &*++UserMBB->getIterator();1226// Add an unconditional branch from UserMBB to fallthrough block. Record1227// it for branch lengthening; this new branch will not get out of range,1228// but if the preceding conditional branch is out of range, the targets1229// will be exchanged, and the altered branch may be out of range, so the1230// machinery has to know about it.1231int UncondBr = Mips::Bimm16;1232BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB);1233unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);1234ImmBranches.push_back(ImmBranch(&UserMBB->back(),1235MaxDisp, false, UncondBr));1236BBInfo[UserMBB->getNumber()].Size += Delta;1237adjustBBOffsetsAfter(UserMBB);1238return;1239}1240}12411242// What a big block. Find a place within the block to split it.12431244// Try to split the block so it's fully aligned. Compute the latest split1245// point where we can add a 4-byte branch instruction, and then align to1246// Align which is the largest possible alignment in the function.1247const Align Align = MF->getAlignment();1248unsigned BaseInsertOffset = UserOffset + U.getMaxDisp();1249LLVM_DEBUG(dbgs() << format("Split in middle of big block before %#x",1250BaseInsertOffset));12511252// The 4 in the following is for the unconditional branch we'll be inserting1253// Alignment of the island is handled1254// inside isOffsetInRange.1255BaseInsertOffset -= 4;12561257LLVM_DEBUG(dbgs() << format(", adjusted to %#x", BaseInsertOffset)1258<< " la=" << Log2(Align) << '\n');12591260// This could point off the end of the block if we've already got constant1261// pool entries following this block; only the last one is in the water list.1262// Back past any possible branches (allow for a conditional and a maximally1263// long unconditional).1264if (BaseInsertOffset + 8 >= UserBBI.postOffset()) {1265BaseInsertOffset = UserBBI.postOffset() - 8;1266LLVM_DEBUG(dbgs() << format("Move inside block: %#x\n", BaseInsertOffset));1267}1268unsigned EndInsertOffset = BaseInsertOffset + 4 +1269CPEMI->getOperand(2).getImm();1270MachineBasicBlock::iterator MI = UserMI;1271++MI;1272unsigned CPUIndex = CPUserIndex+1;1273unsigned NumCPUsers = CPUsers.size();1274//MachineInstr *LastIT = 0;1275for (unsigned Offset = UserOffset + TII->getInstSizeInBytes(*UserMI);1276Offset < BaseInsertOffset;1277Offset += TII->getInstSizeInBytes(*MI), MI = std::next(MI)) {1278assert(MI != UserMBB->end() && "Fell off end of block");1279if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {1280CPUser &U = CPUsers[CPUIndex];1281if (!isOffsetInRange(Offset, EndInsertOffset, U)) {1282// Shift intertion point by one unit of alignment so it is within reach.1283BaseInsertOffset -= Align.value();1284EndInsertOffset -= Align.value();1285}1286// This is overly conservative, as we don't account for CPEMIs being1287// reused within the block, but it doesn't matter much. Also assume CPEs1288// are added in order with alignment padding. We may eventually be able1289// to pack the aligned CPEs better.1290EndInsertOffset += U.CPEMI->getOperand(2).getImm();1291CPUIndex++;1292}1293}12941295NewMBB = splitBlockBeforeInstr(*--MI);1296}12971298/// handleConstantPoolUser - Analyze the specified user, checking to see if it1299/// is out-of-range. If so, pick up the constant pool value and move it some1300/// place in-range. Return true if we changed any addresses (thus must run1301/// another pass of branch lengthening), false otherwise.1302bool MipsConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) {1303CPUser &U = CPUsers[CPUserIndex];1304MachineInstr *UserMI = U.MI;1305MachineInstr *CPEMI = U.CPEMI;1306unsigned CPI = CPEMI->getOperand(1).getIndex();1307unsigned Size = CPEMI->getOperand(2).getImm();1308// Compute this only once, it's expensive.1309unsigned UserOffset = getUserOffset(U);13101311// See if the current entry is within range, or there is a clone of it1312// in range.1313int result = findInRangeCPEntry(U, UserOffset);1314if (result==1) return false;1315else if (result==2) return true;13161317// Look for water where we can place this CPE.1318MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock();1319MachineBasicBlock *NewMBB;1320water_iterator IP;1321if (findAvailableWater(U, UserOffset, IP)) {1322LLVM_DEBUG(dbgs() << "Found water in range\n");1323MachineBasicBlock *WaterBB = *IP;13241325// If the original WaterList entry was "new water" on this iteration,1326// propagate that to the new island. This is just keeping NewWaterList1327// updated to match the WaterList, which will be updated below.1328if (NewWaterList.erase(WaterBB))1329NewWaterList.insert(NewIsland);13301331// The new CPE goes before the following block (NewMBB).1332NewMBB = &*++WaterBB->getIterator();1333} else {1334// No water found.1335// we first see if a longer form of the instrucion could have reached1336// the constant. in that case we won't bother to split1337if (!NoLoadRelaxation) {1338result = findLongFormInRangeCPEntry(U, UserOffset);1339if (result != 0) return true;1340}1341LLVM_DEBUG(dbgs() << "No water found\n");1342createNewWater(CPUserIndex, UserOffset, NewMBB);13431344// splitBlockBeforeInstr adds to WaterList, which is important when it is1345// called while handling branches so that the water will be seen on the1346// next iteration for constant pools, but in this context, we don't want1347// it. Check for this so it will be removed from the WaterList.1348// Also remove any entry from NewWaterList.1349MachineBasicBlock *WaterBB = &*--NewMBB->getIterator();1350IP = llvm::find(WaterList, WaterBB);1351if (IP != WaterList.end())1352NewWaterList.erase(WaterBB);13531354// We are adding new water. Update NewWaterList.1355NewWaterList.insert(NewIsland);1356}13571358// Remove the original WaterList entry; we want subsequent insertions in1359// this vicinity to go after the one we're about to insert. This1360// considerably reduces the number of times we have to move the same CPE1361// more than once and is also important to ensure the algorithm terminates.1362if (IP != WaterList.end())1363WaterList.erase(IP);13641365// Okay, we know we can put an island before NewMBB now, do it!1366MF->insert(NewMBB->getIterator(), NewIsland);13671368// Update internal data structures to account for the newly inserted MBB.1369updateForInsertedWaterBlock(NewIsland);13701371// Decrement the old entry, and remove it if refcount becomes 0.1372decrementCPEReferenceCount(CPI, CPEMI);13731374// No existing clone of this CPE is within range.1375// We will be generating a new clone. Get a UID for it.1376unsigned ID = createPICLabelUId();13771378// Now that we have an island to add the CPE to, clone the original CPE and1379// add it to the island.1380U.HighWaterMark = NewIsland;1381U.CPEMI = BuildMI(NewIsland, DebugLoc(), TII->get(Mips::CONSTPOOL_ENTRY))1382.addImm(ID).addConstantPoolIndex(CPI).addImm(Size);1383CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));1384++NumCPEs;13851386// Mark the basic block as aligned as required by the const-pool entry.1387NewIsland->setAlignment(getCPEAlign(*U.CPEMI));13881389// Increase the size of the island block to account for the new entry.1390BBInfo[NewIsland->getNumber()].Size += Size;1391adjustBBOffsetsAfter(&*--NewIsland->getIterator());13921393// Finally, change the CPI in the instruction operand to be ID.1394for (MachineOperand &MO : UserMI->operands())1395if (MO.isCPI()) {1396MO.setIndex(ID);1397break;1398}13991400LLVM_DEBUG(1401dbgs() << " Moved CPE to #" << ID << " CPI=" << CPI1402<< format(" offset=%#x\n", BBInfo[NewIsland->getNumber()].Offset));14031404return true;1405}14061407/// removeDeadCPEMI - Remove a dead constant pool entry instruction. Update1408/// sizes and offsets of impacted basic blocks.1409void MipsConstantIslands::removeDeadCPEMI(MachineInstr *CPEMI) {1410MachineBasicBlock *CPEBB = CPEMI->getParent();1411unsigned Size = CPEMI->getOperand(2).getImm();1412CPEMI->eraseFromParent();1413BBInfo[CPEBB->getNumber()].Size -= Size;1414// All succeeding offsets have the current size value added in, fix this.1415if (CPEBB->empty()) {1416BBInfo[CPEBB->getNumber()].Size = 0;14171418// This block no longer needs to be aligned.1419CPEBB->setAlignment(Align(1));1420} else {1421// Entries are sorted by descending alignment, so realign from the front.1422CPEBB->setAlignment(getCPEAlign(*CPEBB->begin()));1423}14241425adjustBBOffsetsAfter(CPEBB);1426// An island has only one predecessor BB and one successor BB. Check if1427// this BB's predecessor jumps directly to this BB's successor. This1428// shouldn't happen currently.1429assert(!BBIsJumpedOver(CPEBB) && "How did this happen?");1430// FIXME: remove the empty blocks after all the work is done?1431}14321433/// removeUnusedCPEntries - Remove constant pool entries whose refcounts1434/// are zero.1435bool MipsConstantIslands::removeUnusedCPEntries() {1436unsigned MadeChange = false;1437for (std::vector<CPEntry> &CPEs : CPEntries) {1438for (CPEntry &CPE : CPEs) {1439if (CPE.RefCount == 0 && CPE.CPEMI) {1440removeDeadCPEMI(CPE.CPEMI);1441CPE.CPEMI = nullptr;1442MadeChange = true;1443}1444}1445}1446return MadeChange;1447}14481449/// isBBInRange - Returns true if the distance between specific MI and1450/// specific BB can fit in MI's displacement field.1451bool MipsConstantIslands::isBBInRange1452(MachineInstr *MI,MachineBasicBlock *DestBB, unsigned MaxDisp) {1453unsigned PCAdj = 4;1454unsigned BrOffset = getOffsetOf(MI) + PCAdj;1455unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;14561457LLVM_DEBUG(dbgs() << "Branch of destination " << printMBBReference(*DestBB)1458<< " from " << printMBBReference(*MI->getParent())1459<< " max delta=" << MaxDisp << " from " << getOffsetOf(MI)1460<< " to " << DestOffset << " offset "1461<< int(DestOffset - BrOffset) << "\t" << *MI);14621463if (BrOffset <= DestOffset) {1464// Branch before the Dest.1465if (DestOffset-BrOffset <= MaxDisp)1466return true;1467} else {1468if (BrOffset-DestOffset <= MaxDisp)1469return true;1470}1471return false;1472}14731474/// fixupImmediateBr - Fix up an immediate branch whose destination is too far1475/// away to fit in its displacement field.1476bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {1477MachineInstr *MI = Br.MI;1478unsigned TargetOperand = branchTargetOperand(MI);1479MachineBasicBlock *DestBB = MI->getOperand(TargetOperand).getMBB();14801481// Check to see if the DestBB is already in-range.1482if (isBBInRange(MI, DestBB, Br.MaxDisp))1483return false;14841485if (!Br.isCond)1486return fixupUnconditionalBr(Br);1487return fixupConditionalBr(Br);1488}14891490/// fixupUnconditionalBr - Fix up an unconditional branch whose destination is1491/// too far away to fit in its displacement field. If the LR register has been1492/// spilled in the epilogue, then we can use BL to implement a far jump.1493/// Otherwise, add an intermediate branch instruction to a branch.1494bool1495MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {1496MachineInstr *MI = Br.MI;1497MachineBasicBlock *MBB = MI->getParent();1498MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();1499// Use BL to implement far jump.1500unsigned BimmX16MaxDisp = ((1 << 16)-1) * 2;1501if (isBBInRange(MI, DestBB, BimmX16MaxDisp)) {1502Br.MaxDisp = BimmX16MaxDisp;1503MI->setDesc(TII->get(Mips::BimmX16));1504}1505else {1506// need to give the math a more careful look here1507// this is really a segment address and not1508// a PC relative address. FIXME. But I think that1509// just reducing the bits by 1 as I've done is correct.1510// The basic block we are branching too much be longword aligned.1511// we know that RA is saved because we always save it right now.1512// this requirement will be relaxed later but we also have an alternate1513// way to implement this that I will implement that does not need jal.1514// We should have a way to back out this alignment restriction1515// if we "can" later. but it is not harmful.1516//1517DestBB->setAlignment(Align(4));1518Br.MaxDisp = ((1<<24)-1) * 2;1519MI->setDesc(TII->get(Mips::JalB16));1520}1521BBInfo[MBB->getNumber()].Size += 2;1522adjustBBOffsetsAfter(MBB);1523HasFarJump = true;1524++NumUBrFixed;15251526LLVM_DEBUG(dbgs() << " Changed B to long jump " << *MI);15271528return true;1529}15301531/// fixupConditionalBr - Fix up a conditional branch whose destination is too1532/// far away to fit in its displacement field. It is converted to an inverse1533/// conditional branch + an unconditional branch to the destination.1534bool1535MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {1536MachineInstr *MI = Br.MI;1537unsigned TargetOperand = branchTargetOperand(MI);1538MachineBasicBlock *DestBB = MI->getOperand(TargetOperand).getMBB();1539unsigned Opcode = MI->getOpcode();1540unsigned LongFormOpcode = longformBranchOpcode(Opcode);1541unsigned LongFormMaxOff = branchMaxOffsets(LongFormOpcode);15421543// Check to see if the DestBB is already in-range.1544if (isBBInRange(MI, DestBB, LongFormMaxOff)) {1545Br.MaxDisp = LongFormMaxOff;1546MI->setDesc(TII->get(LongFormOpcode));1547return true;1548}15491550// Add an unconditional branch to the destination and invert the branch1551// condition to jump over it:1552// bteqz L11553// =>1554// bnez L21555// b L11556// L2:15571558// If the branch is at the end of its MBB and that has a fall-through block,1559// direct the updated conditional branch to the fall-through block. Otherwise,1560// split the MBB before the next instruction.1561MachineBasicBlock *MBB = MI->getParent();1562MachineInstr *BMI = &MBB->back();1563bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB);1564unsigned OppositeBranchOpcode = TII->getOppositeBranchOpc(Opcode);15651566++NumCBrFixed;1567if (BMI != MI) {1568if (std::next(MachineBasicBlock::iterator(MI)) == std::prev(MBB->end()) &&1569BMI->isUnconditionalBranch()) {1570// Last MI in the BB is an unconditional branch. Can we simply invert the1571// condition and swap destinations:1572// beqz L11573// b L21574// =>1575// bnez L21576// b L11577unsigned BMITargetOperand = branchTargetOperand(BMI);1578MachineBasicBlock *NewDest =1579BMI->getOperand(BMITargetOperand).getMBB();1580if (isBBInRange(MI, NewDest, Br.MaxDisp)) {1581LLVM_DEBUG(1582dbgs() << " Invert Bcc condition and swap its destination with "1583<< *BMI);1584MI->setDesc(TII->get(OppositeBranchOpcode));1585BMI->getOperand(BMITargetOperand).setMBB(DestBB);1586MI->getOperand(TargetOperand).setMBB(NewDest);1587return true;1588}1589}1590}15911592if (NeedSplit) {1593splitBlockBeforeInstr(*MI);1594// No need for the branch to the next block. We're adding an unconditional1595// branch to the destination.1596int delta = TII->getInstSizeInBytes(MBB->back());1597BBInfo[MBB->getNumber()].Size -= delta;1598MBB->back().eraseFromParent();1599// BBInfo[SplitBB].Offset is wrong temporarily, fixed below1600}1601MachineBasicBlock *NextBB = &*++MBB->getIterator();16021603LLVM_DEBUG(dbgs() << " Insert B to " << printMBBReference(*DestBB)1604<< " also invert condition and change dest. to "1605<< printMBBReference(*NextBB) << "\n");16061607// Insert a new conditional branch and a new unconditional branch.1608// Also update the ImmBranch as well as adding a new entry for the new branch.1609if (MI->getNumExplicitOperands() == 2) {1610BuildMI(MBB, DebugLoc(), TII->get(OppositeBranchOpcode))1611.addReg(MI->getOperand(0).getReg())1612.addMBB(NextBB);1613} else {1614BuildMI(MBB, DebugLoc(), TII->get(OppositeBranchOpcode))1615.addMBB(NextBB);1616}1617Br.MI = &MBB->back();1618BBInfo[MBB->getNumber()].Size += TII->getInstSizeInBytes(MBB->back());1619BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB);1620BBInfo[MBB->getNumber()].Size += TII->getInstSizeInBytes(MBB->back());1621unsigned MaxDisp = getUnconditionalBrDisp(Br.UncondBr);1622ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr));16231624// Remove the old conditional branch. It may or may not still be in MBB.1625BBInfo[MI->getParent()->getNumber()].Size -= TII->getInstSizeInBytes(*MI);1626MI->eraseFromParent();1627adjustBBOffsetsAfter(MBB);1628return true;1629}16301631void MipsConstantIslands::prescanForConstants() {1632unsigned J = 0;1633(void)J;1634for (MachineBasicBlock &B : *MF) {1635for (MachineBasicBlock::instr_iterator I = B.instr_begin(),1636EB = B.instr_end();1637I != EB; ++I) {1638switch(I->getDesc().getOpcode()) {1639case Mips::LwConstant32: {1640PrescannedForConstants = true;1641LLVM_DEBUG(dbgs() << "constant island constant " << *I << "\n");1642J = I->getNumOperands();1643LLVM_DEBUG(dbgs() << "num operands " << J << "\n");1644MachineOperand& Literal = I->getOperand(1);1645if (Literal.isImm()) {1646int64_t V = Literal.getImm();1647LLVM_DEBUG(dbgs() << "literal " << V << "\n");1648Type *Int32Ty =1649Type::getInt32Ty(MF->getFunction().getContext());1650const Constant *C = ConstantInt::get(Int32Ty, V);1651unsigned index = MCP->getConstantPoolIndex(C, Align(4));1652I->getOperand(2).ChangeToImmediate(index);1653LLVM_DEBUG(dbgs() << "constant island constant " << *I << "\n");1654I->setDesc(TII->get(Mips::LwRxPcTcp16));1655I->removeOperand(1);1656I->removeOperand(1);1657I->addOperand(MachineOperand::CreateCPI(index, 0));1658I->addOperand(MachineOperand::CreateImm(4));1659}1660break;1661}1662default:1663break;1664}1665}1666}1667}16681669/// Returns a pass that converts branches to long branches.1670FunctionPass *llvm::createMipsConstantIslandPass() {1671return new MipsConstantIslands();1672}167316741675