[llvm] r184436 - [PowerPC] Optimize @ha/@l constructs

Ulrich Weigand ulrich.weigand at de.ibm.com
Thu Jun 20 09:23:52 PDT 2013


Author: uweigand
Date: Thu Jun 20 11:23:52 2013
New Revision: 184436

URL: http://llvm.org/viewvc/llvm-project?rev=184436&view=rev
Log:

[PowerPC] Optimize @ha/@l constructs

This patch adds support for having the assembler optimize fixups
to constructs like "symbol at ha" or "symbol at l" if "symbol" can be
resolved at assembler time.

This optimization is already present in the PPCMCExpr.cpp code
for handling PPC_HA16/PPC_LO16 target expressions.  However,
those target expression were used only on Darwin targets.

This patch changes target expression code so that they are
usable also with the GNU assembler (using the @ha / @l syntax
instead of the ha16() / lo16() syntax), and changes the
MCInst lowering code to generate those target expressions
where appropriate.

It also changes the asm parser to generate HA16/LO16 target
expressions when parsing assembler source that uses the
@ha / @l modifiers.  The effect is that now the above-
mentioned optimization automatically becomes available
for those situations too.
 

Modified:
    llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h
    llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp
    llvm/trunk/test/MC/PowerPC/ppc64-fixup-apply.s

Modified: llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp?rev=184436&r1=184435&r2=184436&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp Thu Jun 20 11:23:52 2013
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "MCTargetDesc/PPCMCTargetDesc.h"
+#include "MCTargetDesc/PPCMCExpr.h"
 #include "llvm/MC/MCTargetAsmParser.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCExpr.h"
@@ -126,6 +127,10 @@ class PPCAsmParser : public MCTargetAsmP
 
   virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
 
+  const MCExpr *ExtractModifierFromExpr(const MCExpr *E,
+                                        PPCMCExpr::VariantKind &Variant);
+  bool ParseExpression(const MCExpr *&EVal);
+
   bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
 
   bool ParseDirectiveWord(unsigned Size, SMLoc L);
@@ -540,6 +545,91 @@ ParseRegister(unsigned &RegNo, SMLoc &St
   return Error(StartLoc, "invalid register name");
 }
 
+/// Extract @l/@ha modifier from expression.  Recursively scan
+/// the expression and check for VK_PPC_ADDR16_HA/VK_PPC_ADDR16_LO
+/// symbol variants.  If all symbols with modifier use the same
+/// variant, return the corresponding PPCMCExpr::VariantKind,
+/// and a modified expression using the default symbol variant.
+/// Otherwise, return NULL.
+const MCExpr *PPCAsmParser::
+ExtractModifierFromExpr(const MCExpr *E,
+                        PPCMCExpr::VariantKind &Variant) {
+  MCContext &Context = getParser().getContext();
+  Variant = PPCMCExpr::VK_PPC_None;
+
+  switch (E->getKind()) {
+  case MCExpr::Target:
+  case MCExpr::Constant:
+    return 0;
+
+  case MCExpr::SymbolRef: {
+    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
+
+    switch (SRE->getKind()) {
+    case MCSymbolRefExpr::VK_PPC_ADDR16_HA:
+      Variant = PPCMCExpr::VK_PPC_HA16;
+      break;
+    case MCSymbolRefExpr::VK_PPC_ADDR16_LO:
+      Variant = PPCMCExpr::VK_PPC_LO16;
+      break;
+    default:
+      return 0;
+    }
+
+    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Context);
+  }
+
+  case MCExpr::Unary: {
+    const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
+    const MCExpr *Sub = ExtractModifierFromExpr(UE->getSubExpr(), Variant);
+    if (!Sub)
+      return 0;
+    return MCUnaryExpr::Create(UE->getOpcode(), Sub, Context);
+  }
+
+  case MCExpr::Binary: {
+    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
+    PPCMCExpr::VariantKind LHSVariant, RHSVariant;
+    const MCExpr *LHS = ExtractModifierFromExpr(BE->getLHS(), LHSVariant);
+    const MCExpr *RHS = ExtractModifierFromExpr(BE->getRHS(), RHSVariant);
+
+    if (!LHS && !RHS)
+      return 0;
+
+    if (!LHS) LHS = BE->getLHS();
+    if (!RHS) RHS = BE->getRHS();
+
+    if (LHSVariant == PPCMCExpr::VK_PPC_None)
+      Variant = RHSVariant;
+    else if (RHSVariant == PPCMCExpr::VK_PPC_None)
+      Variant = LHSVariant;
+    else if (LHSVariant == RHSVariant)
+      Variant = LHSVariant;
+    else
+      return 0;
+
+    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, Context);
+  }
+  }
+
+  llvm_unreachable("Invalid expression kind!");
+}
+
+/// Parse an expression.  This differs from the default "parseExpression"
+/// in that it handles complex @l/@ha modifiers.
+bool PPCAsmParser::
+ParseExpression(const MCExpr *&EVal) {
+  if (getParser().parseExpression(EVal))
+    return true;
+
+  PPCMCExpr::VariantKind Variant;
+  const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
+  if (E)
+    EVal = PPCMCExpr::Create(Variant, E, getParser().getContext());
+
+  return false;
+}
+
 bool PPCAsmParser::
 ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   SMLoc S = Parser.getTok().getLoc();
