[llvm] r261006 - [Hexagon] Adding relocation for code size, cold path optimization allowing a 23-bit 4-byte aligned relocation to be a valid instruction encoding.

Colin LeMahieu via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 16 12:38:18 PST 2016


Author: colinl
Date: Tue Feb 16 14:38:17 2016
New Revision: 261006

URL: http://llvm.org/viewvc/llvm-project?rev=261006&view=rev
Log:
[Hexagon] Adding relocation for code size, cold path optimization allowing a 23-bit 4-byte aligned relocation to be a valid instruction encoding.

The usual way to get a 32-bit relocation is to use a constant extender which doubles the size of the instruction, 4 bytes to 8 bytes.

Another way is to put a .word32 and mix code and data within a function.  The disadvantage is it's not a valid instruction encoding and jumping over it causes prefetch stalls inside the hardware.

This relocation packs a 23-bit value in to an "r0 = add(rX, #a)" instruction by overwriting the source register bits.  Since r0 is the return value register, if this instruction is placed after a function call which return void, r0 will be filled with an undefined value, the prefetch won't be confused, and the callee can access the constant value by way of the link register.

Added:
    llvm/trunk/test/MC/Hexagon/iconst.s
Modified:
    llvm/trunk/include/llvm/Support/ELFRelocs/Hexagon.def
    llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
    llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp
    llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td
    llvm/trunk/lib/Target/Hexagon/HexagonOperands.td
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h

Modified: llvm/trunk/include/llvm/Support/ELFRelocs/Hexagon.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ELFRelocs/Hexagon.def?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ELFRelocs/Hexagon.def (original)
+++ llvm/trunk/include/llvm/Support/ELFRelocs/Hexagon.def Tue Feb 16 14:38:17 2016
@@ -98,3 +98,4 @@ ELF_RELOC(R_HEX_LD_GOT_16,           90)
 ELF_RELOC(R_HEX_LD_GOT_32_6_X,       91)
 ELF_RELOC(R_HEX_LD_GOT_16_X,         92)
 ELF_RELOC(R_HEX_LD_GOT_11_X,         93)
+ELF_RELOC(R_HEX_23_REG,              94)

Modified: llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp Tue Feb 16 14:38:17 2016
@@ -278,6 +278,7 @@ public:
 
   bool isf32Ext() const { return false; }
   bool iss32Imm() const { return CheckImmRange(32, 0, true, true, false); }
+  bool iss23_2Imm() const { return CheckImmRange(23, 2, true, true, false); }
   bool iss8Imm() const { return CheckImmRange(8, 0, true, false, false); }
   bool iss8Imm64() const { return CheckImmRange(8, 0, true, true, false); }
   bool iss7Imm() const { return CheckImmRange(7, 0, true, false, false); }
@@ -384,6 +385,9 @@ public:
   void adds32ImmOperands(MCInst &Inst, unsigned N) const {
     addSignedImmOperands(Inst, N);
   }
+  void adds23_2ImmOperands(MCInst &Inst, unsigned N) const {
+    addSignedImmOperands(Inst, N);
+  }
   void adds8ImmOperands(MCInst &Inst, unsigned N) const {
     addSignedImmOperands(Inst, N);
   }
@@ -1543,6 +1547,18 @@ int HexagonAsmParser::processInstruction
   default:
     break;
 
+  case Hexagon::A2_iconst: {
+    Inst.setOpcode(Hexagon::A2_addi);
+    MCOperand Reg = Inst.getOperand(0);
+    MCOperand S16 = Inst.getOperand(1);
+    HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr());
+    HexagonMCInstrInfo::setS23_2_reloc(*S16.getExpr());
+    Inst.clear();
+    Inst.addOperand(Reg);
+    Inst.addOperand(MCOperand::createReg(Hexagon::R0));
+    Inst.addOperand(S16);
+    break;
+  }
   case Hexagon::M4_mpyrr_addr:
   case Hexagon::S4_addi_asl_ri:
   case Hexagon::S4_addi_lsr_ri:

