[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