Skip to content

Commit e603451

Browse files
authored
[X86] Support branch hint (#97721)
For more details about this feature, please refer to latest Intel 64 and IA-32 Architectures Optimization Reference Manual Volume 1: https://www.intel.com/content/www/us/en/content-details/821612/intel-64-and-ia-32-architectures-optimization-reference-manual-volume-1.html
1 parent 4a9dabe commit e603451

File tree

5 files changed

+113
-3
lines changed

5 files changed

+113
-3
lines changed

clang/lib/Basic/Targets/X86.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
457457
HasCF = true;
458458
} else if (Feature == "+zu") {
459459
HasZU = true;
460+
} else if (Feature == "+branch-hint") {
461+
HasBranchHint = true;
460462
}
461463

462464
X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
@@ -1292,6 +1294,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
12921294
.Case("nf", HasNF)
12931295
.Case("cf", HasCF)
12941296
.Case("zu", HasZU)
1297+
.Case("branch-hint", HasBranchHint)
12951298
.Default(false);
12961299
}
12971300

clang/lib/Basic/Targets/X86.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
174174
bool HasCF = false;
175175
bool HasZU = false;
176176
bool HasInlineAsmUseGPR32 = false;
177+
bool HasBranchHint = false;
177178

178179
protected:
179180
llvm::X86::CPUKind CPU = llvm::X86::CK_None;

llvm/lib/Target/X86/X86.td

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,11 @@ def TuningUseGLMDivSqrtCosts
749749
: SubtargetFeature<"use-glm-div-sqrt-costs", "UseGLMDivSqrtCosts", "true",
750750
"Use Goldmont specific floating point div/sqrt costs">;
751751

752+
// Starting with Redwood Cove architecture, the branch has branch taken hint
753+
// (i.e., instruction prefix 3EH).
754+
def TuningBranchHint: SubtargetFeature<"branch-hint", "HasBranchHint", "true",
755+
"Target has branch hint feature">;
756+
752757
//===----------------------------------------------------------------------===//
753758
// X86 CPU Families
754759
// TODO: Remove these - use general tuning features to determine codegen.
@@ -1124,6 +1129,8 @@ def ProcessorFeatures {
11241129
FeaturePREFETCHI];
11251130
list<SubtargetFeature> GNRFeatures =
11261131
!listconcat(SPRFeatures, GNRAdditionalFeatures);
1132+
list<SubtargetFeature> GNRAdditionalTuning = [TuningBranchHint];
1133+
list<SubtargetFeature> GNRTuning = !listconcat(SPRTuning, GNRAdditionalTuning);
11271134

11281135
// Graniterapids D
11291136
list<SubtargetFeature> GNRDAdditionalFeatures = [FeatureAMXCOMPLEX];
@@ -1815,12 +1822,12 @@ def : ProcModel<"pantherlake", AlderlakePModel,
18151822
def : ProcModel<"clearwaterforest", AlderlakePModel,
18161823
ProcessorFeatures.CWFFeatures, ProcessorFeatures.ADLTuning>;
18171824
def : ProcModel<"graniterapids", SapphireRapidsModel,
1818-
ProcessorFeatures.GNRFeatures, ProcessorFeatures.SPRTuning>;
1825+
ProcessorFeatures.GNRFeatures, ProcessorFeatures.GNRTuning>;
18191826
def : ProcModel<"emeraldrapids", SapphireRapidsModel,
1820-
ProcessorFeatures.SPRFeatures, ProcessorFeatures.SPRTuning>;
1827+
ProcessorFeatures.SPRFeatures, ProcessorFeatures.GNRTuning>;
18211828
foreach P = ["graniterapids-d", "graniterapids_d"] in {
18221829
def : ProcModel<P, SapphireRapidsModel,
1823-
ProcessorFeatures.GNRDFeatures, ProcessorFeatures.SPRTuning>;
1830+
ProcessorFeatures.GNRDFeatures, ProcessorFeatures.GNRTuning>;
18241831
}
18251832

18261833
// AMD CPUs.

llvm/lib/Target/X86/X86MCInstLower.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/ADT/STLExtras.h"
2626
#include "llvm/ADT/SmallString.h"
2727
#include "llvm/ADT/StringExtras.h"
28+
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
2829
#include "llvm/CodeGen/MachineConstantPool.h"
2930
#include "llvm/CodeGen/MachineFunction.h"
3031
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
@@ -54,6 +55,14 @@
5455

5556
using namespace llvm;
5657

