From 225c0bd61ee189264eb17e149b3c0bc8219a0478 Mon Sep 17 00:00:00 2001 From: Pete Couperus Date: Thu, 14 Mar 2019 17:50:46 +0000 Subject: [PATCH] [ARC] Better classify add/sub immediate instructions in frame lowering. Summary: Some operations have multiple ARC instructions that are applicable. For instance, "add r0, r0, 123" can be encoded as a "LImm" instruction with a 32-bit immediate (8-bytes), or as a signed 12-bit immediate instruction for the case where the source and destination register are the same (4-bytes). The ARC assembler will choose the shortest encoding, but we should track the correct instruction in the compiler. This patch fixes the instruction used in some cases from ARCFrameLowering. Subscribers: hiraditya, jdoerfert, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59326 llvm-svn: 356179 --- llvm/lib/Target/ARC/ARCFrameLowering.cpp | 50 +++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/ARC/ARCFrameLowering.cpp b/llvm/lib/Target/ARC/ARCFrameLowering.cpp index 047da85..ac0a4bb 100644 --- a/llvm/lib/Target/ARC/ARCFrameLowering.cpp +++ b/llvm/lib/Target/ARC/ARCFrameLowering.cpp @@ -64,6 +64,8 @@ static void generateStackAdjustment(MachineBasicBlock &MBB, assert((AbsAmount % 4 == 0) && "Stack adjustments must be 4-byte aligned."); if (isUInt<6>(AbsAmount)) AdjOp = Positive ? ARC::ADD_rru6 : ARC::SUB_rru6; + else if (isInt<12>(AbsAmount)) + AdjOp = Positive ? ARC::ADD_rrs12 : ARC::SUB_rrs12; else AdjOp = Positive ? ARC::ADD_rrlimm : ARC::SUB_rrlimm; @@ -133,8 +135,12 @@ void ARCFrameLowering::emitPrologue(MachineFunction &MF, // Add in the varargs area here first. LLVM_DEBUG(dbgs() << "Varargs\n"); unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex()); - BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6)) - .addReg(ARC::SP) + unsigned Opc = ARC::SUB_rrlimm; + if (isUInt<6>(VarArgsBytes)) + Opc = ARC::SUB_rru6; + else if (isInt<12>(VarArgsBytes)) + Opc = ARC::SUB_rrs12; + BuildMI(MBB, MBBI, dl, TII->get(Opc), ARC::SP) .addReg(ARC::SP) .addImm(VarArgsBytes); } @@ -246,7 +252,10 @@ void ARCFrameLowering::emitEpilogue(MachineFunction &MF, // Then, replace the frame pointer by (new) [sp,StackSize-4]. // Then, move the stack pointer the rest of the way (sp = sp + StackSize). if (hasFP(MF)) { - BuildMI(MBB, MBBI, DebugLoc(), TII->get(ARC::SUB_rru6), ARC::SP) + unsigned Opc = ARC::SUB_rrlimm; + if (isUInt<6>(StackSize)) + Opc = ARC::SUB_rru6; + BuildMI(MBB, MBBI, DebugLoc(), TII->get(Opc), ARC::SP) .addReg(ARC::FP) .addImm(StackSize); AmountAboveFunclet += 4; @@ -270,19 +279,28 @@ void ARCFrameLowering::emitEpilogue(MachineFunction &MF, } // Move the stack pointer up to the point of the funclet. - if (StackSize - AmountAboveFunclet) { - BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6)) - .addReg(ARC::SP) + if (unsigned MoveAmount = StackSize - AmountAboveFunclet) { + unsigned Opc = ARC::ADD_rrlimm; + if (isUInt<6>(MoveAmount)) + Opc = ARC::ADD_rru6; + else if (isInt<12>(MoveAmount)) + Opc = ARC::ADD_rrs12; + BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc), ARC::SP) .addReg(ARC::SP) .addImm(StackSize - AmountAboveFunclet); } if (StackSlotsUsedByFunclet) { + // This part of the adjustment will always be < 64 bytes. BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::BL)) .addExternalSymbol(load_funclet_name[Last - ARC::R15]) .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill); - BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6)) - .addReg(ARC::SP) + unsigned Opc = ARC::ADD_rrlimm; + if (isUInt<6>(4 * StackSlotsUsedByFunclet)) + Opc = ARC::ADD_rru6; + else if (isInt<12>(4 * StackSlotsUsedByFunclet)) + Opc = ARC::ADD_rrs12; + BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc), ARC::SP) .addReg(ARC::SP) .addImm(4 * (StackSlotsUsedByFunclet)); } @@ -304,7 +322,12 @@ void ARCFrameLowering::emitEpilogue(MachineFunction &MF, // Add in the varargs area here first. LLVM_DEBUG(dbgs() << "Varargs\n"); unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex()); - BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6)) + unsigned Opc = ARC::ADD_rrlimm; + if (isUInt<6>(VarArgsBytes)) + Opc = ARC::ADD_rru6; + else if (isInt<12>(VarArgsBytes)) + Opc = ARC::ADD_rrs12; + BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc)) .addReg(ARC::SP) .addReg(ARC::SP) .addImm(VarArgsBytes); @@ -430,7 +453,14 @@ static void emitRegUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned Reg, int NumBytes, bool IsAdd, const ARCInstrInfo *TII) { - unsigned Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6; + unsigned Opc; + if (isUInt<6>(NumBytes)) + Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6; + else if (isInt<12>(NumBytes)) + Opc = IsAdd ? ARC::ADD_rrs12 : ARC::SUB_rrs12; + else + Opc = IsAdd ? ARC::ADD_rrlimm : ARC::SUB_rrlimm; + BuildMI(MBB, MBBI, dl, TII->get(Opc), Reg) .addReg(Reg, RegState::Kill) .addImm(NumBytes); -- 2.7.4