Skip to content

Commit 8a31604

Browse files
committed
[AArch64][GlobalISel] Enable use of the optsize predicate in the selector.
To do this while supporting the existing functionality in SelectionDAG of using PGO info, we add the ProfileSummaryInfo and LazyBlockFrequencyInfo analysis dependencies to the instruction selector pass. Then, use the predicate to generate constant pool loads for f32 materialization, if we're targeting optsize/minsize. Differential Revision: https://reviews.llvm.org/D97732
1 parent c0f8115 commit 8a31604

19 files changed

+185
-39
lines changed

llvm/include/llvm/CodeGen/GlobalISel/InstructionSelect.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
#include "llvm/CodeGen/MachineFunctionPass.h"
1818

1919
namespace llvm {
20+
21+
class BlockFrequencyInfo;
22+
class ProfileSummaryInfo;
23+
2024
/// This pass is responsible for selecting generic machine instructions to
2125
/// target-specific instructions. It relies on the InstructionSelector provided
2226
/// by the target.
@@ -43,9 +47,16 @@ class InstructionSelect : public MachineFunctionPass {
4347
MachineFunctionProperties::Property::Selected);
4448
}
4549

50+
InstructionSelect(CodeGenOpt::Level OL);
4651
InstructionSelect();
4752

4853
bool runOnMachineFunction(MachineFunction &MF) override;
54+
55+
protected:
56+
BlockFrequencyInfo *BFI = nullptr;
57+
ProfileSummaryInfo *PSI = nullptr;
58+
59+
CodeGenOpt::Level OptLevel = CodeGenOpt::None;
4960
};
5061
} // End namespace llvm.
5162

llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
#include "llvm/ADT/DenseMap.h"
1919
#include "llvm/ADT/Optional.h"
2020
#include "llvm/ADT/SmallVector.h"
21+
#include "llvm/Analysis/BlockFrequencyInfo.h"
22+
#include "llvm/Analysis/ProfileSummaryInfo.h"
23+
#include "llvm/CodeGen/GlobalISel/Utils.h"
24+
#include "llvm/CodeGen/MachineBasicBlock.h"
25+
#include "llvm/CodeGen/MachineFunction.h"
2126
#include "llvm/Support/CodeGenCoverage.h"
2227
#include "llvm/Support/LowLevelTypeImpl.h"
2328
#include <bitset>
@@ -429,18 +434,25 @@ class InstructionSelector {
429434
CodeGenCoverage *CoverageInfo = nullptr;
430435
GISelKnownBits *KnownBits = nullptr;
431436
MachineFunction *MF = nullptr;
437+
ProfileSummaryInfo *PSI = nullptr;
438+
BlockFrequencyInfo *BFI = nullptr;
439+
// For some predicates, we need to track the current MBB.
440+
MachineBasicBlock *CurMBB = nullptr;
432441

433442
virtual void setupGeneratedPerFunctionState(MachineFunction &MF) {
434443
llvm_unreachable("TableGen should have emitted implementation");
435444
}
436445

437446
/// Setup per-MF selector state.
438-
virtual void setupMF(MachineFunction &mf,
439-
GISelKnownBits &KB,
440-
CodeGenCoverage &covinfo) {
447+
virtual void setupMF(MachineFunction &mf, GISelKnownBits *KB,
448+
CodeGenCoverage &covinfo, ProfileSummaryInfo *psi,
449+
BlockFrequencyInfo *bfi) {
441450
CoverageInfo = &covinfo;
442-
KnownBits = &KB;
451+
KnownBits = KB;
443452
MF = &mf;
453+
PSI = psi;
454+
BFI = bfi;
455+
CurMBB = nullptr;
444456
setupGeneratedPerFunctionState(mf);
445457
}
446458

@@ -463,6 +475,12 @@ class InstructionSelector {
463475
MatcherState(unsigned MaxRenderers);
464476
};
465477

478+
bool shouldOptForSize(const MachineFunction *MF) const {
479+
const auto &F = MF->getFunction();
480+
return F.hasOptSize() || F.hasMinSize() ||
481+
(PSI && BFI && CurMBB && llvm::shouldOptForSize(*CurMBB, PSI, BFI));
482+
}
483+
466484
public:
467485
template <class PredicateBitset, class ComplexMatcherMemFn,
468486
class CustomRendererFn>

llvm/include/llvm/CodeGen/GlobalISel/Utils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_CODEGEN_GLOBALISEL_UTILS_H
1616

1717
#include "llvm/ADT/StringRef.h"
18+
#include "llvm/CodeGen/MachineBasicBlock.h"
1819
#include "llvm/CodeGen/Register.h"
1920
#include "llvm/Support/Alignment.h"
2021
#include "llvm/Support/LowLevelTypeImpl.h"
@@ -23,6 +24,7 @@
2324
namespace llvm {
2425

2526
class AnalysisUsage;
27+
class BlockFrequencyInfo;
2628
class GISelKnownBits;
2729
class MachineFunction;
2830
class MachineInstr;
@@ -32,6 +34,7 @@ class MachineOptimizationRemarkMissed;
3234
struct MachinePointerInfo;
3335
class MachineRegisterInfo;
3436
class MCInstrDesc;
37+
class ProfileSummaryInfo;
3538
class RegisterBankInfo;
3639
class TargetInstrInfo;
3740
class TargetLowering;
@@ -283,5 +286,9 @@ bool isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
283286
/// Returns an integer representing true, as defined by the
284287
/// TargetBooleanContents.
285288
int64_t getICmpTrueVal(const TargetLowering &TLI, bool IsVector, bool IsFP);
289+
290+
/// Returns true if the given block should be optimized for size.
291+
bool shouldOptForSize(const MachineBasicBlock &MBB, ProfileSummaryInfo *PSI,
292+
BlockFrequencyInfo *BFI);
286293
} // End namespace llvm.
287294
#endif

llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111

1212
#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
1313
#include "llvm/ADT/PostOrderIterator.h"
14+
#include "llvm/ADT/ScopeExit.h"
1415
#include "llvm/ADT/Twine.h"
16+
#include "llvm/Analysis/BlockFrequencyInfo.h"
17+
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
18+
#include "llvm/Analysis/ProfileSummaryInfo.h"
1519
#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
1620
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
1721
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
@@ -50,16 +54,29 @@ INITIALIZE_PASS_BEGIN(InstructionSelect, DEBUG_TYPE,
5054
false, false)
5155
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
5256
INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
57+
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
58+
INITIALIZE_PASS_DEPENDENCY(LazyBlockFrequencyInfoPass)
5359
INITIALIZE_PASS_END(InstructionSelect, DEBUG_TYPE,
5460
"Select target instructions out of generic instructions",
5561
false, false)
5662

57-
InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) { }
63+
InstructionSelect::InstructionSelect(CodeGenOpt::Level OL)
64+
: MachineFunctionPass(ID), OptLevel(OL) {}
65+
66+
// In order not to crash when calling getAnalysis during testing with -run-pass
67+
// we use the default opt level here instead of None, so that the addRequired()
68+
// calls are made in getAnalysisUsage().
69+
InstructionSelect::InstructionSelect()
70+
: MachineFunctionPass(ID), OptLevel(CodeGenOpt::Default) {}
5871

5972
void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const {
6073
AU.addRequired<TargetPassConfig>();
61-
AU.addRequired<GISelKnownBitsAnalysis>();
62-
AU.addPreserved<GISelKnownBitsAnalysis>();
74+
if (OptLevel != CodeGenOpt::None) {
75+
AU.addRequired<GISelKnownBitsAnalysis>();
76+
AU.addPreserved<GISelKnownBitsAnalysis>();
77+
AU.addRequired<ProfileSummaryInfoWrapperPass>();
78+
LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
79+
}
6380
getSelectionDAGFallbackAnalysisUsage(AU);
6481
MachineFunctionPass::getAnalysisUsage(AU);
6582
}
@@ -71,13 +88,26 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
7188
return false;
7289

7390
LLVM_DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n');
74-
GISelKnownBits &KB = getAnalysis<GISelKnownBitsAnalysis>().get(MF);
7591

7692
const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
7793
InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector();
94+
95+
CodeGenOpt::Level OldOptLevel = OptLevel;
96+
auto RestoreOptLevel = make_scope_exit([=]() { OptLevel = OldOptLevel; });
97+
OptLevel = MF.getFunction().hasOptNone() ? CodeGenOpt::None
98+
: MF.getTarget().getOptLevel();
99+
100+
GISelKnownBits *KB = nullptr;
101+
if (OptLevel != CodeGenOpt::None) {
102+
KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
103+
PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
104+
if (PSI && PSI->hasProfileSummary())
105+
BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
106+
}
107+
78108
CodeGenCoverage CoverageInfo;
79109
assert(ISel && "Cannot work without InstructionSelector");
80-
ISel->setupMF(MF, KB, CoverageInfo);
110+
ISel->setupMF(MF, KB, CoverageInfo, PSI, BFI);
81111

82112
// An optimization remark emitter. Used to report failures.
83113
MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
@@ -102,6 +132,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
102132
#endif
103133

104134
for (MachineBasicBlock *MBB : post_order(&MF)) {
135+
ISel->CurMBB = MBB;
105136
if (MBB->empty())
106137
continue;
107138

llvm/lib/CodeGen/GlobalISel/Utils.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/CodeGen/MachineInstr.h"
2121
#include "llvm/CodeGen/MachineInstrBuilder.h"
2222
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
23+
#include "llvm/CodeGen/MachineSizeOpts.h"
2324
#include "llvm/CodeGen/MachineRegisterInfo.h"
2425
#include "llvm/CodeGen/StackProtector.h"
2526
#include "llvm/CodeGen/TargetInstrInfo.h"
@@ -851,3 +852,10 @@ int64_t llvm::getICmpTrueVal(const TargetLowering &TLI, bool IsVector,
851852
}
852853
llvm_unreachable("Invalid boolean contents");
853854
}
855+
856+
bool llvm::shouldOptForSize(const MachineBasicBlock &MBB,
857+
ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
858+
const auto &F = MBB.getParent()->getFunction();
859+
return F.hasOptSize() || F.hasMinSize() ||
860+
llvm::shouldOptimizeForSize(MBB.getBasicBlock(), PSI, BFI);
861+
}

llvm/lib/Target/AArch64/AArch64TargetMachine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ void AArch64PassConfig::addPreGlobalInstructionSelect() {
588588
}
589589

590590
bool AArch64PassConfig::addGlobalInstructionSelect() {
591-
addPass(new InstructionSelect());
591+
addPass(new InstructionSelect(getOptLevel()));
592592
if (getOptLevel() != CodeGenOpt::None)
593593
addPass(createAArch64PostSelectOptimize());
594594
return false;

llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@
4747
using namespace llvm;
4848
using namespace MIPatternMatch;
4949

50+
namespace llvm {
51+
class BlockFrequencyInfo;
52+
class ProfileSummaryInfo;
53+
}
54+
5055
namespace {
5156

5257
#define GET_GLOBALISEL_PREDICATE_BITSET
@@ -62,9 +67,10 @@ class AArch64InstructionSelector : public InstructionSelector {
6267
bool select(MachineInstr &I) override;
6368
static const char *getName() { return DEBUG_TYPE; }
6469

65-
void setupMF(MachineFunction &MF, GISelKnownBits &KB,
66-
CodeGenCoverage &CoverageInfo) override {
67-
InstructionSelector::setupMF(MF, KB, CoverageInfo);
70+
void setupMF(MachineFunction &MF, GISelKnownBits *KB,
71+
CodeGenCoverage &CoverageInfo, ProfileSummaryInfo *PSI,
72+
BlockFrequencyInfo *BFI) override {
73+
InstructionSelector::setupMF(MF, KB, CoverageInfo, PSI, BFI);
6874

6975
// hasFnAttribute() is expensive to call on every BRCOND selection, so
7076
// cache it here for each run of the selector.
@@ -2426,7 +2432,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
24262432
: AArch64::FPR128RegClass);
24272433

24282434
// For 64b values, emit a constant pool load instead.
2429-
if (DefSize == 64 || DefSize == 128) {
2435+
// For s32, use a cp load if we have optsize/minsize.
2436+
if (DefSize == 64 || DefSize == 128 ||
2437+
(DefSize == 32 && shouldOptForSize(&MF))) {
24302438
auto *FPImm = I.getOperand(1).getFPImm();
24312439
MachineIRBuilder MIB(I);
24322440
auto *LoadMI = emitLoadFromConstantPool(FPImm, MIB);
@@ -4051,10 +4059,18 @@ MachineInstr *AArch64InstructionSelector::emitLoadFromConstantPool(
40514059
AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
40524060
break;
40534061
case 8:
4054-
LoadMI = &*MIRBuilder
4055-
.buildInstr(AArch64::LDRDui, {&AArch64::FPR64RegClass}, {Adrp})
4056-
.addConstantPoolIndex(
4057-
CPIdx, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
4062+
LoadMI =
4063+
&*MIRBuilder
4064+
.buildInstr(AArch64::LDRDui, {&AArch64::FPR64RegClass}, {Adrp})
4065+
.addConstantPoolIndex(CPIdx, 0,
4066+
AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
4067+
break;
4068+
case 4:
4069+
LoadMI =
4070+
&*MIRBuilder
4071+
.buildInstr(AArch64::LDRSui, {&AArch64::FPR32RegClass}, {Adrp})
4072+
.addConstantPoolIndex(CPIdx, 0,
4073+
AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
40584074
break;
40594075
default:
40604076
LLVM_DEBUG(dbgs() << "Could not load from constant pool of type "

llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ AMDGPUInstructionSelector::AMDGPUInstructionSelector(
5959

6060
const char *AMDGPUInstructionSelector::getName() { return DEBUG_TYPE; }
6161

62-
void AMDGPUInstructionSelector::setupMF(MachineFunction &MF, GISelKnownBits &KB,
63-
CodeGenCoverage &CoverageInfo) {
62+
void AMDGPUInstructionSelector::setupMF(MachineFunction &MF, GISelKnownBits *KB,
63+
CodeGenCoverage &CoverageInfo,
64+
ProfileSummaryInfo *PSI,
65+
BlockFrequencyInfo *BFI) {
6466
MRI = &MF.getRegInfo();
6567
Subtarget = &MF.getSubtarget<GCNSubtarget>();
66-
InstructionSelector::setupMF(MF, KB, CoverageInfo);
68+
InstructionSelector::setupMF(MF, KB, CoverageInfo, PSI, BFI);
6769
}
6870

6971
bool AMDGPUInstructionSelector::isVCC(Register Reg,

llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ struct ImageDimIntrinsicInfo;
3636
class AMDGPUInstrInfo;
3737
class AMDGPURegisterBankInfo;
3838
class AMDGPUTargetMachine;
39+
class BlockFrequencyInfo;
40+
class ProfileSummaryInfo;
3941
class GCNSubtarget;
4042
class MachineInstr;
4143
class MachineIRBuilder;
@@ -60,8 +62,9 @@ class AMDGPUInstructionSelector final : public InstructionSelector {
6062
bool select(MachineInstr &I) override;
6163
static const char *getName();
6264

63-
void setupMF(MachineFunction &MF, GISelKnownBits &KB,
64-
CodeGenCoverage &CoverageInfo) override;
65+
void setupMF(MachineFunction &MF, GISelKnownBits *KB,
66+
CodeGenCoverage &CoverageInfo, ProfileSummaryInfo *PSI,
67+
BlockFrequencyInfo *BFI) override;
6568

6669
private:
6770
struct GEPInfo {

llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1114,7 +1114,7 @@ bool GCNPassConfig::addRegBankSelect() {
11141114
}
11151115

11161116
bool GCNPassConfig::addGlobalInstructionSelect() {
1117-
addPass(new InstructionSelect());
1117+
addPass(new InstructionSelect(getOptLevel()));
11181118
// TODO: Fix instruction selection to do the right thing for image
11191119
// instructions with tfe or lwe in the first place, instead of running a
11201120
// separate pass to fix them up?

llvm/lib/Target/ARM/ARMTargetMachine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ bool ARMPassConfig::addRegBankSelect() {
487487
}
488488

489489
bool ARMPassConfig::addGlobalInstructionSelect() {
490-
addPass(new InstructionSelect());
490+
addPass(new InstructionSelect(getOptLevel()));
491491
return false;
492492
}
493493

llvm/lib/Target/Mips/MipsTargetMachine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,6 @@ bool MipsPassConfig::addRegBankSelect() {
335335
}
336336

337337
bool MipsPassConfig::addGlobalInstructionSelect() {
338-
addPass(new InstructionSelect());
338+
addPass(new InstructionSelect(getOptLevel()));
339339
return false;
340340
}

llvm/lib/Target/PowerPC/PPCTargetMachine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,6 @@ bool PPCPassConfig::addRegBankSelect() {
568568
}
569569

570570
bool PPCPassConfig::addGlobalInstructionSelect() {
571-
addPass(new InstructionSelect());
571+
addPass(new InstructionSelect(getOptLevel()));
572572
return false;
573573
}

llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ bool RISCVPassConfig::addRegBankSelect() {
174174
}
175175

176176
bool RISCVPassConfig::addGlobalInstructionSelect() {
177-
addPass(new InstructionSelect());
177+
addPass(new InstructionSelect(getOptLevel()));
178178
return false;
179179
}
180180

llvm/lib/Target/X86/X86TargetMachine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ bool X86PassConfig::addRegBankSelect() {
465465
}
466466

467467
bool X86PassConfig::addGlobalInstructionSelect() {
468-
addPass(new InstructionSelect());
468+
addPass(new InstructionSelect(getOptLevel()));
469469
return false;
470470
}
471471

llvm/test/CodeGen/AArch64/GlobalISel/gisel-commandline-option.ll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@
6565
; VERIFY-NEXT: Verify generated machine code
6666
; ENABLED-NEXT: Localizer
6767
; VERIFY-O0-NEXT: Verify generated machine code
68-
; ENABLED-NEXT: Analysis for ComputingKnownBits
68+
; ENABLED-O1-NEXT: Analysis for ComputingKnownBits
69+
; ENABLED-O1-NEXT: Lazy Branch Probability Analysis
70+
; ENABLED-O1-NEXT: Lazy Block Frequency Analysis
6971
; ENABLED-NEXT: InstructionSelect
7072
; ENABLED-O1-NEXT: AArch64 Post Select Optimizer
7173
; VERIFY-NEXT: Verify generated machine code

0 commit comments

Comments
 (0)