58+
static cl::opt<bool> EnableBranchHint("enable-branch-hint",
59+
cl::desc("Enable branch hint."),
60+
cl::init(false), cl::Hidden);
61+
static cl::opt<unsigned> BranchHintProbabilityThreshold(
62+
"branch-hint-probability-threshold",
63+
cl::desc("The probability threshold of enabling branch hint."),
64+
cl::init(50), cl::Hidden);
65+
5766
namespace {
5867

5968
/// X86MCInstLower - This class is used to lower an MachineInstr into an MCInst.
@@ -2444,6 +2453,21 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
24442453
if (IndCSPrefix && MI->hasRegisterImplicitUseOperand(X86::R11))
24452454
EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX));
24462455
break;
2456+
case X86::JCC_1:
2457+
// Two instruction prefixes (2EH for branch not-taken and 3EH for branch
2458+
// taken) are used as branch hints. Here we add branch taken prefix for
2459+
// jump instruction with higher probability than threshold.
2460+
if (getSubtarget().hasBranchHint() && EnableBranchHint) {
2461+
const MachineBranchProbabilityInfo *MBPI =
2462+
&getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
2463+
MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();
2464+
BranchProbability EdgeProb =
2465+
MBPI->getEdgeProbability(MI->getParent(), DestBB);
2466+
BranchProbability Threshold(BranchHintProbabilityThreshold, 100);
2467+
if (EdgeProb > Threshold)
2468+
EmitAndCountInstruction(MCInstBuilder(X86::DS_PREFIX));
2469+
}
2470+
break;
24472471
}
24482472

24492473
MCInst TmpInst;

llvm/test/CodeGen/X86/branch-hint.ll

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc < %s -mtriple=x86_64 -mattr=+branch-hint -enable-branch-hint | FileCheck %s
3+
; RUN: llc < %s -mtriple=x86_64 -mattr=+branch-hint -enable-branch-hint -branch-hint-probability-threshold=50 | FileCheck %s
4+
; RUN: llc < %s -mtriple=x86_64 -mattr=+branch-hint -enable-branch-hint -branch-hint-probability-threshold=60 -tail-dup-placement=false | FileCheck --check-prefix=TH60 %s
5+
6+
7+
; Design: Add DS segment override prefix for condition branch who has high
8+
; probability to take (which is greater than the probability threshold of
9+
; enabling branch hint).
10+
11+
define void @p51(i32 %x, ptr %p) {
12+
; CHECK-LABEL: p51:
13+
; CHECK: # %bb.0: # %entry
14+
; CHECK-NEXT: testl %edi, %edi
15+
; CHECK-NEXT: ds
16+
; CHECK-NEXT: je .LBB0_2
17+
; CHECK-NEXT: # %bb.1: # %if.then
18+
; CHECK-NEXT: movl %edi, (%rsi)
19+
; CHECK-NEXT: .LBB0_2: # %if.end
20+
; CHECK-NEXT: retq
21+
;
22+
; TH60-LABEL: p51:
23+
; TH60: # %bb.0: # %entry
24+
; TH60-NEXT: testl %edi, %edi
25+
; TH60-NEXT: je .LBB0_2
26+
; TH60-NEXT: # %bb.1: # %if.then
27+
; TH60-NEXT: movl %edi, (%rsi)
28+
; TH60-NEXT: .LBB0_2: # %if.end
29+
; TH60-NEXT: retq
30+
entry:
31+
%tobool.not = icmp eq i32 %x, 0
32+
br i1 %tobool.not, label %if.end, label %if.then, !prof !0
33+
34+
if.then:
35+
store i32 %x, ptr %p, align 4
36+
br label %if.end
37+
38+
if.end:
39+
ret void
40+
}
41+
42+
define void @p61(i32 %x, ptr %p) {
43+
; CHECK-LABEL: p61:
44+
; CHECK: # %bb.0: # %entry
45+
; CHECK-NEXT: testl %edi, %edi
46+
; CHECK-NEXT: jne .LBB1_1
47+
; CHECK-NEXT: # %bb.2: # %if.end
48+
; CHECK-NEXT: retq
49+
; CHECK-NEXT: .LBB1_1: # %if.then
50+
; CHECK-NEXT: movl %edi, (%rsi)
51+
; CHECK-NEXT: retq
52+
;
53+
; TH60-LABEL: p61:
54+
; TH60: # %bb.0: # %entry
55+
; TH60-NEXT: testl %edi, %edi
56+
; TH60-NEXT: ds
57+
; TH60-NEXT: je .LBB1_2
58+
; TH60-NEXT: # %bb.1: # %if.then
59+
; TH60-NEXT: movl %edi, (%rsi)
60+
; TH60-NEXT: .LBB1_2: # %if.end
61+
; TH60-NEXT: retq
62+
entry:
63+
%tobool.not = icmp eq i32 %x, 0
64+
br i1 %tobool.not, label %if.end, label %if.then, !prof !1
65+
66+
if.then:
67+
store i32 %x, ptr %p, align 4
68+
br label %if.end
69+
70+
if.end:
71+
ret void
72+
}
73+
74+
!0 = !{!"branch_weights", i32 51, i32 49}
75+
!1 = !{!"branch_weights", i32 61, i32 39}

0 commit comments

Comments
 (0)