@@ -571,7 +661,7 @@ ParseOperand(SmallVectorImpl<MCParsedAsm
   case AsmToken::Identifier:
   case AsmToken::Dot:
   case AsmToken::Dollar:
-    if (!getParser().parseExpression(EVal))
+    if (!ParseExpression(EVal))
       break;
     /* fall through */
   default:

Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp?rev=184436&r1=184435&r2=184436&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp Thu Jun 20 11:23:52 2013
@@ -11,25 +11,37 @@
 #include "PPCMCExpr.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCAsmInfo.h"
 
 using namespace llvm;
 
 const PPCMCExpr*
 PPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr,
                        MCContext &Ctx) {
-  return new (Ctx) PPCMCExpr(Kind, Expr);
+  int AssemblerDialect = Ctx.getAsmInfo()->getAssemblerDialect();
+  return new (Ctx) PPCMCExpr(Kind, Expr, AssemblerDialect);
 }
 
 void PPCMCExpr::PrintImpl(raw_ostream &OS) const {
-  switch (Kind) {
-  default: llvm_unreachable("Invalid kind!");
-  case VK_PPC_HA16: OS << "ha16"; break;
-  case VK_PPC_LO16: OS << "lo16"; break;
-  }
+  if (isDarwinSyntax()) {
+    switch (Kind) {
+    default: llvm_unreachable("Invalid kind!");
+    case VK_PPC_HA16: OS << "ha16"; break;
+    case VK_PPC_LO16: OS << "lo16"; break;
+    }
+
+    OS << '(';
+    getSubExpr()->print(OS);
+    OS << ')';
+  } else {
+    getSubExpr()->print(OS);
 
-  OS << '(';
-  getSubExpr()->print(OS);
-  OS << ')';
+    switch (Kind) {
+    default: llvm_unreachable("Invalid kind!");
+    case VK_PPC_HA16: OS << "@ha"; break;
+    case VK_PPC_LO16: OS << "@l"; break;
+    }
+  }
 }
 
 bool

Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h?rev=184436&r1=184435&r2=184436&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h Thu Jun 20 11:23:52 2013
@@ -27,9 +27,11 @@ public:
 private:
   const VariantKind Kind;
   const MCExpr *Expr;
+  const int AssemblerDialect;
 
-  explicit PPCMCExpr(VariantKind _Kind, const MCExpr *_Expr)
-    : Kind(_Kind), Expr(_Expr) {}
+  explicit PPCMCExpr(VariantKind _Kind, const MCExpr *_Expr,
+                     int _AssemblerDialect)
+    : Kind(_Kind), Expr(_Expr), AssemblerDialect(_AssemblerDialect) {}
 
 public:
   /// @name Construction
@@ -56,6 +58,10 @@ public:
   /// getSubExpr - Get the child of this expression.
   const MCExpr *getSubExpr() const { return Expr; }
 
+  /// isDarwinSyntax - True if expression is to be printed using Darwin syntax.
+  bool isDarwinSyntax() const { return AssemblerDialect == 1; }
+
+
   /// @}
 
   void PrintImpl(raw_ostream &OS) const;

