32#define LOONGARCH_PRERA_EXPAND_PSEUDO_NAME \
33 "LoongArch Pre-RA pseudo instruction expansion pass"
34#define LOONGARCH_EXPAND_PSEUDO_NAME \
35 "LoongArch pseudo instruction expansion pass"
65 unsigned FlagsHi,
unsigned SecondOpcode,
70 unsigned LastOpcode,
unsigned IdentifyingMO);
74 unsigned LastOpcode,
unsigned IdentifyingMO,
76 bool EraseFromParent);
112char LoongArchPreRAExpandPseudo::ID = 0;
114bool LoongArchPreRAExpandPseudo::runOnMachineFunction(
MachineFunction &MF) {
136bool LoongArchPreRAExpandPseudo::expandMI(
139 switch (
MBBI->getOpcode()) {
140 case LoongArch::PseudoLA_PCREL:
141 return expandLoadAddressPcrel(
MBB,
MBBI, NextMBBI);
142 case LoongArch::PseudoLA_PCREL_LARGE:
143 return expandLoadAddressPcrel(
MBB,
MBBI, NextMBBI,
true);
144 case LoongArch::PseudoLA_GOT:
145 return expandLoadAddressGot(
MBB,
MBBI, NextMBBI);
146 case LoongArch::PseudoLA_GOT_LARGE:
147 return expandLoadAddressGot(
MBB,
MBBI, NextMBBI,
true);
148 case LoongArch::PseudoLA_TLS_LE:
149 return expandLoadAddressTLSLE(
MBB,
MBBI, NextMBBI);
150 case LoongArch::PseudoLA_TLS_IE:
151 return expandLoadAddressTLSIE(
MBB,
MBBI, NextMBBI);
152 case LoongArch::PseudoLA_TLS_IE_LARGE:
153 return expandLoadAddressTLSIE(
MBB,
MBBI, NextMBBI,
true);
154 case LoongArch::PseudoLA_TLS_LD:
155 return expandLoadAddressTLSLD(
MBB,
MBBI, NextMBBI);
156 case LoongArch::PseudoLA_TLS_LD_LARGE:
157 return expandLoadAddressTLSLD(
MBB,
MBBI, NextMBBI,
true);
158 case LoongArch::PseudoLA_TLS_GD:
159 return expandLoadAddressTLSGD(
MBB,
MBBI, NextMBBI);
160 case LoongArch::PseudoLA_TLS_GD_LARGE:
161 return expandLoadAddressTLSGD(
MBB,
MBBI, NextMBBI,
true);
162 case LoongArch::PseudoLA_TLS_DESC:
163 return expandLoadAddressTLSDesc(
MBB,
MBBI, NextMBBI);
164 case LoongArch::PseudoLA_TLS_DESC_LARGE:
165 return expandLoadAddressTLSDesc(
MBB,
MBBI, NextMBBI,
true);
166 case LoongArch::PseudoCALL:
167 case LoongArch::PseudoCALL_LARGE:
168 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
false);
169 case LoongArch::PseudoTAIL:
170 case LoongArch::PseudoTAIL_LARGE:
171 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
true);
172 case LoongArch::PseudoBRIND:
182bool LoongArchPreRAExpandPseudo::expandPcalau12iInstPair(
185 unsigned SecondOpcode,
unsigned FlagsLo) {
191 bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
206 if (
MI.hasOneMemOperand())
209 MI.eraseFromParent();
213bool LoongArchPreRAExpandPseudo::expandLargeAddressLoad(
216 unsigned IdentifyingMO) {
218 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LastOpcode, IdentifyingMO,
219 MI.getOperand(2),
MI.getOperand(0).getReg(),
223bool LoongArchPreRAExpandPseudo::expandLargeAddressLoad(
227 bool EraseFromParent) {
236 unsigned MO0, MO1, MO2, MO3;
237 switch (IdentifyingMO) {
268 "Large code model requires LA64");
298 const char *SymName = Symbol.getSymbolName();
299 Part0.addExternalSymbol(SymName, MO0);
300 Part1.addExternalSymbol(SymName, MO1);
301 Part2.addExternalSymbol(SymName, MO2);
302 Part3.addExternalSymbol(SymName, MO3);
304 Part0.addDisp(Symbol, 0, MO0);
305 Part1.addDisp(Symbol, 0, MO1);
306 Part2.addDisp(Symbol, 0, MO2);
307 Part3.addDisp(Symbol, 0, MO3);
311 MI.eraseFromParent();
316bool LoongArchPreRAExpandPseudo::expandLoadAddressPcrel(
322 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
330 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
335bool LoongArchPreRAExpandPseudo::expandLoadAddressGot(
341 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::LDX_D,
349 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
354bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLE(
384 unsigned AddOp = STI.
is64Bit() ? LoongArch::PseudoAddTPRel_D
385 : LoongArch::PseudoAddTPRel_W;
391 unsigned AddiOp = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
415 MI.eraseFromParent();
419bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSIE(
425 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::LDX_D,
433 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
438bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLD(
444 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
452 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
457bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSGD(
463 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
471 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
476bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSDesc(
484 unsigned ADD = STI.is64Bit() ? LoongArch::ADD_D : LoongArch::ADD_W;
485 unsigned ADDI = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
486 unsigned LD = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
487 bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
497 EnableRelax && !Large));
511 "Large code model requires LA64");
548 EnableRelax && !Large));
553 EnableRelax && !Large));
558 MI.eraseFromParent();
562bool LoongArchPreRAExpandPseudo::expandFunctionCALL(
581 Opcode = IsTailCall ? LoongArch::PseudoB_TAIL : LoongArch::BL;
590 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL;
598 unsigned LAOpcode = UseGOT ? LoongArch::LDX_D : LoongArch::ADD_D;
599 expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LAOpcode, MO, Func, AddrReg,
607 CALL.copyImplicitOps(
MI);
610 CALL.setMIFlags(
MI.getFlags());
612 MI.eraseFromParent();
616void LoongArchPreRAExpandPseudo::annotateTableJump(
621 bool IsFound =
false;
627 for (
auto &MO : MInst->
all_uses()) {
631 if (!Reg.isVirtual())
639 MBBI->setPreInstrSymbol(
646 FindJTIMI(
DefMI, --FindDepth);
651 FindJTIMI(&*
MBBI, 3);
681char LoongArchExpandPseudo::ID = 0;
710 switch (
MBBI->getOpcode()) {
711 case LoongArch::PseudoCopyCFR:
712 return expandCopyCFR(
MBB,
MBBI, NextMBBI);
713 case LoongArch::PseudoCALL_MEDIUM:
714 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
false);
715 case LoongArch::PseudoTAIL_MEDIUM:
716 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
true);
722bool LoongArchExpandPseudo::expandCopyCFR(
743 MF->
insert(++FalseBB->getIterator(), SinkBB);
754 BuildMI(FalseBB,
DL,
TII->get(LoongArch::SET_CFR_TRUE), DestReg);
756 FalseBB->addSuccessor(SinkBB);
758 SinkBB->splice(SinkBB->end(), &
MBB,
MI,
MBB.
end());
759 SinkBB->transferSuccessors(&
MBB);
765 MI.eraseFromParent();
775bool LoongArchExpandPseudo::expandFunctionCALL(
797 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL;
798 Register ScratchReg = IsTailCall ? LoongArch::R20 : LoongArch::R1;
814 CALL.copyImplicitOps(
MI);
817 CALL.setMIFlags(
MI.getFlags());
819 MI.eraseFromParent();
834 return new LoongArchPreRAExpandPseudo();
837 return new LoongArchExpandPseudo();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static Expected< BitVector > expand(StringRef S, StringRef Original)
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define LOONGARCH_PRERA_EXPAND_PSEUDO_NAME
cl::opt< bool > LArchAnnotateTableJump
#define LOONGARCH_EXPAND_PSEUDO_NAME
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
LLVM Basic Block Representation.
FunctionPass class - This class is used to implement most global optimizations.
A set of physical registers with utility functions to track liveness when walking backward/forward th...
LoongArchMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private Lo...
MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addDisp(const MachineOperand &Disp, int64_t off, unsigned char 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
Representation of each machine instruction.
iterator_range< filtered_mop_iterator > all_uses()
Returns an iterator range over all operands that are (explicit or implicit) register uses.
unsigned getNumOperands() const
Retuns the total number of operands.
const MachineOperand & getOperand(unsigned i) const
void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
@ MO_ExternalSymbol
Name of external global symbol.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
StringRef - Represent a constant reference to a string, i.e.
CodeModel::Model getCodeModel() const
Returns the code model.
virtual const TargetInstrInfo * getInstrInfo() const
self_iterator getIterator()
#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.
static unsigned encodeFlags(unsigned Flags, bool Relax)
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &)
void initializeLoongArchExpandPseudoPass(PassRegistry &)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
FunctionPass * createLoongArchPreRAExpandPseudoPass()
FunctionPass * createLoongArchExpandPseudoPass()
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().