diff options
author | Tim Northover <tnorthover@apple.com> | 2014-04-16 11:52:51 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2014-04-16 11:52:51 +0000 |
commit | fef8e383eb8c0dc534c7cac98b3670dec2cc86fb (patch) | |
tree | 30177c4f31c2bff05701633d347412f874b22353 /lib | |
parent | ea9988a81231d4097efe6799f7e2f4922dab2d7f (diff) |
ARM64: use 32-bit moves for constants where possible.
If we know that a particular 64-bit constant has all high bits zero, then we
can rely on the fact that 32-bit ARM64 instructions automatically zero out the
high bits of an x-register. This gives the expansion logic less constraints to
satisfy and so sometimes allows it to pick better sequences.
Came up while porting test/CodeGen/AArch64/movw-consts.ll: this will allow a
32-bit MOVN to be used in @test8 soon.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206379 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp | 16 | ||||
-rw-r--r-- | lib/Target/ARM64/ARM64InstrInfo.td | 16 |
2 files changed, 24 insertions, 8 deletions
diff --git a/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp b/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp index 5d2afae3fff..7d2a97f8e72 100644 --- a/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp +++ b/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp @@ -28,7 +28,7 @@ namespace { class ARM64DeadRegisterDefinitions : public MachineFunctionPass { private: const TargetRegisterInfo *TRI; - bool implicitlyDefinesSubReg(unsigned Reg, const MachineInstr &MI); + bool implicitlyDefinesOverlappingReg(unsigned Reg, const MachineInstr &MI); bool processMachineBasicBlock(MachineBasicBlock &MBB); bool usesFrameIndex(const MachineInstr &MI); public: @@ -47,12 +47,11 @@ public: char ARM64DeadRegisterDefinitions::ID = 0; } // end anonymous namespace -bool -ARM64DeadRegisterDefinitions::implicitlyDefinesSubReg(unsigned Reg, - const MachineInstr &MI) { +bool ARM64DeadRegisterDefinitions::implicitlyDefinesOverlappingReg( + unsigned Reg, const MachineInstr &MI) { for (const MachineOperand &MO : MI.implicit_operands()) if (MO.isReg() && MO.isDef()) - if (TRI->isSubRegister(Reg, MO.getReg())) + if (TRI->regsOverlap(Reg, MO.getReg())) return true; return false; } @@ -86,9 +85,10 @@ ARM64DeadRegisterDefinitions::processMachineBasicBlock(MachineBasicBlock &MBB) { DEBUG(dbgs() << " Ignoring, def is tied operand.\n"); continue; } - // Don't change the register if there's an implicit def of a subreg. - if (implicitlyDefinesSubReg(MO.getReg(), MI)) { - DEBUG(dbgs() << " Ignoring, implicitly defines subregister.\n"); + // Don't change the register if there's an implicit def of a subreg or + // supperreg. + if (implicitlyDefinesOverlappingReg(MO.getReg(), MI)) { + DEBUG(dbgs() << " Ignoring, implicitly defines overlap reg.\n"); continue; } // Make sure the instruction take a register class that contains diff --git a/lib/Target/ARM64/ARM64InstrInfo.td b/lib/Target/ARM64/ARM64InstrInfo.td index 9f599eb2355..69f1e2c5a6d 100644 --- a/lib/Target/ARM64/ARM64InstrInfo.td +++ b/lib/Target/ARM64/ARM64InstrInfo.td @@ -395,6 +395,22 @@ def MOVi64imm Sched<[WriteImm]>; } // isReMaterializable, isCodeGenOnly +// If possible, we want to use MOVi32imm even for 64-bit moves. This gives the +// eventual expansion code fewer bits to worry about getting right. Marshalling +// the types is a little tricky though: +def i64imm_32bit : ImmLeaf<i64, [{ + return (Imm & 0xffffffffULL) == Imm; +}]>; + +def trunc_imm : SDNodeXForm<imm, [{ + return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i32); +}]>; + +def : Pat<(i64 i64imm_32bit:$src), + (SUBREG_TO_REG (i64 0), (MOVi32imm (trunc_imm imm:$src)), sub_32)>; + +// Deal with the various forms of (ELF) large addressing with MOVZ/MOVK +// sequences. def : Pat<(ARM64WrapperLarge tglobaladdr:$g3, tglobaladdr:$g2, tglobaladdr:$g1, tglobaladdr:$g0), (MOVKXi (MOVKXi (MOVKXi (MOVZXi tglobaladdr:$g3, 48), |