Skip to content

Commit 7628b40

Browse files
committed
[LoongArch] Ensure PseudoLA* can be hoisted
Since we mark the pseudos as mayLoad but do not provide any MMOs, isSafeToMove conservatively returns false, stopping MachineLICM from hoisting the instructions. PseudoLA_TLS_{LD,GD} does not actually expand to a load, so stop marking that as mayLoad to allow it to be hoisted, and for the others make sure to add MMOs during lowering to indicate they're GOT loads and thus can be freely moved.
1 parent df6750e commit 7628b40

File tree

5 files changed

+178
-130
lines changed

5 files changed

+178
-130
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,7 @@ SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
785785
SDLoc DL(N);
786786
EVT Ty = getPointerTy(DAG.getDataLayout());
787787
SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0);
788+
SDValue Load;
788789

789790
switch (M) {
790791
default:
@@ -796,33 +797,48 @@ SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
796797
// This is not actually used, but is necessary for successfully matching
797798
// the PseudoLA_*_LARGE nodes.
798799
SDValue Tmp = DAG.getConstant(0, DL, Ty);
799-
if (IsLocal)
800+
if (IsLocal) {
800801
// This generates the pattern (PseudoLA_PCREL_LARGE tmp sym), that
801802
// eventually becomes the desired 5-insn code sequence.
802-
return SDValue(DAG.getMachineNode(LoongArch::PseudoLA_PCREL_LARGE, DL, Ty,
803+
Load = SDValue(DAG.getMachineNode(LoongArch::PseudoLA_PCREL_LARGE, DL, Ty,
803804
Tmp, Addr),
804805
0);
805-
806-
// This generates the pattern (PseudoLA_GOT_LARGE tmp sym), that eventually
807-
// becomes the desired 5-insn code sequence.
808-
return SDValue(
809-
DAG.getMachineNode(LoongArch::PseudoLA_GOT_LARGE, DL, Ty, Tmp, Addr),
810-
0);
806+
} else {
807+
// This generates the pattern (PseudoLA_GOT_LARGE tmp sym), that
808+
// eventually becomes the desired 5-insn code sequence.
809+
Load = SDValue(
810+
DAG.getMachineNode(LoongArch::PseudoLA_GOT_LARGE, DL, Ty, Tmp, Addr),
811+
0);
812+
}
813+
break;
811814
}
812815

813816
case CodeModel::Small:
814817
case CodeModel::Medium:
815-
if (IsLocal)
818+
if (IsLocal) {
816819
// This generates the pattern (PseudoLA_PCREL sym), which expands to
817820
// (addi.w/d (pcalau12i %pc_hi20(sym)) %pc_lo12(sym)).
818-
return SDValue(
821+
Load = SDValue(
819822
DAG.getMachineNode(LoongArch::PseudoLA_PCREL, DL, Ty, Addr), 0);
823+
} else {
824+
// This generates the pattern (PseudoLA_GOT sym), which expands to (ld.w/d
825+
// (pcalau12i %got_pc_hi20(sym)) %got_pc_lo12(sym)).
826+
Load =
827+
SDValue(DAG.getMachineNode(LoongArch::PseudoLA_GOT, DL, Ty, Addr), 0);
828+
}
829+
}
820830

821-
// This generates the pattern (PseudoLA_GOT sym), which expands to (ld.w/d
822-
// (pcalau12i %got_pc_hi20(sym)) %got_pc_lo12(sym)).
823-
return SDValue(DAG.getMachineNode(LoongArch::PseudoLA_GOT, DL, Ty, Addr),
824-
0);
831+
if (!IsLocal) {
832+
MachineFunction &MF = DAG.getMachineFunction();
833+
MachineMemOperand *MemOp = MF.getMachineMemOperand(
834+
MachinePointerInfo::getGOT(MF),
835+
MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
836+
MachineMemOperand::MOInvariant,
837+
LLT(Ty.getSimpleVT()), Align(Ty.getFixedSizeInBits() / 8));
838+
DAG.setNodeMemRefs(cast<MachineSDNode>(Load.getNode()), {MemOp});
825839
}
840+
841+
return Load;
826842
}
827843

828844
SDValue LoongArchTargetLowering::lowerBlockAddress(SDValue Op,
@@ -860,7 +876,7 @@ SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op,
860876

861877
SDValue LoongArchTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
862878
SelectionDAG &DAG,
863-
unsigned Opc,
879+
unsigned Opc, bool UseGOT,
864880
bool Large) const {
865881
SDLoc DL(N);
866882
EVT Ty = getPointerTy(DAG.getDataLayout());
@@ -873,6 +889,15 @@ SDValue LoongArchTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
873889
SDValue Offset = Large
874890
? SDValue(DAG.getMachineNode(Opc, DL, Ty, Tmp, Addr), 0)
875891
: SDValue(DAG.getMachineNode(Opc, DL, Ty, Addr), 0);
892+
if (UseGOT) {
893+
MachineFunction &MF = DAG.getMachineFunction();
894+
MachineMemOperand *MemOp = MF.getMachineMemOperand(
895+
MachinePointerInfo::getGOT(MF),
896+
MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
897+
MachineMemOperand::MOInvariant,
898+
LLT(Ty.getSimpleVT()), Align(Ty.getFixedSizeInBits() / 8));
899+
DAG.setNodeMemRefs(cast<MachineSDNode>(Offset.getNode()), {MemOp});
900+
}
876901

877902
// Add the thread pointer.
878903
return DAG.getNode(ISD::ADD, DL, Ty, Offset,
@@ -972,13 +997,14 @@ LoongArchTargetLowering::lowerGlobalTLSAddress(SDValue Op,
972997
return getStaticTLSAddr(N, DAG,
973998
Large ? LoongArch::PseudoLA_TLS_IE_LARGE
974999
: LoongArch::PseudoLA_TLS_IE,
975-
Large);
1000+
/*UseGOT=*/true, Large);
9761001
case TLSModel::LocalExec:
9771002
// This model is used when static linking as the TLS offsets are resolved
9781003
// during program linking.
9791004
//
9801005
// This node doesn't need an extra argument for the large code model.
981-
return getStaticTLSAddr(N, DAG, LoongArch::PseudoLA_TLS_LE);
1006+
return getStaticTLSAddr(N, DAG, LoongArch::PseudoLA_TLS_LE,
1007+
/*UseGOT=*/false);
9821008
}
9831009

9841010
return getTLSDescAddr(N, DAG,

llvm/lib/Target/LoongArch/LoongArchISelLowering.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ class LoongArchTargetLowering : public TargetLowering {
267267
SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M,
268268
bool IsLocal = true) const;
269269
SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
270-
unsigned Opc, bool Large = false) const;
270+
unsigned Opc, bool UseGOT, bool Large = false) const;
271271
SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
272272
unsigned Opc, bool Large = false) const;
273273
SDValue getTLSDescAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,

