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 FlagsHi,
unsigned SecondOpcode,
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:
165 case LoongArch::PseudoCALL_LARGE:
166 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
false);
167 case LoongArch::PseudoTAIL:
168 case LoongArch::PseudoTAIL_LARGE:
169 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
true);
170 case LoongArch::PseudoBRIND:
180bool LoongArchPreRAExpandPseudo::expandPcalau12iInstPair(
183 unsigned SecondOpcode,
unsigned FlagsLo) {
189 bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
204 if (
MI.hasOneMemOperand())
207 MI.eraseFromParent();
211bool LoongArchPreRAExpandPseudo::expandLargeAddressLoad(
214 unsigned IdentifyingMO) {
216 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LastOpcode, IdentifyingMO,
217 MI.getOperand(2),
MI.getOperand(0).getReg(),
221bool LoongArchPreRAExpandPseudo::expandLargeAddressLoad(
225 bool EraseFromParent) {
234 unsigned MO0, MO1, MO2, MO3;
235 switch (IdentifyingMO) {
266 "Large code model requires LA64");
296 const char *SymName = Symbol.getSymbolName();
297 Part0.addExternalSymbol(SymName, MO0);
298 Part1.addExternalSymbol(SymName, MO1);
299 Part2.addExternalSymbol(SymName, MO2);
300 Part3.addExternalSymbol(SymName, MO3);
302 Part0.addDisp(Symbol, 0, MO0);
303 Part1.addDisp(Symbol, 0, MO1);
304 Part2.addDisp(Symbol, 0, MO2);
305 Part3.addDisp(Symbol, 0, MO3);
309 MI.eraseFromParent();
314bool LoongArchPreRAExpandPseudo::expandLoadAddressPcrel(
320 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
328 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
333bool LoongArchPreRAExpandPseudo::expandLoadAddressGot(
339 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::LDX_D,
347 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
352bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLE(
382 unsigned AddOp = STI.
is64Bit() ? LoongArch::PseudoAddTPRel_D
383 : LoongArch::PseudoAddTPRel_W;
389 unsigned AddiOp = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
413 MI.eraseFromParent();
417bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSIE(
423 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::LDX_D,
431 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
436bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLD(
442 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
450 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
455bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSGD(
461 return expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LoongArch::ADD_D,
469 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
474bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSDesc(
482 unsigned ADD = STI.is64Bit() ? LoongArch::ADD_D : LoongArch::ADD_W;
483 unsigned ADDI = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
484 unsigned LD = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
485 bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
495 EnableRelax && !Large));
509 "Large code model requires LA64");
546 EnableRelax && !Large));
551 EnableRelax && !Large));
556 MI.eraseFromParent();
560bool LoongArchPreRAExpandPseudo::expandFunctionCALL(
579 Opcode = IsTailCall ? LoongArch::PseudoB_TAIL : LoongArch::BL;
588 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL;
596 unsigned LAOpcode = UseGOT ? LoongArch::LDX_D : LoongArch::ADD_D;
597 expandLargeAddressLoad(
MBB,
MBBI, NextMBBI, LAOpcode, MO, Func, AddrReg,
605 CALL.copyImplicitOps(
MI);
608 CALL.setMIFlags(
MI.getFlags());
610 MI.eraseFromParent();
614void LoongArchPreRAExpandPseudo::annotateTableJump(
619 bool IsFound =
false;
625 for (
auto &MO : MInst->
all_uses()) {
629 if (!
Reg.isVirtual())
634 for (
unsigned Idx = 0; Idx <
DefMI->getNumOperands(); ++Idx) {
637 MBBI->setPreInstrSymbol(
645 FindJTIMI(
DefMI, --FindDepth);
650 FindJTIMI(&*
MBBI, 3);
678char LoongArchExpandPseudo::ID = 0;
707 switch (
MBBI->getOpcode()) {
708 case LoongArch::PseudoCopyCFR:
709 return expandCopyCFR(
MBB,
MBBI, NextMBBI);
710 case LoongArch::PseudoCALL_MEDIUM:
711 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
false);
712 case LoongArch::PseudoTAIL_MEDIUM:
713 return expandFunctionCALL(
MBB,
MBBI, NextMBBI,
true);
719bool LoongArchExpandPseudo::expandCopyCFR(
739 MF->
insert(++
MBB.getIterator(), FalseBB);
740 MF->
insert(++FalseBB->getIterator(), SinkBB);
751 BuildMI(FalseBB,
DL,
TII->get(LoongArch::SET_CFR_TRUE), DestReg);
753 FalseBB->addSuccessor(SinkBB);
755 SinkBB->splice(SinkBB->end(), &
MBB,
MI,
MBB.end());
756 SinkBB->transferSuccessors(&
MBB);
758 MBB.addSuccessor(FalseBB);
759 MBB.addSuccessor(SinkBB);
761 NextMBBI =
MBB.end();
762 MI.eraseFromParent();
772bool LoongArchExpandPseudo::expandFunctionCALL(
794 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL;
795 Register ScratchReg = IsTailCall ? LoongArch::R20 : LoongArch::R1;
811 CALL.copyImplicitOps(
MI);
814 CALL.setMIFlags(
MI.getFlags());
816 MI.eraseFromParent();
831 return new LoongArchPreRAExpandPseudo();
834 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)
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.
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 & 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.
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().