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"
63 unsigned OpcodeHi,
unsigned OpcodeLo,
64 unsigned FlagsHi,
unsigned FlagsLo);
68 unsigned LastOpcode,
unsigned IdentifyingMO);
72 unsigned LastOpcode,
unsigned IdentifyingMO,
74 bool EraseFromParent);
110char LoongArchPreRAExpandPseudo::ID = 0;
112bool LoongArchPreRAExpandPseudo::runOnMachineFunction(
MachineFunction &MF) {
134bool LoongArchPreRAExpandPseudo::expandMI(
137 switch (
MBBI->getOpcode()) {
138 case LoongArch::PseudoLA_PCREL:
139 return expandLoadAddressPcrel(
MBB,
MBBI, NextMBBI);
140 case LoongArch::PseudoLA_PCREL_LARGE:
141 return expandLoadAddressPcrel(
MBB,
MBBI, NextMBBI,
true);
142 case LoongArch::PseudoLA_GOT:
143 return expandLoadAddressGot(
MBB,
MBBI, NextMBBI);
144 case LoongArch::PseudoLA_GOT_LARGE:
145 return expandLoadAddressGot(
MBB,
MBBI, NextMBBI,
true);
146 case LoongArch::PseudoLA_TLS_LE:
147 return expandLoadAddressTLSLE(
MBB,
MBBI, NextMBBI);
148 case LoongArch::PseudoLA_TLS_IE:
149 return expandLoadAddressTLSIE(
MBB,
MBBI, NextMBBI);
150 case LoongArch::PseudoLA_TLS_IE_LARGE:
151 return expandLoadAddressTLSIE(
MBB,
MBBI, NextMBBI,
true);
152 case LoongArch::PseudoLA_TLS_LD:
153 return expandLoadAddressTLSLD(
MBB,
MBBI, NextMBBI);
154 case LoongArch::PseudoLA_TLS_LD_LARGE:
155 return expandLoadAddressTLSLD(
MBB,
MBBI, NextMBBI,
true);
156 case LoongArch::PseudoLA_TLS_GD:
157 return expandLoadAddressTLSGD(
MBB,
MBBI, NextMBBI);
158 case LoongArch::PseudoLA_TLS_GD_LARGE:
159 return expandLoadAddressTLSGD(
MBB,
MBBI, NextMBBI,
true);
160 case LoongArch::PseudoLA_TLS_DESC:
161 return expandLoadAddressTLSDesc(
MBB,
MBBI, NextMBBI);
162 case LoongArch::PseudoLA_TLS_DESC_LARGE:
163 return expandLoadAddressTLSDesc(
MBB,
MBBI, NextMBBI,
true);
164 case LoongArch::PseudoCALL_SMALL:
165 case LoongArch::PseudoCALL_LARGE:
166 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
false);
167 case LoongArch::PseudoTAIL_SMALL:
168 case LoongArch::PseudoTAIL_LARGE:
169 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
true);
170 case LoongArch::PseudoBRIND:
180bool LoongArchPreRAExpandPseudo::expandPcaxxu12iInstPair(
183 unsigned FlagsHi,
unsigned FlagsLo) {
189 bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
203 if (OpcodeHi == LoongArch::PCALAU12I) {
212 .
addSym(PCAddSymbol, FlagsLo);
215 if (
MI.hasOneMemOperand())
218 MI.eraseFromParent();
222bool LoongArchPreRAExpandPseudo::expandLargeAddressLoad(
225 unsigned IdentifyingMO) {
227 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LastOpcode, IdentifyingMO,
228 MI.getOperand(2),
MI.getOperand(0).getReg(),
232bool LoongArchPreRAExpandPseudo::expandLargeAddressLoad(
236 bool EraseFromParent) {
245 unsigned MO0, MO1, MO2, MO3;
246 switch (IdentifyingMO) {
277 "Large code model requires LA64");
307 const char *SymName = Symbol.getSymbolName();
308 Part0.addExternalSymbol(SymName, MO0);
309 Part1.addExternalSymbol(SymName, MO1);
310 Part2.addExternalSymbol(SymName, MO2);
311 Part3.addExternalSymbol(SymName, MO3);
313 Part0.addDisp(Symbol, 0, MO0);
314 Part1.addDisp(Symbol, 0, MO1);
315 Part2.addDisp(Symbol, 0, MO2);
316 Part3.addDisp(Symbol, 0, MO3);
320 MI.eraseFromParent();
325bool LoongArchPreRAExpandPseudo::expandLoadAddressPcrel(
331 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
346 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
347 unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
348 unsigned OpcodeLo = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
353 return expandPcaxxu12iInstPair(
MBB,
MBBI, NextMBBI, OpcodeHi, OpcodeLo,
357bool LoongArchPreRAExpandPseudo::expandLoadAddressGot(
363 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::LDX_D,
378 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
379 unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
380 unsigned OpcodeLo = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
385 return expandPcaxxu12iInstPair(
MBB,
MBBI, NextMBBI, OpcodeHi, OpcodeLo,
389bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLE(
419 unsigned AddOp = STI.
is64Bit() ? LoongArch::PseudoAddTPRel_D
420 : LoongArch::PseudoAddTPRel_W;
426 unsigned AddiOp = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
450 MI.eraseFromParent();
454bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSIE(
460 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::LDX_D,
475 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
476 unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
477 unsigned OpcodeLo = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
482 return expandPcaxxu12iInstPair(
MBB,
MBBI, NextMBBI, OpcodeHi, OpcodeLo,
486bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLD(
492 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
507 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
508 unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
509 unsigned OpcodeLo = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
514 return expandPcaxxu12iInstPair(
MBB,
MBBI, NextMBBI, OpcodeHi, OpcodeLo,
518bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSGD(
524 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
539 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
540 unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
541 unsigned OpcodeLo = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
546 return expandPcaxxu12iInstPair(
MBB,
MBBI, NextMBBI, OpcodeHi, OpcodeLo,
550bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSDesc(
558 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
559 bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
560 unsigned PCA = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
561 unsigned ADD = STI.is64Bit() ? LoongArch::ADD_D : LoongArch::ADD_W;
562 unsigned ADDI = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
563 unsigned LD = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
589 "Large code model requires LA64");
645 EnableRelax && !Large));
650 EnableRelax && !Large));
655 MI.eraseFromParent();
659bool LoongArchPreRAExpandPseudo::expandFunctionCALL(
678 Opcode = IsTailCall ? LoongArch::PseudoB_TAIL : LoongArch::BL;
687 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL;
695 unsigned LAOpcode = UseGOT ? LoongArch::LDX_D : LoongArch::ADD_D;
696 expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LAOpcode, MO, Func, AddrReg,
704 CALL.copyImplicitOps(
MI);
707 CALL.setMIFlags(
MI.getFlags());
709 MI.eraseFromParent();
713void LoongArchPreRAExpandPseudo::annotateTableJump(
718 bool IsFound =
false;
724 for (
auto &MO : MInst->
all_uses()) {
728 if (!
Reg.isVirtual())
733 for (
unsigned Idx = 0; Idx <
DefMI->getNumOperands(); ++Idx) {
736 MBBI->setPreInstrSymbol(
744 FindJTIMI(
DefMI, --FindDepth);
749 FindJTIMI(&*
MBBI, 4);
777char LoongArchExpandPseudo::ID = 0;
806 switch (
MBBI->getOpcode()) {
807 case LoongArch::PseudoCopyCFR:
808 return expandCopyCFR(
MBB,
MBBI, NextMBBI);
809 case LoongArch::PseudoCALL_MEDIUM:
810 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
false);
811 case LoongArch::PseudoTAIL_MEDIUM:
812 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
true);
818bool LoongArchExpandPseudo::expandCopyCFR(
838 MF->
insert(++
MBB.getIterator(), FalseBB);
839 MF->
insert(++FalseBB->getIterator(), SinkBB);
850 BuildMI(FalseBB,
DL,
TII->get(LoongArch::SET_CFR_TRUE), DestReg);
852 FalseBB->addSuccessor(SinkBB);
854 SinkBB->splice(SinkBB->end(), &
MBB,
MI,
MBB.end());
855 SinkBB->transferSuccessors(&
MBB);
857 MBB.addSuccessor(FalseBB);
858 MBB.addSuccessor(SinkBB);
860 NextMBBI =
MBB.end();
861 MI.eraseFromParent();
871bool LoongArchExpandPseudo::expandFunctionCALL(
902 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL;
903 Register ScratchReg = IsTailCall ? LoongArch::R20 : LoongArch::R1;
905 unsigned PC = Is64Bit ? LoongArch::PCADDU18I : LoongArch::PCADDU12I;
921 CALL.copyImplicitOps(
MI);
924 CALL.setMIFlags(
MI.getFlags());
926 MI.eraseFromParent();
941 return new LoongArchPreRAExpandPseudo();
944 return new LoongArchExpandPseudo();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
cl::opt< bool > LArchAnnotateTableJump("loongarch-annotate-tablejump", cl::Hidden, cl::desc("Annotate table jump instruction to correlate it with the jump table."), cl::init(false))
#define LOONGARCH_PRERA_EXPAND_PSEUDO_NAME
#define LOONGARCH_EXPAND_PSEUDO_NAME
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool is64Bit(const char *name)
Represent the analysis usage information of a pass.
LLVM_ABI 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...
LLVM_ABI MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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)
CreateMachineInstr - Allocate a new MachineInstr.
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 & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) 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.
LLVM_ABI void setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol)
Set a symbol that will be emitted just prior to the instruction itself.
filtered_mop_range all_uses()
Returns an iterator range over all operands that are (explicit or implicit) register uses.
LLVM_ABI 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,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
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.
#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.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionPass * createLoongArchPreRAExpandPseudoPass()
FunctionPass * createLoongArchExpandPseudoPass()
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().