llvm/lib/Target/LoongArch/LoongArchInstrInfo.td

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,24 +1580,33 @@ def PseudoLA_ABS_LARGE : Pseudo<(outs GPR:$dst),
15801580
"la.abs", "$dst, $src">;
15811581
def PseudoLA_PCREL : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
15821582
"la.pcrel", "$dst, $src">;
1583-
let Defs = [R20], Size = 20 in
1583+
def PseudoLA_TLS_LD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1584+
"la.tls.ld", "$dst, $src">;
1585+
def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1586+
"la.tls.gd", "$dst, $src">;
1587+
let Defs = [R20], Size = 20 in {
15841588
def PseudoLA_PCREL_LARGE : Pseudo<(outs GPR:$dst),
15851589
(ins GPR:$tmp, bare_symbol:$src), [],
15861590
"la.pcrel", "$dst, $tmp, $src">,
15871591
Requires<[IsLA64]>;
15881592
def PseudoLA_TLS_LE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
15891593
"la.tls.le", "$dst, $src">;
1594+
def PseudoLA_TLS_LD_LARGE : Pseudo<(outs GPR:$dst),
1595+
(ins GPR:$tmp, bare_symbol:$src), [],
1596+
"la.tls.ld", "$dst, $tmp, $src">,
1597+
Requires<[IsLA64]>;
1598+
def PseudoLA_TLS_GD_LARGE : Pseudo<(outs GPR:$dst),
1599+
(ins GPR:$tmp, bare_symbol:$src), [],
1600+
"la.tls.gd", "$dst, $tmp, $src">,
1601+
Requires<[IsLA64]>;
1602+
} // Defs = [R20], Size = 20
15901603
}
15911604
let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
15921605
isAsmParserOnly = 1 in {
15931606
def PseudoLA_GOT : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
15941607
"la.got", "$dst, $src">;
15951608
def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
15961609
"la.tls.ie", "$dst, $src">;
1597-
def PseudoLA_TLS_LD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1598-
"la.tls.ld", "$dst, $src">;
1599-
def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1600-
"la.tls.gd", "$dst, $src">;
16011610
let Defs = [R20], Size = 20 in {
16021611
def PseudoLA_GOT_LARGE : Pseudo<(outs GPR:$dst),
16031612
(ins GPR:$tmp, bare_symbol:$src), [],
@@ -1607,14 +1616,6 @@ def PseudoLA_TLS_IE_LARGE : Pseudo<(outs GPR:$dst),
16071616
(ins GPR:$tmp, bare_symbol:$src), [],
16081617
"la.tls.ie", "$dst, $tmp, $src">,
16091618
Requires<[IsLA64]>;
1610-
def PseudoLA_TLS_LD_LARGE : Pseudo<(outs GPR:$dst),
1611-
(ins GPR:$tmp, bare_symbol:$src), [],
1612-
"la.tls.ld", "$dst, $tmp, $src">,
1613-
Requires<[IsLA64]>;
1614-
def PseudoLA_TLS_GD_LARGE : Pseudo<(outs GPR:$dst),
1615-
(ins GPR:$tmp, bare_symbol:$src), [],
1616-
"la.tls.gd", "$dst, $tmp, $src">,
1617-
Requires<[IsLA64]>;
16181619
} // Defs = [R20], Size = 20
16191620
}
16201621

0 commit comments

Comments
 (0)