Modified: llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp?rev=184436&r1=184435&r2=184436&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp Thu Jun 20 11:23:52 2013
@@ -111,30 +111,22 @@ static MCOperand GetSymbolRef(const Mach
 
   unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK;
 
-  if (!isDarwin) {
-    switch (access) {
-      case PPCII::MO_HA16:
-        RefKind = MCSymbolRefExpr::VK_PPC_ADDR16_HA;
-        break;
-      case PPCII::MO_LO16:
-        RefKind = MCSymbolRefExpr::VK_PPC_ADDR16_LO;
-        break;
-      case PPCII::MO_TPREL16_HA:
-        RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA;
-        break;
-      case PPCII::MO_TPREL16_LO:
-        RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO;
-        break;
-      case PPCII::MO_DTPREL16_LO:
-        RefKind = MCSymbolRefExpr::VK_PPC_DTPREL16_LO;
-        break;
-      case PPCII::MO_TLSLD16_LO:
-        RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO;
-        break;
-      case PPCII::MO_TOC16_LO:
-        RefKind = MCSymbolRefExpr::VK_PPC_TOC16_LO;
-        break;
-    }
+  switch (access) {
+    case PPCII::MO_TPREL16_HA:
+      RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA;
+      break;
+    case PPCII::MO_TPREL16_LO:
+      RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO;
+      break;
+    case PPCII::MO_DTPREL16_LO:
+      RefKind = MCSymbolRefExpr::VK_PPC_DTPREL16_LO;
+      break;
+    case PPCII::MO_TLSLD16_LO:
+      RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO;
+      break;
+    case PPCII::MO_TOC16_LO:
+      RefKind = MCSymbolRefExpr::VK_PPC_TOC16_LO;
+      break;
   }
 
   const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);
@@ -152,16 +144,14 @@ static MCOperand GetSymbolRef(const Mach
     Expr = MCBinaryExpr::CreateSub(Expr, PB, Ctx);
   }
 
-  // Add Darwin ha16() / lo16() markers if required.
-  if (isDarwin) {
-    switch (access) {
-      case PPCII::MO_HA16:
-        Expr = PPCMCExpr::CreateHa16(Expr, Ctx);
-        break;
-      case PPCII::MO_LO16:
-        Expr = PPCMCExpr::CreateLo16(Expr, Ctx);
-        break;
-    }
+  // Add ha16() / lo16() markers if required.
+  switch (access) {
+    case PPCII::MO_HA16:
+      Expr = PPCMCExpr::CreateHa16(Expr, Ctx);
+      break;
+    case PPCII::MO_LO16:
+      Expr = PPCMCExpr::CreateLo16(Expr, Ctx);
+      break;
   }
 
   return MCOperand::CreateExpr(Expr);

Modified: llvm/trunk/test/MC/PowerPC/ppc64-fixup-apply.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/ppc64-fixup-apply.s?rev=184436&r1=184435&r2=184436&view=diff
==============================================================================
--- llvm/trunk/test/MC/PowerPC/ppc64-fixup-apply.s (original)
+++ llvm/trunk/test/MC/PowerPC/ppc64-fixup-apply.s Thu Jun 20 11:23:52 2013
@@ -12,6 +12,22 @@ addis 1, 1, target
 
 .set target, 0x1234
 
+addi 1, 1, target2 at l
+addis 1, 1, target2 at ha
+
+.set target2, 0x12345678
+
+addi 1, 1, target3-target4 at l
+addis 1, 1, target3-target4 at ha
+
+.set target3, 0x23455678
+.set target4, 0x12341234
+
+addi 1, 1, target5+0x8000 at l
+addis 1, 1, target5+0x8000 at ha
+
+.set target5, 0x10000001
+
 .data
 
 .quad v1
@@ -33,13 +49,14 @@ addis 1, 1, target
 # CHECK-NEXT:    ]
 # CHECK-NEXT:    Address: 0x0
 # CHECK-NEXT:    Offset:
-# CHECK-NEXT:    Size: 8
+# CHECK-NEXT:    Size: 32
 # CHECK-NEXT:    Link: 0
 # CHECK-NEXT:    Info: 0
 # CHECK-NEXT:    AddressAlignment: 4
 # CHECK-NEXT:    EntrySize: 0
 # CHECK-NEXT:    SectionData (
-# CHECK-NEXT:      0000: 38211234 3C211234
+# CHECK-NEXT:      0000: 38211234 3C211234 38215678 3C211234
+# CHECK-NEXT:      0010: 38214444 3C211111 38218001 3C211001
 # CHECK-NEXT:    )
 # CHECK-NEXT:  }
 





More information about the llvm-commits mailing list