@@ -61,6 +61,10 @@ class ARMInstructionSelector : public InstructionSelector {
61
61
bool selectSelect (MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const ;
62
62
bool selectShift (unsigned ShiftOpc, MachineInstrBuilder &MIB) const ;
63
63
64
+ bool selectConstantUsingPool (MachineInstrBuilder &MIB) const ;
65
+ void emitLoadFromConstantPool (const Register DefReg, const Constant *CPVal,
66
+ MachineInstrBuilder &MIB) const ;
67
+
64
68
// Check if the types match and both operands have the expected size and
65
69
// register bank.
66
70
bool validOpRegPair (MachineRegisterInfo &MRI, unsigned LHS, unsigned RHS,
@@ -812,6 +816,57 @@ bool ARMInstructionSelector::selectShift(unsigned ShiftOpc,
812
816
return constrainSelectedInstRegOperands (*MIB, TII, TRI, RBI);
813
817
}
814
818
819
+ bool ARMInstructionSelector::selectConstantUsingPool (
820
+ MachineInstrBuilder &MIB) const {
821
+ MachineInstr &MI = *MIB;
822
+ assert (MI.getOpcode () == TargetOpcode::G_CONSTANT && " Expected G_CONSTANT" );
823
+
824
+ const Register DefReg = MI.getOperand (0 ).getReg ();
825
+ MachineOperand &ConstOperand = MI.getOperand (1 );
826
+ if (!ConstOperand.isCImm ())
827
+ return false ;
828
+ const Constant *ConstVal = ConstOperand.getCImm ();
829
+ uint64_t ImmVal = ConstOperand.getCImm ()->getZExtValue ();
830
+
831
+ if (ConstantMaterializationCost (ImmVal, Subtarget) > 2 &&
832
+ !Subtarget->genExecuteOnly ()) {
833
+ emitLoadFromConstantPool (DefReg, ConstVal, MIB);
834
+ MI.eraseFromParent ();
835
+ return true ;
836
+ }
837
+
838
+ return false ;
839
+ }
840
+
841
+ void ARMInstructionSelector::emitLoadFromConstantPool (
842
+ const Register DefReg, const Constant *ConstVal,
843
+ MachineInstrBuilder &MIB) const {
844
+ MachineBasicBlock &MBB = *MIB->getParent ();
845
+ MachineFunction &MF = *MBB.getParent ();
846
+ const DataLayout &DL = MF.getDataLayout ();
847
+
848
+ auto InsertBefore = std::next (MIB->getIterator ());
849
+ auto &DbgLoc = MIB->getDebugLoc ();
850
+
851
+ Type *ConstTy = ConstVal->getType ();
852
+ unsigned Size = DL.getTypeStoreSize (ConstTy);
853
+ Align Alignment = DL.getPrefTypeAlign (ConstTy);
854
+
855
+ MachineConstantPool *Pool = MF.getConstantPool ();
856
+ unsigned ConstIndex = Pool->getConstantPoolIndex (ConstVal, Alignment);
857
+
858
+ auto Load = BuildMI (MBB, InsertBefore, DbgLoc, TII.get (ARM::LDRcp))
859
+ .addDef (DefReg)
860
+ .addConstantPoolIndex (ConstIndex)
861
+ .addImm (0 )
862
+ .add (predOps (ARMCC::AL));
863
+ MachinePointerInfo PtrInfo = MachinePointerInfo::getConstantPool (MF);
864
+ Load->addMemOperand (MF, MF.getMachineMemOperand (PtrInfo,
865
+ MachineMemOperand::MOLoad,
866
+ Size, Alignment));
867
+ constrainSelectedInstRegOperands (*Load, TII, TRI, RBI);
868
+ }
869
+
815
870
void ARMInstructionSelector::renderVFPF32Imm (
816
871
MachineInstrBuilder &NewInstBuilder, const MachineInstr &OldInst,
817
872
int OpIdx) const {
@@ -970,6 +1025,9 @@ bool ARMInstructionSelector::select(MachineInstr &I) {
970
1025
return selectCopy (I, TII, MRI, TRI, RBI);
971
1026
}
972
1027
case G_CONSTANT: {
1028
+ if (selectConstantUsingPool (MIB))
1029
+ return true ;
1030
+
973
1031
if (!MRI.getType (I.getOperand (0 ).getReg ()).isPointer ()) {
974
1032
// Non-pointer constants should be handled by TableGen.
975
1033
LLVM_DEBUG (dbgs () << " Unsupported constant type\n " );
0 commit comments