summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-04-16 11:52:51 +0000
committerTim Northover <tnorthover@apple.com>2014-04-16 11:52:51 +0000
commitfef8e383eb8c0dc534c7cac98b3670dec2cc86fb (patch)
tree30177c4f31c2bff05701633d347412f874b22353 /lib
parentea9988a81231d4097efe6799f7e2f4922dab2d7f (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.cpp16
-rw-r--r--lib/Target/ARM64/ARM64InstrInfo.td16
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),