Skip to content

Commit 7c7fe51

Browse files
committed
[GlobalISel][ARM] Selection of G_CONSTANT using constant pool
Some constants cannot be represented as immediate operands. They can be loaded from constant pool. This change implement selection of such constants in the same way as the DAG selector uses.
1 parent 8949290 commit 7c7fe51

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

llvm/lib/Target/ARM/ARMInstructionSelector.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class ARMInstructionSelector : public InstructionSelector {
6161
bool selectSelect(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const;
6262
bool selectShift(unsigned ShiftOpc, MachineInstrBuilder &MIB) const;
6363

64+
bool selectConstantUsingPool(MachineInstrBuilder &MIB) const;
65+
void emitLoadFromConstantPool(const Register DefReg, const Constant *CPVal,
66+
MachineInstrBuilder &MIB) const;
67+
6468
// Check if the types match and both operands have the expected size and
6569
// register bank.
6670
bool validOpRegPair(MachineRegisterInfo &MRI, unsigned LHS, unsigned RHS,
@@ -812,6 +816,57 @@ bool ARMInstructionSelector::selectShift(unsigned ShiftOpc,
812816
return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
813817
}
814818

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+
815870
void ARMInstructionSelector::renderVFPF32Imm(
816871
MachineInstrBuilder &NewInstBuilder, const MachineInstr &OldInst,
817872
int OpIdx) const {
@@ -970,6 +1025,9 @@ bool ARMInstructionSelector::select(MachineInstr &I) {
9701025
return selectCopy(I, TII, MRI, TRI, RBI);
9711026
}
9721027
case G_CONSTANT: {
1028+
if (selectConstantUsingPool(MIB))
1029+
return true;
1030+
9731031
if (!MRI.getType(I.getOperand(0).getReg()).isPointer()) {
9741032
// Non-pointer constants should be handled by TableGen.
9751033
LLVM_DEBUG(dbgs() << "Unsupported constant type\n");

llvm/test/CodeGen/ARM/GlobalISel/select-const.mir

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,22 @@ body: |
2323
MOVPCLR 14 /* CC::al */, $noreg, implicit $r0
2424
2525
...
26+
---
27+
name: get_from_constpool
28+
legalized: true
29+
regBankSelected: true
30+
selected: false
31+
tracksRegLiveness: true
32+
registers:
33+
- { id: 0, class: gprb, preferred-register: '' }
34+
body: |
35+
bb.1.entry:
36+
; CHECK-LABEL: name: get_from_constpool
37+
; CHECK: [[LDRcp:%[0-9]+]]:gpr = LDRcp %const.0, 0, 14 /* CC::al */, $noreg :: (load (s32) from constant-pool)
38+
; CHECK-NEXT: $r0 = COPY [[LDRcp]]
39+
; CHECK-NEXT: BX_RET 14 /* CC::al */, $noreg, implicit $r0
40+
%0:gprb(s32) = G_CONSTANT i32 287454020
41+
$r0 = COPY %0(s32)
42+
BX_RET 14 /* CC::al */, $noreg, implicit $r0
43+
44+
...

0 commit comments

Comments
 (0)