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);
113char LoongArchPreRAExpandPseudo::ID = 0;
115bool LoongArchPreRAExpandPseudo::runOnMachineFunction(
MachineFunction &MF) {
137bool LoongArchPreRAExpandPseudo::expandMI(
140 switch (
MBBI->getOpcode()) {
141 case LoongArch::PseudoLA_PCREL:
142 return expandLoadAddressPcrel(
MBB,
MBBI, NextMBBI);
143 case LoongArch::PseudoLA_PCREL_LARGE:
144 return expandLoadAddressPcrel(
MBB,
MBBI, NextMBBI,
true);
145 case LoongArch::PseudoLA_GOT:
146 return expandLoadAddressGot(
MBB,
MBBI, NextMBBI);
147 case LoongArch::PseudoLA_GOT_LARGE:
148 return expandLoadAddressGot(
MBB,
MBBI, NextMBBI,
true);
149 case LoongArch::PseudoLA_TLS_LE:
150 return expandLoadAddressTLSLE(
MBB,
MBBI, NextMBBI);
151 case LoongArch::PseudoLA_TLS_IE:
152 return expandLoadAddressTLSIE(
MBB,
MBBI, NextMBBI);
153 case LoongArch::PseudoLA_TLS_IE_LARGE:
154 return expandLoadAddressTLSIE(
MBB,
MBBI, NextMBBI,
true);
155 case LoongArch::PseudoLA_TLS_LD:
156 return expandLoadAddressTLSLD(
MBB,
MBBI, NextMBBI);
157 case LoongArch::PseudoLA_TLS_LD_LARGE:
158 return expandLoadAddressTLSLD(
MBB,
MBBI, NextMBBI,
true);
159 case LoongArch::PseudoLA_TLS_GD:
160 return expandLoadAddressTLSGD(
MBB,
MBBI, NextMBBI);
161 case LoongArch::PseudoLA_TLS_GD_LARGE:
162 return expandLoadAddressTLSGD(
MBB,
MBBI, NextMBBI,
true);
163 case LoongArch::PseudoLA_TLS_DESC:
164 return expandLoadAddressTLSDesc(
MBB,
MBBI, NextMBBI);
165 case LoongArch::PseudoLA_TLS_DESC_LARGE:
166 return expandLoadAddressTLSDesc(
MBB,
MBBI, NextMBBI,
true);
167 case LoongArch::PseudoCALL_SMALL:
168 case LoongArch::PseudoCALL_LARGE:
169 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
false);
170 case LoongArch::PseudoTAIL_SMALL:
171 case LoongArch::PseudoTAIL_LARGE:
172 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
true);
173 case LoongArch::PseudoMOVCF2GRViaFR:
174 return expandMOVCF2GRViaFR(
MBB,
MBBI, NextMBBI);
175 case LoongArch::PseudoBRIND:
185bool LoongArchPreRAExpandPseudo::expandPcaxxu12iInstPair(
188 unsigned FlagsHi,
unsigned FlagsLo) {
194 bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
208 if (OpcodeHi == LoongArch::PCALAU12I) {
217 .
addSym(PCAddSymbol, FlagsLo);
220 if (
MI.hasOneMemOperand())
223 MI.eraseFromParent();
227bool LoongArchPreRAExpandPseudo::expandLargeAddressLoad(
230 unsigned IdentifyingMO) {
232 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LastOpcode, IdentifyingMO,
233 MI.getOperand(2),
MI.getOperand(0).getReg(),
237bool LoongArchPreRAExpandPseudo::expandLargeAddressLoad(
241 bool EraseFromParent) {
250 unsigned MO0, MO1, MO2, MO3;
251 switch (IdentifyingMO) {
282 "Large code model requires LA64");
312 const char *SymName = Symbol.getSymbolName();
313 Part0.addExternalSymbol(SymName, MO0);
314 Part1.addExternalSymbol(SymName, MO1);
315 Part2.addExternalSymbol(SymName, MO2);
316 Part3.addExternalSymbol(SymName, MO3);
318 Part0.addDisp(Symbol, 0, MO0);
319 Part1.addDisp(Symbol, 0, MO1);
320 Part2.addDisp(Symbol, 0, MO2);
321 Part3.addDisp(Symbol, 0, MO3);
325 MI.eraseFromParent();
330bool LoongArchPreRAExpandPseudo::expandLoadAddressPcrel(
336 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
351 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
352 unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
353 unsigned OpcodeLo = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
358 return expandPcaxxu12iInstPair(
MBB,
MBBI, NextMBBI, OpcodeHi, OpcodeLo,
362bool LoongArchPreRAExpandPseudo::expandLoadAddressGot(
368 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::LDX_D,
383 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
384 unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
385 unsigned OpcodeLo = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
390 return expandPcaxxu12iInstPair(
MBB,
MBBI, NextMBBI, OpcodeHi, OpcodeLo,
394bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLE(
424 unsigned AddOp = STI.
is64Bit() ? LoongArch::PseudoAddTPRel_D
425 : LoongArch::PseudoAddTPRel_W;
431 unsigned AddiOp = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
455 MI.eraseFromParent();
459bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSIE(
465 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::LDX_D,
480 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
481 unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
482 unsigned OpcodeLo = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
487 return expandPcaxxu12iInstPair(
MBB,
MBBI, NextMBBI, OpcodeHi, OpcodeLo,
491bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLD(
497 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
512 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
513 unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
514 unsigned OpcodeLo = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
519 return expandPcaxxu12iInstPair(
MBB,
MBBI, NextMBBI, OpcodeHi, OpcodeLo,
523bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSGD(
529 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
544 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
545 unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
546 unsigned OpcodeLo = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
551 return expandPcaxxu12iInstPair(
MBB,
MBBI, NextMBBI, OpcodeHi, OpcodeLo,
555bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSDesc(
563 bool Has32S = STI.hasFeature(LoongArch::Feature32S);
564 bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
565 unsigned PCA = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
566 unsigned ADD = STI.is64Bit() ? LoongArch::ADD_D : LoongArch::ADD_W;
567 unsigned ADDI = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
568 unsigned LD = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
594 "Large code model requires LA64");
650 EnableRelax && !Large));
655 EnableRelax && !Large))
661 MI.eraseFromParent();
665bool LoongArchPreRAExpandPseudo::expandFunctionCALL(
680 unsigned Opcode = IsTailCall ? LoongArch::PseudoB_TAIL : LoongArch::BL;
681 MI.setDesc(
TII->get(Opcode));
690 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL;
698 unsigned LAOpcode = UseGOT ? LoongArch::LDX_D : LoongArch::ADD_D;
699 expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LAOpcode, MO, Func, AddrReg,
704 MI.setDesc(
TII->get(Opcode));
705 MI.getOperand(0).ChangeToRegister(AddrReg,
false);
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);
779char LoongArchExpandPseudo::ID = 0;
808 switch (
MBBI->getOpcode()) {
809 case LoongArch::PseudoCopyCFR:
810 return expandCopyCFR(
MBB,
MBBI, NextMBBI);
811 case LoongArch::PseudoCALL_MEDIUM:
812 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
false);
813 case LoongArch::PseudoTAIL_MEDIUM:
814 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
true);
815 case LoongArch::PseudoAddUpperImm:
816 return expandAddUpperImm(
MBB,
MBBI);
822bool LoongArchExpandPseudo::expandCopyCFR(
842 MF->
insert(++
MBB.getIterator(), FalseBB);
843 MF->
insert(++FalseBB->getIterator(), SinkBB);
854 BuildMI(FalseBB,
DL,
TII->get(LoongArch::SET_CFR_TRUE), DestReg);
856 FalseBB->addSuccessor(SinkBB);
858 SinkBB->splice(SinkBB->end(), &
MBB,
MI,
MBB.end());
859 SinkBB->transferSuccessors(&
MBB);
861 MBB.addSuccessor(FalseBB);
862 MBB.addSuccessor(SinkBB);
864 NextMBBI =
MBB.end();
865 MI.eraseFromParent();
875bool LoongArchExpandPseudo::expandFunctionCALL(
904 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL;
905 Register ScratchReg = IsTailCall ? LoongArch::R20 : LoongArch::R1;
907 unsigned PC = Is64Bit ? LoongArch::PCADDU18I : LoongArch::PCADDU12I;
918 MI.setDesc(
TII->get(Opcode));
919 MI.getOperand(0).ChangeToRegister(ScratchReg,
false);
927bool LoongArchExpandPseudo::expandAddUpperImm(
934 bool DstIsDead =
MBBI->getOperand(0).isDead();
937 int64_t
Hi =
MBBI->getOperand(2).getImm();
938 bool IsLA64 = STI.is64Bit();
950 MBBI->eraseFromParent();
954bool LoongArchPreRAExpandPseudo::expandMOVCF2GRViaFR(
966 MI.getOperand(0).getReg())
968 MI.eraseFromParent();
983 return new LoongArchPreRAExpandPseudo();
986 return new LoongArchExpandPseudo();
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
static bool expandMBB(MachineBasicBlock &MBB, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NMBB, const MipsSubtarget *STI, const MipsInstrInfo *TII)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
MachineRegisterInfo & MRI
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 & setOperandDead(unsigned OpIdx) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
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 & 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.
static MachineOperand CreateImm(int64_t Val)
@ 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.
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.
static unsigned encodeFlags(unsigned Flags, bool Relax)
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.
@ Kill
The last use of a register.
@ Define
Register definition.
@ Renamable
Register that may be renamed.
constexpr RegState getDeadRegState(bool B)
constexpr RegState getRenamableRegState(bool B)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionPass * createLoongArchPreRAExpandPseudoPass()
FunctionPass * createLoongArchExpandPseudoPass()
LLVM_ABI void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().