[llvm] 916044d - [X86][MC] Support enhanced relaxation for branch align

Shengchen Kan via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 8 04:08:41 PDT 2020


Author: Shengchen Kan
Date: 2020-04-08T19:08:19+08:00
New Revision: 916044d819c8e383fe1cd99190e3ff572d80f48f

URL: https://github.com/llvm/llvm-project/commit/916044d819c8e383fe1cd99190e3ff572d80f48f
DIFF: https://github.com/llvm/llvm-project/commit/916044d819c8e383fe1cd99190e3ff572d80f48f.diff

LOG: [X86][MC] Support enhanced relaxation for branch align

Summary:
Since D75300 has been landed, I want to support enhanced relaxation when we need to align branches and allow prefix padding. "Enhanced Relaxtion" means we allow an instruction that could not be traditionally relaxed to be emitted into RelaxableFragment so that we increase its length by adding prefixes for optimization.

The motivation is straightforward, RelaxFragment is mostly for relative jumps and we can not increase the length of jumps when we need to align them, so if we need to achieve D75300's purpose (reducing the bytes of nops) when need to align jumps, we have to make more instructions "relaxable".

Reviewers: reames, MaskRay, craig.topper, LuoYuanke, jyknight

Reviewed By: reames

Subscribers: hiraditya, llvm-commits, annita.zhang

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D76286

Added: 
    llvm/test/MC/X86/align-branch-enhanced-relaxation.s

Modified: 
    llvm/include/llvm/MC/MCAsmBackend.h
    llvm/lib/MC/MCObjectStreamer.cpp
    llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index f859d0c418a3..9b67c920d15b 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -49,6 +49,10 @@ class MCAsmBackend {
   /// Return true if this target might automatically pad instructions and thus
   /// need to emit padding enable/disable directives around sensative code.
   virtual bool allowAutoPadding() const { return false; }
+  /// Return true if this target allows an unrelaxable instruction to be
+  /// emitted into RelaxableFragment and then we can increase its size in a
+  /// tricky way for optimization.
+  virtual bool allowEnhancedRelaxation() const { return false; }
 
   /// Give the target a chance to manipulate state related to instruction
   /// alignment (e.g. padding for optimization), instruction relaxablility, etc.

diff  --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 70c9201e8a17..3cb3faae2c04 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -385,7 +385,9 @@ void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,
 
   // If this instruction doesn't need relaxation, just emit it as data.
   MCAssembler &Assembler = getAssembler();
-  if (!Assembler.getBackend().mayNeedRelaxation(Inst, STI)) {
+  MCAsmBackend &Backend = Assembler.getBackend();
+  if (!(Backend.mayNeedRelaxation(Inst, STI) ||
+        Backend.allowEnhancedRelaxation())) {
     EmitInstToData(Inst, STI);
     return;
   }

diff  --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index c2eb78bd056d..fd2c3ab3b493 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -164,6 +164,7 @@ class X86AsmBackend : public MCAsmBackend {
   }
 
   bool allowAutoPadding() const override;
+  bool allowEnhancedRelaxation() const override;
   void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst) override;
   void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst) override;
 
@@ -457,6 +458,10 @@ bool X86AsmBackend::allowAutoPadding() const {
   return (AlignBoundary != Align(1) && AlignBranchType != X86::AlignBranchNone);
 }
 
+bool X86AsmBackend::allowEnhancedRelaxation() const {
+  return allowAutoPadding() && X86PadMaxPrefixSize != 0 && X86PadForBranchAlign;
+}
+
 bool X86AsmBackend::needAlign(MCObjectStreamer &OS) const {
   if (!OS.getAllowAutoPadding())
     return false;

diff  --git a/llvm/test/MC/X86/align-branch-enhanced-relaxation.s b/llvm/test/MC/X86/align-branch-enhanced-relaxation.s
new file mode 100644
index 000000000000..4720e35a64b0
--- /dev/null
+++ b/llvm/test/MC/X86/align-branch-enhanced-relaxation.s
@@ -0,0 +1,52 @@
+  # RUN: llvm-mc -mcpu=skylake -filetype=obj -triple x86_64-pc-linux-gnu %s -x86-pad-max-prefix-size=1 --x86-align-branch-boundary=32 --x86-align-branch=jmp+indirect | llvm-objdump -d - | FileCheck %s
+  # RUN: llvm-mc -mcpu=skylake -filetype=obj -triple x86_64-pc-linux-gnu %s --mc-relax-all | llvm-objdump -d - | FileCheck --check-prefixes=RELAX-ALL %s
+
+  # Exercise cases where we are allowed to increase the length of unrelaxable
+  # instructions (by adding prefixes) for alignment purposes.
+
+  # The first test checks instructions 'int3', 'push %rbp', which will be padded
+  # later are unrelaxable (their encoding size is still 1 byte when
+  # --mc-relax-all is passed).
+  .text
+  .globl labeled_unrelaxable_test
+labeled_unrelaxable_test:
+# RELAX-ALL:       0: cc                               int3
+# RELAX-ALL:       1: 54                               pushq    %rsp
+  int3
+  push %rsp
+
+  # The second test is a basic test, we just check the jmp is aligned by prefix
+  # padding the previous instructions.
+  .text
+  .globl labeled_basic_test
+labeled_basic_test:
+  .p2align 5
+  .rept 28
+  int3
+  .endr
+# CHECK:      3c: 2e cc                            int3
+# CHECK:      3e: 2e 54                            pushq    %rsp
+# CHECK:      40: eb 00                            jmp
+  int3
+  push %rsp
+  jmp foo
+foo:
+  ret
+
+   # The third test check the correctness cornercase - can't add prefixes on a
+   # prefix or a instruction following by a prefix.
+  .globl labeled_prefix_test
+labeled_prefix_test:
+  .p2align 5
+  .rept 28
+  int3
+  .endr
+# CHECK:      7c: 2e cc                            int3
+  int3
+# CHECK:      7e: 3e cc                            int3
+  DS
+  int3
+# CHECK:      80: eb 00                            jmp
+  jmp bar
+bar:
+  ret


        


More information about the llvm-commits mailing list