@@ -785,6 +785,7 @@ SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
785
785
SDLoc DL (N);
786
786
EVT Ty = getPointerTy (DAG.getDataLayout ());
787
787
SDValue Addr = getTargetNode (N, DL, Ty, DAG, 0 );
788
+ SDValue Load;
788
789
789
790
switch (M) {
790
791
default :
@@ -796,33 +797,49 @@ SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
796
797
// This is not actually used, but is necessary for successfully matching
797
798
// the PseudoLA_*_LARGE nodes.
798
799
SDValue Tmp = DAG.getConstant (0 , DL, Ty);
799
- if (IsLocal)
800
+ if (IsLocal) {
800
801
// This generates the pattern (PseudoLA_PCREL_LARGE tmp sym), that
801
802
// 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,
803
804
Tmp, Addr),
804
805
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 ;
811
814
}
812
815
813
816
case CodeModel::Small:
814
817
case CodeModel::Medium:
815
- if (IsLocal)
818
+ if (IsLocal) {
816
819
// This generates the pattern (PseudoLA_PCREL sym), which expands to
817
820
// (addi.w/d (pcalau12i %pc_hi20(sym)) %pc_lo12(sym)).
818
- return SDValue (
821
+ Load = SDValue (
819
822
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
+ }
820
830
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
+ // Mark the load instruction as invariant to enable hoisting in MachineLICM.
833
+ MachineFunction &MF = DAG.getMachineFunction ();
834
+ MachineMemOperand *MemOp = MF.getMachineMemOperand (
835
+ MachinePointerInfo::getGOT (MF),
836
+ MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
837
+ MachineMemOperand::MOInvariant,
838
+ LLT (Ty.getSimpleVT ()), Align (Ty.getFixedSizeInBits () / 8 ));
839
+ DAG.setNodeMemRefs (cast<MachineSDNode>(Load.getNode ()), {MemOp});
825
840
}
841
+
842
+ return Load;
826
843
}
827
844
828
845
SDValue LoongArchTargetLowering::lowerBlockAddress (SDValue Op,
@@ -860,7 +877,7 @@ SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op,
860
877
861
878
SDValue LoongArchTargetLowering::getStaticTLSAddr (GlobalAddressSDNode *N,
862
879
SelectionDAG &DAG,
863
- unsigned Opc,
880
+ unsigned Opc, bool UseGOT,
864
881
bool Large) const {
865
882
SDLoc DL (N);
866
883
EVT Ty = getPointerTy (DAG.getDataLayout ());
@@ -873,6 +890,16 @@ SDValue LoongArchTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
873
890
SDValue Offset = Large
874
891
? SDValue (DAG.getMachineNode (Opc, DL, Ty, Tmp, Addr), 0 )
875
892
: SDValue (DAG.getMachineNode (Opc, DL, Ty, Addr), 0 );
893
+ if (UseGOT) {
894
+ // Mark the load instruction as invariant to enable hoisting in MachineLICM.
895
+ MachineFunction &MF = DAG.getMachineFunction ();
896
+ MachineMemOperand *MemOp = MF.getMachineMemOperand (
897
+ MachinePointerInfo::getGOT (MF),
898
+ MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
899
+ MachineMemOperand::MOInvariant,
900
+ LLT (Ty.getSimpleVT ()), Align (Ty.getFixedSizeInBits () / 8 ));
901
+ DAG.setNodeMemRefs (cast<MachineSDNode>(Offset.getNode ()), {MemOp});
902
+ }
876
903
877
904
// Add the thread pointer.
878
905
return DAG.getNode (ISD::ADD, DL, Ty, Offset,
@@ -976,13 +1003,14 @@ LoongArchTargetLowering::lowerGlobalTLSAddress(SDValue Op,
976
1003
return getStaticTLSAddr (N, DAG,
977
1004
Large ? LoongArch::PseudoLA_TLS_IE_LARGE
978
1005
: LoongArch::PseudoLA_TLS_IE,
979
- Large);
1006
+ /* UseGOT= */ true , Large);
980
1007
case TLSModel::LocalExec:
981
1008
// This model is used when static linking as the TLS offsets are resolved
982
1009
// during program linking.
983
1010
//
984
1011
// This node doesn't need an extra argument for the large code model.
985
- return getStaticTLSAddr (N, DAG, LoongArch::PseudoLA_TLS_LE);
1012
+ return getStaticTLSAddr (N, DAG, LoongArch::PseudoLA_TLS_LE,
1013
+ /* UseGOT=*/ false );
986
1014
}
987
1015
988
1016
return getTLSDescAddr (N, DAG,
0 commit comments