From: Tim Northover Date: Fri, 15 Feb 2013 09:33:26 +0000 (+0000) Subject: AArch64: refactor frame handling to use movz/movk for overlarge offsets. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5466e36fb5887ba3f9fa84e75024cedb147469bc;p=platform%2Fupstream%2Fllvm.git AArch64: refactor frame handling to use movz/movk for overlarge offsets. In the near future litpools will be in a different section, which means that any access to them is at least two instructions. This makes the case for a movz/movk pair (if total offset <= 32-bits) even more compelling. llvm-svn: 175257 --- diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 94b3429..9a7504a 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -623,18 +623,35 @@ void llvm::emitRegUpdate(MachineBasicBlock &MBB, else if (abs(NumBytes) & ~0xffffff) { // Generically, we have to materialize the offset into a temporary register // and subtract it. There are a couple of ways this could be done, for now - // we'll go for a literal-pool load. - MachineFunction &MF = *MBB.getParent(); - MachineConstantPool *MCP = MF.getConstantPool(); - const Constant *C - = ConstantInt::get(Type::getInt64Ty(MF.getFunction()->getContext()), - abs(NumBytes)); - unsigned CPI = MCP->getConstantPoolIndex(C, 8); - - // LDR xTMP, .LITPOOL - BuildMI(MBB, MBBI, dl, TII.get(AArch64::LDRx_lit), ScratchReg) - .addConstantPoolIndex(CPI) - .setMIFlag(MIFlags); + // we'll use a movz/movk or movn/movk sequence. + uint64_t Bits = static_cast(abs(NumBytes)); + BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVZxii), ScratchReg) + .addImm(0xffff & Bits).addImm(0) + .setMIFlags(MIFlags); + + Bits >>= 16; + if (Bits & 0xffff) { + BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg) + .addReg(ScratchReg) + .addImm(0xffff & Bits).addImm(1) + .setMIFlags(MIFlags); + } + + Bits >>= 16; + if (Bits & 0xffff) { + BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg) + .addReg(ScratchReg) + .addImm(0xffff & Bits).addImm(2) + .setMIFlags(MIFlags); + } + + Bits >>= 16; + if (Bits & 0xffff) { + BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg) + .addReg(ScratchReg) + .addImm(0xffff & Bits).addImm(3) + .setMIFlags(MIFlags); + } // ADD DST, SRC, xTMP (, lsl #0) unsigned AddOp = NumBytes > 0 ? AArch64::ADDxxx_uxtx : AArch64::SUBxxx_uxtx; diff --git a/llvm/test/CodeGen/AArch64/large-frame.ll b/llvm/test/CodeGen/AArch64/large-frame.ll index 61690d7..2b2e129 100644 --- a/llvm/test/CodeGen/AArch64/large-frame.ll +++ b/llvm/test/CodeGen/AArch64/large-frame.ll @@ -11,17 +11,22 @@ define void @test_bigframe() { %var3 = alloca i8, i32 20000000 ; CHECK: sub sp, sp, #496 ; CHECK: str x30, [sp, #488] -; CHECK: ldr [[FRAMEOFFSET:x[0-9]+]], [[FRAMEOFFSET_CPI:.LCPI0_[0-9]+]] -; CHECK: sub sp, sp, [[FRAMEOFFSET]] - -; CHECK: ldr [[VAR1OFFSET:x[0-9]+]], [[VAR1LOC_CPI:.LCPI0_[0-9]+]] + ; Total adjust is 39999536 +; CHECK: movz [[SUBCONST:x[0-9]+]], #22576 +; CHECK: movk [[SUBCONST]], #610, lsl #16 +; CHECK: sub sp, sp, [[SUBCONST]] + + ; Total offset is 20000024 +; CHECK: movz [[VAR1OFFSET:x[0-9]+]], #11544 +; CHECK: movk [[VAR1OFFSET]], #305, lsl #16 ; CHECK: add {{x[0-9]+}}, sp, [[VAR1OFFSET]] store volatile i8* %var1, i8** @addr %var1plus2 = getelementptr i8* %var1, i32 2 store volatile i8* %var1plus2, i8** @addr -; CHECK: ldr [[VAR2OFFSET:x[0-9]+]], [[VAR2LOC_CPI:.LCPI0_[0-9]+]] +; CHECK: movz [[VAR2OFFSET:x[0-9]+]], #11528 +; CHECK: movk [[VAR2OFFSET]], #305, lsl #16 ; CHECK: add {{x[0-9]+}}, sp, [[VAR2OFFSET]] store volatile i8* %var2, i8** @addr @@ -33,18 +38,10 @@ define void @test_bigframe() { %var3plus2 = getelementptr i8* %var3, i32 2 store volatile i8* %var3plus2, i8** @addr -; CHECK: ldr [[FRAMEOFFSET:x[0-9]+]], [[FRAMEOFFSET_CPI]] -; CHECK: add sp, sp, [[FRAMEOFFSET]] +; CHECK: movz [[ADDCONST:x[0-9]+]], #22576 +; CHECK: movk [[ADDCONST]], #610, lsl #16 +; CHECK: add sp, sp, [[ADDCONST]] ret void - -; CHECK: [[FRAMEOFFSET_CPI]]: -; CHECK-NEXT: 39999536 - -; CHECK: [[VAR1LOC_CPI]]: -; CHECK-NEXT: 20000024 - -; CHECK: [[VAR2LOC_CPI]]: -; CHECK-NEXT: 20000008 } define void @test_mediumframe() { @@ -103,10 +100,10 @@ define void @test_tempallocation([8 x i64] %val) nounwind { ; CHECK-NEXT: stp x19, x20, [sp, ; Make sure we don't trash an argument register -; CHECK-NOT: ldr {{x[0-7]}}, .LCPI1 +; CHECK-NOT: movz {{x[0-7],}} ; CHECK: sub sp, sp, -; CHECK-NOT: ldr {{x[0-7]}}, .LCPI1 +; CHECK-NOT: movz {{x[0-7],}} ; CHECK: bl use_addr call void @use_addr(i8* %var)