Modified: llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp Tue Feb 16 14:38:17 2016
@@ -264,6 +264,19 @@ void HexagonAsmPrinter::HexagonProcessIn
   switch (Inst.getOpcode()) {
   default: return;
 
+  case Hexagon::A2_iconst: {
+    Inst.setOpcode(Hexagon::A2_addi);
+    MCOperand Reg = Inst.getOperand(0);
+    MCOperand S16 = Inst.getOperand(1);
+    HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr());
+    HexagonMCInstrInfo::setS23_2_reloc(*S16.getExpr());
+    Inst.clear();
+    Inst.addOperand(Reg);
+    Inst.addOperand(MCOperand::createReg(Hexagon::R0));
+    Inst.addOperand(S16);
+    break;
+  }
+
   // "$dst = CONST64(#$src1)",
   case Hexagon::CONST64_Float_Real:
   case Hexagon::CONST64_Int_Real:

Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td Tue Feb 16 14:38:17 2016
@@ -418,6 +418,12 @@ defm addi : Addri_base<"add", add>, ImmR
 def: Pat<(i32 (add I32:$Rs, s32ImmPred:$s16)),
          (i32 (A2_addi I32:$Rs, imm:$s16))>;
 
+let hasNewValue = 1, hasSideEffects = 0, isPseudo = 1 in
+def A2_iconst
+  : ALU32_ri <(outs IntRegs:$Rd),
+              (ins s23_2Imm:$s23_2),
+  "$Rd = iconst(#$s23_2)"> {}
+
 //===----------------------------------------------------------------------===//
 // Template class used for the following ALU32 instructions.
 // Rd=and(Rs,#s10)

Modified: llvm/trunk/lib/Target/Hexagon/HexagonOperands.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonOperands.td?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonOperands.td (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonOperands.td Tue Feb 16 14:38:17 2016
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 def s32ImmOperand : AsmOperandClass { let Name = "s32Imm"; }
+def s23_2ImmOperand : AsmOperandClass { let Name = "s23_2Imm"; }
 def s8ImmOperand : AsmOperandClass { let Name = "s8Imm"; }
 def s8Imm64Operand : AsmOperandClass { let Name = "s8Imm64"; }
 def s6ImmOperand : AsmOperandClass { let Name = "s6Imm"; }
@@ -48,6 +49,7 @@ let OperandType = "OPERAND_IMMEDIATE",
     DecoderMethod = "unsignedImmDecoder" in {
   def s32Imm : Operand<i32> { let ParserMatchClass = s32ImmOperand;
                               let DecoderMethod = "s32ImmDecoder"; }
+  def s23_2Imm : Operand<i32> { let ParserMatchClass = s23_2ImmOperand; }
   def s8Imm : Operand<i32> { let ParserMatchClass = s8ImmOperand;
                              let DecoderMethod = "s8ImmDecoder"; }
   def s8Imm64 : Operand<i64>  { let ParserMatchClass = s8Imm64Operand;

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp Tue Feb 16 14:38:17 2016
@@ -282,6 +282,8 @@ unsigned HexagonELFObjectWriter::getRelo
     return ELF::R_HEX_TPREL_16_X;
   case fixup_Hexagon_TPREL_11_X:
     return ELF::R_HEX_TPREL_11_X;
+  case fixup_Hexagon_23_REG:
+    return ELF::R_HEX_23_REG;
   }
 }
 

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h Tue Feb 16 14:38:17 2016
@@ -110,6 +110,7 @@ enum Fixups {
   fixup_Hexagon_TPREL_32_6_X,
   fixup_Hexagon_TPREL_16_X,
   fixup_Hexagon_TPREL_11_X,
+  fixup_Hexagon_23_REG,
 
   LastTargetFixupKind,
   NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp Tue Feb 16 14:38:17 2016
@@ -550,6 +550,13 @@ unsigned HexagonMCCodeEmitter::getExprOp
       }
     } else
       switch (kind) {
+      case MCSymbolRefExpr::VK_None: {
+        if (HexagonMCInstrInfo::s23_2_reloc(*MO.getExpr()))
+          FixupKind = Hexagon::fixup_Hexagon_23_REG;
+        else
+          raise_relocation_error(bits, kind);
+        break;
+      }
       case MCSymbolRefExpr::VK_DTPREL:
         FixupKind = Hexagon::fixup_Hexagon_DTPREL_16;
         break;

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp Tue Feb 16 14:38:17 2016
@@ -52,12 +52,17 @@ void HexagonMCExpr::setMustNotExtend(boo
 }
 bool HexagonMCExpr::mustNotExtend() const { return MustNotExtend; }
 
+bool HexagonMCExpr::s23_2_reloc() const { return S23_2_reloc; }
+void HexagonMCExpr::setS23_2_reloc(bool Val) {
+  S23_2_reloc = Val;
+}
+
 bool HexagonMCExpr::classof(MCExpr const *E) {
   return E->getKind() == MCExpr::Target;
 }
 
 HexagonMCExpr::HexagonMCExpr(MCExpr const *Expr)
-    : Expr(Expr), MustNotExtend(false), MustExtend(false) {}
+    : Expr(Expr), MustNotExtend(false), MustExtend(false), S23_2_reloc(false) {}
 
 void HexagonMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
   Expr->print(OS, MAI);

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h Tue Feb 16 14:38:17 2016
@@ -29,12 +29,15 @@ public:
   bool mustExtend() const;
   void setMustNotExtend(bool Val = true);
   bool mustNotExtend() const;
+  void setS23_2_reloc(bool Val = true);
+  bool s23_2_reloc() const;
 
 private:
   HexagonMCExpr(MCExpr const *Expr);
   MCExpr const *Expr;
   bool MustNotExtend;
   bool MustExtend;
+  bool S23_2_reloc;
 };
 } // end namespace llvm
 

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp Tue Feb 16 14:38:17 2016
@@ -431,6 +431,9 @@ bool HexagonMCInstrInfo::isConstExtended
   // object we are going to end up with here for now.
   // In the future we probably should add isSymbol(), etc.
   assert(!MO.isImm());
