summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
diff options
context:
space:
mode:
authorJessica Paquette <jpaquette@apple.com>2019-08-23 20:31:34 +0000
committerJessica Paquette <jpaquette@apple.com>2019-08-23 20:31:34 +0000
commit83fe56b3b95672be8f64f32f4f472bedca402369 (patch)
treec64bac01d8eb0e11351d4eb9ac4fad3d01a58d80 /llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
parent277631e3b8dda9afaa5ddc16e69116455e68ae87 (diff)
downloadbcm5719-llvm-83fe56b3b95672be8f64f32f4f472bedca402369.tar.gz
bcm5719-llvm-83fe56b3b95672be8f64f32f4f472bedca402369.zip
[AArch64][GlobalISel] Import XRO load/store patterns instead of custom selection
Instead of using custom C++ in `earlySelect` for loads and stores, just import the patterns. Remove `earlySelectLoad`, since we can just import the work it's doing. Some minor changes to how `ComplexRendererFns` are returned for the XRO addressing modes. If you add immediates in two steps, sometimes they are not imported properly and you only end up with one immediate. I'm not sure if this is intentional. - Update load-addressing-modes.mir to include the instructions we can now import. - Add a similar test, store-addressing-modes.mir to show which store opcodes we currently import, and show that we can pull in shifts etc. - Update arm64-fastisel-gep-promote-before-add.ll to use FastISel instead of GISel. This test failed with GISel because GISel folds the gep into the load. The test checks that FastISel doesn't fold non-pointer-width adds into loads. GISel on the other hand, produces a G_CONSTANT of -128 for the add, and then a G_GEP, which must be pointer-width. Note that we don't get STRBRoX right now. It seems like the importer can't handle `FPR8Op:{ *:[Untyped] }:$Rt` source operands. So, those are not currently supported. Differential Revision: https://reviews.llvm.org/D66679 llvm-svn: 369806
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp')
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp92
1 files changed, 26 insertions, 66 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
index 8958b09a032..15493ec6852 100644
--- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -76,7 +76,6 @@ private:
bool earlySelect(MachineInstr &I) const;
bool earlySelectSHL(MachineInstr &I, MachineRegisterInfo &MRI) const;
- bool earlySelectLoad(MachineInstr &I, MachineRegisterInfo &MRI) const;
/// Eliminate same-sized cross-bank copies into stores before selectImpl().
void contractCrossBankCopyIntoStore(MachineInstr &I,
@@ -208,6 +207,10 @@ private:
ComplexRendererFns selectAddrModeRegisterOffset(MachineOperand &Root) const;
ComplexRendererFns selectAddrModeXRO(MachineOperand &Root,
unsigned SizeInBytes) const;
+ template <int Width>
+ ComplexRendererFns selectAddrModeXRO(MachineOperand &Root) const {
+ return selectAddrModeXRO(Root, Width / 8);
+ }
ComplexRendererFns selectShiftedRegister(MachineOperand &Root) const;
@@ -1246,57 +1249,6 @@ void AArch64InstructionSelector::contractCrossBankCopyIntoStore(
I.getOperand(0).setReg(DefDstReg);
}
-bool AArch64InstructionSelector::earlySelectLoad(
- MachineInstr &I, MachineRegisterInfo &MRI) const {
- // Try to fold in shifts, etc into the addressing mode of a load.
- assert(I.getOpcode() == TargetOpcode::G_LOAD && "unexpected op");
-
- // Don't handle atomic loads/stores yet.
- auto &MemOp = **I.memoperands_begin();
- if (MemOp.isAtomic()) {
- LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
- return false;
- }
-
- unsigned MemBytes = MemOp.getSize();
-
- // Only support 64-bit loads for now.
- if (MemBytes != 8)
- return false;
-
- Register DstReg = I.getOperand(0).getReg();
- const LLT DstTy = MRI.getType(DstReg);
- // Don't handle vectors.
- if (DstTy.isVector())
- return false;
-
- unsigned DstSize = DstTy.getSizeInBits();
- // TODO: 32-bit destinations.
- if (DstSize != 64)
- return false;
-
- // Check if we can do any folding from GEPs/shifts etc. into the load.
- auto ImmFn = selectAddrModeXRO(I.getOperand(1), MemBytes);
- if (!ImmFn)
- return false;
-
- // We can fold something. Emit the load here.
- MachineIRBuilder MIB(I);
-
- // Choose the instruction based off the size of the element being loaded, and
- // whether or not we're loading into a FPR.
- const RegisterBank &RB = *RBI.getRegBank(DstReg, MRI, TRI);
- unsigned Opc =
- RB.getID() == AArch64::GPRRegBankID ? AArch64::LDRXroX : AArch64::LDRDroX;
- // Construct the load.
- auto LoadMI = MIB.buildInstr(Opc, {DstReg}, {});
- for (auto &RenderFn : *ImmFn)
- RenderFn(LoadMI);
- LoadMI.addMemOperand(*I.memoperands_begin());
- I.eraseFromParent();
- return constrainSelectedInstRegOperands(*LoadMI, TII, TRI, RBI);
-}
-
bool AArch64InstructionSelector::earlySelect(MachineInstr &I) const {
assert(I.getParent() && "Instruction should be in a basic block!");
assert(I.getParent()->getParent() && "Instruction should be in a function!");
@@ -1308,8 +1260,6 @@ bool AArch64InstructionSelector::earlySelect(MachineInstr &I) const {
switch (I.getOpcode()) {
case TargetOpcode::G_SHL:
return earlySelectSHL(I, MRI);
- case TargetOpcode::G_LOAD:
- return earlySelectLoad(I, MRI);
case TargetOpcode::G_CONSTANT: {
bool IsZero = false;
if (I.getOperand(1).isCImm())
@@ -4342,12 +4292,16 @@ AArch64InstructionSelector::selectAddrModeShiftedExtendXReg(
// We can use the LHS of the GEP as the base, and the LHS of the shift as an
// offset. Signify that we are shifting by setting the shift flag to 1.
- return {{
- [=](MachineInstrBuilder &MIB) { MIB.add(Gep->getOperand(1)); },
- [=](MachineInstrBuilder &MIB) { MIB.addUse(OffsetReg); },
- [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
- [=](MachineInstrBuilder &MIB) { MIB.addImm(1); },
- }};
+ return {{[=](MachineInstrBuilder &MIB) {
+ MIB.addUse(Gep->getOperand(1).getReg());
+ },
+ [=](MachineInstrBuilder &MIB) { MIB.addUse(OffsetReg); },
+ [=](MachineInstrBuilder &MIB) {
+ // Need to add both immediates here to make sure that they are both
+ // added to the instruction.
+ MIB.addImm(0);
+ MIB.addImm(1);
+ }}};
}
/// This is used for computing addresses like this:
@@ -4375,12 +4329,18 @@ AArch64InstructionSelector::selectAddrModeRegisterOffset(
return None;
// Base is the GEP's LHS, offset is its RHS.
- return {{
- [=](MachineInstrBuilder &MIB) { MIB.add(Gep->getOperand(1)); },
- [=](MachineInstrBuilder &MIB) { MIB.add(Gep->getOperand(2)); },
- [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
- [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
- }};
+ return {{[=](MachineInstrBuilder &MIB) {
+ MIB.addUse(Gep->getOperand(1).getReg());
+ },
+ [=](MachineInstrBuilder &MIB) {
+ MIB.addUse(Gep->getOperand(2).getReg());
+ },
+ [=](MachineInstrBuilder &MIB) {
+ // Need to add both immediates here to make sure that they are both
+ // added to the instruction.
+ MIB.addImm(0);
+ MIB.addImm(0);
+ }}};
}
/// This is intended to be equivalent to selectAddrModeXRO in
OpenPOWER on IntegriCloud