@@ -63,10 +63,9 @@ class RISCVInstructionSelector : public InstructionSelector {
63
63
// Custom selection methods
64
64
bool selectCopy (MachineInstr &MI, MachineRegisterInfo &MRI) const ;
65
65
bool materializeImm (Register Reg, int64_t Imm, MachineIRBuilder &MIB) const ;
66
- bool selectGlobalValue (MachineInstr &MI, MachineIRBuilder &MIB,
67
- MachineRegisterInfo &MRI) const ;
68
- bool selectJumpTable (MachineInstr &MI, MachineIRBuilder &MIB,
69
- MachineRegisterInfo &MRI) const ;
66
+ bool selectAddr (MachineInstr &MI, MachineIRBuilder &MIB,
67
+ MachineRegisterInfo &MRI, bool IsLocal = true ,
68
+ bool IsExternWeak = false ) const ;
70
69
bool selectSExtInreg (MachineInstr &MI, MachineIRBuilder &MIB) const ;
71
70
bool selectSelect (MachineInstr &MI, MachineIRBuilder &MIB,
72
71
MachineRegisterInfo &MRI) const ;
@@ -517,10 +516,18 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
517
516
MI.eraseFromParent ();
518
517
return true ;
519
518
}
520
- case TargetOpcode::G_GLOBAL_VALUE:
521
- return selectGlobalValue (MI, MIB, MRI);
519
+ case TargetOpcode::G_GLOBAL_VALUE: {
520
+ auto *GV = MI.getOperand (1 ).getGlobal ();
521
+ if (GV->isThreadLocal ()) {
522
+ // TODO: implement this case.
523
+ return false ;
524
+ }
525
+
526
+ return selectAddr (MI, MIB, MRI, GV->isDSOLocal (),
527
+ GV->hasExternalWeakLinkage ());
528
+ }
522
529
case TargetOpcode::G_JUMP_TABLE:
523
- return selectJumpTable (MI, MIB, MRI);
530
+ return selectAddr (MI, MIB, MRI);
524
531
case TargetOpcode::G_BRCOND: {
525
532
Register LHS, RHS;
526
533
RISCVCC::CondCode CC;
@@ -760,16 +767,16 @@ bool RISCVInstructionSelector::materializeImm(Register DstReg, int64_t Imm,
760
767
return true ;
761
768
}
762
769
763
- bool RISCVInstructionSelector::selectGlobalValue (
764
- MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI) const {
765
- assert (MI.getOpcode () == TargetOpcode::G_GLOBAL_VALUE &&
766
- " Expected G_GLOBAL_VALUE" );
770
+ bool RISCVInstructionSelector::selectAddr (MachineInstr &MI,
771
+ MachineIRBuilder &MIB,
772
+ MachineRegisterInfo &MRI,
773
+ bool IsLocal,
774
+ bool IsExternWeak) const {
775
+ assert ((MI.getOpcode () == TargetOpcode::G_GLOBAL_VALUE ||
776
+ MI.getOpcode () == TargetOpcode::G_JUMP_TABLE) &&
777
+ " Unexpected opcode" );
767
778
768
- auto *GV = MI.getOperand (1 ).getGlobal ();
769
- if (GV->isThreadLocal ()) {
770
- // TODO: implement this case.
771
- return false ;
772
- }
779
+ const MachineOperand &DispMO = MI.getOperand (1 );
773
780
774
781
Register DefReg = MI.getOperand (0 ).getReg ();
775
782
const LLT DefTy = MRI.getType (DefReg);
@@ -780,12 +787,12 @@ bool RISCVInstructionSelector::selectGlobalValue(
780
787
// is incompatible with existing code models. This also applies to non-pic
781
788
// mode.
782
789
if (TM.isPositionIndependent () || Subtarget->allowTaggedGlobals ()) {
783
- if (GV-> isDSOLocal () && !Subtarget->allowTaggedGlobals ()) {
790
+ if (IsLocal && !Subtarget->allowTaggedGlobals ()) {
784
791
// Use PC-relative addressing to access the symbol. This generates the
785
792
// pattern (PseudoLLA sym), which expands to (addi (auipc %pcrel_hi(sym))
786
793
// %pcrel_lo(auipc)).
787
794
Result =
788
- MIB.buildInstr (RISCV::PseudoLLA, {DefReg}, {}).addGlobalAddress (GV );
795
+ MIB.buildInstr (RISCV::PseudoLLA, {DefReg}, {}).addDisp (DispMO, 0 );
789
796
} else {
790
797
// Use PC-relative addressing to access the GOT for this symbol, then
791
798
// load the address from the GOT. This generates the pattern (PseudoLGA
@@ -799,7 +806,7 @@ bool RISCVInstructionSelector::selectGlobalValue(
799
806
DefTy, Align (DefTy.getSizeInBits () / 8 ));
800
807
801
808
Result = MIB.buildInstr (RISCV::PseudoLGA, {DefReg}, {})
802
- .addGlobalAddress (GV )
809
+ .addDisp (DispMO, 0 )
803
810
.addMemOperand (MemOp);
804
811
}
805
812
@@ -822,26 +829,26 @@ bool RISCVInstructionSelector::selectGlobalValue(
822
829
// (lui %hi(sym)) %lo(sym)).
823
830
Register AddrHiDest = MRI.createVirtualRegister (&RISCV::GPRRegClass);
824
831
MachineInstr *AddrHi = MIB.buildInstr (RISCV::LUI, {AddrHiDest}, {})
825
- .addGlobalAddress (GV , 0 , RISCVII::MO_HI);
832
+ .addDisp (DispMO , 0 , RISCVII::MO_HI);
826
833
827
834
if (!constrainSelectedInstRegOperands (*AddrHi, TII, TRI, RBI))
828
835
return false ;
829
836
830
837
Result = MIB.buildInstr (RISCV::ADDI, {DefReg}, {AddrHiDest})
831
- .addGlobalAddress (GV , 0 , RISCVII::MO_LO);
838
+ .addDisp (DispMO , 0 , RISCVII::MO_LO);
832
839
833
840
if (!constrainSelectedInstRegOperands (*Result, TII, TRI, RBI))
834
841
return false ;
835
842
836
843
MI.eraseFromParent ();
837
844
return true ;
838
845
}
839
- case CodeModel::Medium: {
846
+ case CodeModel::Medium:
840
847
// Emit LGA/LLA instead of the sequence it expands to because the pcrel_lo
841
848
// relocation needs to reference a label that points to the auipc
842
849
// instruction itself, not the global. This cannot be done inside the
843
850
// instruction selector.
844
- if (GV-> hasExternalWeakLinkage () ) {
851
+ if (IsExternWeak ) {
845
852
// An extern weak symbol may be undefined, i.e. have value 0, which may
846
853
// not be within 2GiB of PC, so use GOT-indirect addressing to access the
847
854
// symbol. This generates the pattern (PseudoLGA sym), which expands to
@@ -854,65 +861,14 @@ bool RISCVInstructionSelector::selectGlobalValue(
854
861
DefTy, Align (DefTy.getSizeInBits () / 8 ));
855
862
856
863
Result = MIB.buildInstr (RISCV::PseudoLGA, {DefReg}, {})
857
- .addGlobalAddress (GV )
864
+ .addDisp (DispMO, 0 )
858
865
.addMemOperand (MemOp);
859
866
} else {
860
867
// Generate a sequence for accessing addresses within any 2GiB range
861
868
// within the address space. This generates the pattern (PseudoLLA sym),
862
869
// which expands to (addi (auipc %pcrel_hi(sym)) %pcrel_lo(auipc)).
863
870
Result =
864
- MIB.buildInstr (RISCV::PseudoLLA, {DefReg}, {}).addGlobalAddress (GV);
865
- }
866
-
867
- if (!constrainSelectedInstRegOperands (*Result, TII, TRI, RBI))
868
- return false ;
869
-
870
- MI.eraseFromParent ();
871
- return true ;
872
- }
873
- }
874
- return false ;
875
- }
876
-
877
- // FIXME: This is very similar to selectGlobalValue. Merge somehow?
878
- bool RISCVInstructionSelector::selectJumpTable (MachineInstr &MI,
879
- MachineIRBuilder &MIB,
880
- MachineRegisterInfo &MRI) const {
881
- assert (MI.getOpcode () == TargetOpcode::G_JUMP_TABLE &&
882
- " Expected G_JUMP_TABLE" );
883
-
884
- int Idx = MI.getOperand (1 ).getIndex ();
885
-
886
- Register DefReg = MI.getOperand (0 ).getReg ();
887
- const LLT DefTy = MRI.getType (DefReg);
888
- MachineInstr *Result = nullptr ;
889
-
890
- // When HWASAN is used and tagging of global variables is enabled
891
- // they should be accessed via the GOT, since the tagged address of a global
892
- // is incompatible with existing code models. This also applies to non-pic
893
- // mode.
894
- if (TM.isPositionIndependent () || Subtarget->allowTaggedGlobals ()) {
895
- if (!Subtarget->allowTaggedGlobals ()) {
896
- // Use PC-relative addressing to access the symbol. This generates the
897
- // pattern (PseudoLLA sym), which expands to (addi (auipc %pcrel_hi(sym))
898
- // %pcrel_lo(auipc)).
899
- Result =
900
- MIB.buildInstr (RISCV::PseudoLLA, {DefReg}, {}).addJumpTableIndex (Idx);
901
- } else {
902
- // Use PC-relative addressing to access the GOT for this symbol, then
903
- // load the address from the GOT. This generates the pattern (PseudoLGA
904
- // sym), which expands to (ld (addi (auipc %got_pcrel_hi(sym))
905
- // %pcrel_lo(auipc))).
906
- MachineFunction &MF = *MI.getParent ()->getParent ();
907
- MachineMemOperand *MemOp = MF.getMachineMemOperand (
908
- MachinePointerInfo::getGOT (MF),
909
- MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
910
- MachineMemOperand::MOInvariant,
911
- DefTy, Align (DefTy.getSizeInBits () / 8 ));
912
-
913
- Result = MIB.buildInstr (RISCV::PseudoLGA, {DefReg}, {})
914
- .addJumpTableIndex (Idx)
915
- .addMemOperand (MemOp);
871
+ MIB.buildInstr (RISCV::PseudoLLA, {DefReg}, {}).addDisp (DispMO, 0 );
916
872
}
917
873
918
874
if (!constrainSelectedInstRegOperands (*Result, TII, TRI, RBI))
@@ -922,46 +878,6 @@ bool RISCVInstructionSelector::selectJumpTable(MachineInstr &MI,
922
878
return true ;
923
879
}
924
880
925
- switch (TM.getCodeModel ()) {
926
- default : {
927
- reportGISelFailure (const_cast <MachineFunction &>(*MF), *TPC, *MORE,
928
- getName (), " Unsupported code model for lowering" , MI);
929
- return false ;
930
- }
931
- case CodeModel::Small: {
932
- // Must lie within a single 2 GiB address range and must lie between
933
- // absolute addresses -2 GiB and +2 GiB. This generates the pattern (addi
934
- // (lui %hi(sym)) %lo(sym)).
935
- Register AddrHiDest = MRI.createVirtualRegister (&RISCV::GPRRegClass);
936
- MachineInstr *AddrHi = MIB.buildInstr (RISCV::LUI, {AddrHiDest}, {})
937
- .addJumpTableIndex (Idx, RISCVII::MO_HI);
938
-
939
- if (!constrainSelectedInstRegOperands (*AddrHi, TII, TRI, RBI))
940
- return false ;
941
-
942
- Result = MIB.buildInstr (RISCV::ADDI, {DefReg}, {AddrHiDest})
943
- .addJumpTableIndex (Idx, RISCVII::MO_LO);
944
-
945
- if (!constrainSelectedInstRegOperands (*Result, TII, TRI, RBI))
946
- return false ;
947
-
948
- MI.eraseFromParent ();
949
- return true ;
950
- }
951
- case CodeModel::Medium: {
952
- // Generate a sequence for accessing addresses within any 2GiB range
953
- // within the address space. This generates the pattern (PseudoLLA sym),
954
- // which expands to (addi (auipc %pcrel_hi(sym)) %pcrel_lo(auipc)).
955
- Result =
956
- MIB.buildInstr (RISCV::PseudoLLA, {DefReg}, {}).addJumpTableIndex (Idx);
957
-
958
- if (!constrainSelectedInstRegOperands (*Result, TII, TRI, RBI))
959
- return false ;
960
-
961
- MI.eraseFromParent ();
962
- return true ;
963
- }
964
- }
965
881
return false ;
966
882
}
967
883
0 commit comments