+  if (isa<HexagonMCExpr>(MO.getExpr()) &&
+      HexagonMCInstrInfo::mustNotExtend(*MO.getExpr()))
+    return false;
   int64_t Value;
   if (!MO.getExpr()->evaluateAsAbsolute(Value))
     return true;
@@ -665,6 +668,15 @@ void HexagonMCInstrInfo::setMemStoreReor
   Operand.setImm(Operand.getImm() | memStoreReorderEnabledMask);
   assert(isMemStoreReorderEnabled(MCI));
 }
+void HexagonMCInstrInfo::setS23_2_reloc(MCExpr const &Expr, bool Val) {
+  HexagonMCExpr &HExpr =
+      const_cast<HexagonMCExpr &>(*llvm::cast<HexagonMCExpr>(&Expr));
+  HExpr.setS23_2_reloc(Val);
+}
+bool HexagonMCInstrInfo::s23_2_reloc(MCExpr const &Expr) {
+  HexagonMCExpr const &HExpr = *llvm::cast<HexagonMCExpr>(&Expr);
+  return HExpr.s23_2_reloc();
+}
 
 void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
   assert(isBundle(MCI));

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h?rev=261006&r1=261005&r2=261006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h Tue Feb 16 14:38:17 2016
@@ -274,12 +274,14 @@ bool prefersSlot3(MCInstrInfo const &MCI
 // Replace the instructions inside MCB, represented by Candidate
 void replaceDuplex(MCContext &Context, MCInst &MCB, DuplexCandidate Candidate);
 
+bool s23_2_reloc(MCExpr const &Expr);
 // Marks a bundle as endloop0
 void setInnerLoop(MCInst &MCI);
 void setMemReorderDisabled(MCInst &MCI);
 void setMemStoreReorderEnabled(MCInst &MCI);
 void setMustExtend(MCExpr &Expr, bool Val = true);
 void setMustNotExtend(MCExpr const &Expr, bool Val = true);
+void setS23_2_reloc(MCExpr const &Expr, bool Val = true);
 
 // Marks a bundle as endloop1
 void setOuterLoop(MCInst &MCI);

Added: llvm/trunk/test/MC/Hexagon/iconst.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/iconst.s?rev=261006&view=auto
==============================================================================
--- llvm/trunk/test/MC/Hexagon/iconst.s (added)
+++ llvm/trunk/test/MC/Hexagon/iconst.s Tue Feb 16 14:38:17 2016
@@ -0,0 +1,6 @@
+# RUN: llvm-mc -triple=hexagon -filetype=obj %s | llvm-objdump -d -r - | FileCheck %s
+
+a:
+# CHECK: r0 = add(r0, #0)
+# CHECK: R_HEX_23_REG
+r0 = iconst(#a)
\ No newline at end of file




More information about the llvm-commits mailing list