Skip to content

Commit a4e01af

Browse files
committed
- Add llc-pipeline test to track pass run ordering
- move instcombine before spirv-prelegalizer simplifies the matcher - update matcher and inst combine application - make SPIRVPreLegalizer preserve previous passes.
1 parent 763f6d4 commit a4e01af

File tree

4 files changed

+162
-21
lines changed

4 files changed

+162
-21
lines changed

llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "SPIRVUtils.h"
1818
#include "llvm/ADT/PostOrderIterator.h"
1919
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
20+
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
21+
#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
2022
#include "llvm/IR/Attributes.h"
2123
#include "llvm/IR/Constants.h"
2224
#include "llvm/IR/DebugInfoMetadata.h"
@@ -35,9 +37,16 @@ class SPIRVPreLegalizer : public MachineFunctionPass {
3537
initializeSPIRVPreLegalizerPass(*PassRegistry::getPassRegistry());
3638
}
3739
bool runOnMachineFunction(MachineFunction &MF) override;
40+
void getAnalysisUsage(AnalysisUsage &AU) const override;
3841
};
3942
} // namespace
4043

44+
void SPIRVPreLegalizer::getAnalysisUsage(AnalysisUsage &AU) const {
45+
AU.addPreserved<GISelKnownBitsAnalysis>();
46+
AU.addPreserved<GISelCSEAnalysisWrapperPass>();
47+
MachineFunctionPass::getAnalysisUsage(AU);
48+
}
49+
4150
static void
4251
addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
4352
const SPIRVSubtarget &STI,

llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,9 @@ bool matchLengthToDistance(MachineInstr &MI, MachineRegisterInfo &MRI) {
6464
return false;
6565

6666
// First operand of MI is `G_INTRINSIC` so start at operand 2.
67-
Register SubAssignTypeReg = MI.getOperand(2).getReg();
68-
MachineInstr *Sub1AssignTypeInst = MRI.getVRegDef(SubAssignTypeReg);
69-
if (!Sub1AssignTypeInst ||
70-
Sub1AssignTypeInst->getDesc().getOpcode() != SPIRV::ASSIGN_TYPE)
71-
return false;
72-
73-
Register SubReg1 = Sub1AssignTypeInst->getOperand(1).getReg();
74-
MachineInstr *SubInstr1 = MRI.getVRegDef(SubReg1);
75-
if (!SubInstr1 || SubInstr1->getOpcode() != TargetOpcode::G_FSUB)
67+
Register SubReg = MI.getOperand(2).getReg();
68+
MachineInstr *SubInstr = MRI.getVRegDef(SubReg);
69+
if (!SubInstr || SubInstr->getOpcode() != TargetOpcode::G_FSUB)
7670
return false;
7771

7872
return true;
@@ -81,9 +75,7 @@ void applySPIRVDistance(MachineInstr &MI, MachineRegisterInfo &MRI,
8175
MachineIRBuilder &B) {
8276

8377
// Extract the operands for X and Y from the match criteria.
84-
Register SubAssignTypeReg = MI.getOperand(2).getReg();
85-
MachineInstr *Sub1AssignTypeInst = MRI.getVRegDef(SubAssignTypeReg);
86-
Register SubDestReg = Sub1AssignTypeInst->getOperand(1).getReg();
78+
Register SubDestReg = MI.getOperand(2).getReg();
8779
MachineInstr *SubInstr = MRI.getVRegDef(SubDestReg);
8880
Register SubOperand1 = SubInstr->getOperand(1).getReg();
8981
Register SubOperand2 = SubInstr->getOperand(2).getReg();
@@ -105,14 +97,14 @@ void applySPIRVDistance(MachineInstr &MI, MachineRegisterInfo &MRI,
10597
.addUse(SubOperand2); // Operand Y
10698

10799
auto RemoveAllUses = [&](Register Reg) {
108-
for (auto &UseMI : MRI.use_instructions(Reg)) {
109-
UseMI.eraseFromParent();
110-
}
111-
};
100+
SmallVector<MachineInstr *, 4> UsesToErase;
101+
for (auto &UseMI : MRI.use_instructions(Reg))
102+
UsesToErase.push_back(&UseMI);
112103

113-
RemoveAllUses(
114-
SubAssignTypeReg); // remove all uses of FSUB ASSIGN_TYPE register
115-
MI.eraseFromParent(); // remove spv_length intrinsic
104+
// calling eraseFromParent to early invalidates the iterator.
105+
for (auto *MIToErase : UsesToErase)
106+
MIToErase->eraseFromParent();
107+
};
116108
RemoveAllUses(SubDestReg); // remove all uses of FSUB Result
117109
SubInstr->eraseFromParent(); // remove FSUB instruction
118110
}
@@ -131,7 +123,7 @@ class SPIRVPreLegalizerCombinerImpl : public Combiner {
131123
const SPIRVSubtarget &STI, MachineDominatorTree *MDT,
132124
const LegalizerInfo *LI);
133125

134-
static const char *getName() { return "SPIRV00PreLegalizerCombiner"; }
126+
static const char *getName() { return "SPIRVPreLegalizerCombiner"; }
135127

136128
bool tryCombineAll(MachineInstr &I) const override;
137129

llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ bool SPIRVPassConfig::addIRTranslator() {
218218
}
219219

220220
void SPIRVPassConfig::addPreLegalizeMachineIR() {
221-
addPass(createSPIRVPreLegalizerPass());
222221
addPass(createSPIRVPreLegalizerCombiner());
222+
addPass(createSPIRVPreLegalizerPass());
223223
}
224224

225225
// Use the default legalizer.
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
; RUN: llc -mtriple=spirv-unknown-unknown -debug-pass=Structure < %s -o /dev/null 2>&1 | \
2+
; RUN: grep -v "Verify generated machine code" | FileCheck %s
3+
4+
; REQUIRES: asserts
5+
6+
7+
; CHECK-LABEL: Pass Arguments:
8+
; CHECK-NEXT: Target Library Information
9+
; CHECK-NEXT: Target Pass Configuration
10+
; CHECK-NEXT: Machine Module Information
11+
; CHECK-NEXT: Target Transform Information
12+
; CHECK-NEXT: Type-Based Alias Analysis
13+
; CHECK-NEXT: Scoped NoAlias Alias Analysis
14+
; CHECK-NEXT: Assumption Cache Tracker
15+
; CHECK-NEXT: Profile summary info
16+
; CHECK-NEXT: Create Garbage Collector Module Metadata
17+
; CHECK-NEXT: Machine Branch Probability Analysis
18+
; CHECK-NEXT: ModulePass Manager
19+
; CHECK-NEXT: Pre-ISel Intrinsic Lowering
20+
; CHECK-NEXT: FunctionPass Manager
21+
; CHECK-NEXT: Expand large div/rem
22+
; CHECK-NEXT: Expand large fp convert
23+
; CHECK-NEXT: Module Verifier
24+
; CHECK-NEXT: Dominator Tree Construction
25+
; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
26+
; CHECK-NEXT: Natural Loop Information
27+
; CHECK-NEXT: Canonicalize natural loops
28+
; CHECK-NEXT: Scalar Evolution Analysis
29+
; CHECK-NEXT: Loop Pass Manager
30+
; CHECK-NEXT: Canonicalize Freeze Instructions in Loops
31+
; CHECK-NEXT: Induction Variable Users
32+
; CHECK-NEXT: Loop Strength Reduction
33+
; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
34+
; CHECK-NEXT: Function Alias Analysis Results
35+
; CHECK-NEXT: Merge contiguous icmps into a memcmp
36+
; CHECK-NEXT: Natural Loop Information
37+
; CHECK-NEXT: Lazy Branch Probability Analysis
38+
; CHECK-NEXT: Lazy Block Frequency Analysis
39+
; CHECK-NEXT: Expand memcmp() to load/stores
40+
; CHECK-NEXT: Lower Garbage Collection Instructions
41+
; CHECK-NEXT: Shadow Stack GC Lowering
42+
; CHECK-NEXT: Remove unreachable blocks from the CFG
43+
; CHECK-NEXT: Natural Loop Information
44+
; CHECK-NEXT: Post-Dominator Tree Construction
45+
; CHECK-NEXT: Branch Probability Analysis
46+
; CHECK-NEXT: Block Frequency Analysis
47+
; CHECK-NEXT: Constant Hoisting
48+
; CHECK-NEXT: Replace intrinsics with calls to vector library
49+
; CHECK-NEXT: Partially inline calls to library functions
50+
; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining)
51+
; CHECK-NEXT: Scalarize Masked Memory Intrinsics
52+
; CHECK-NEXT: Expand reduction intrinsics
53+
; CHECK-NEXT: Natural Loop Information
54+
; CHECK-NEXT: Canonicalize natural loops
55+
; CHECK-NEXT: Unnamed pass: implement Pass::getPassName()
56+
; CHECK-NEXT: SPIRV convergence regions analysis
57+
; CHECK-NEXT: SPIRV split region exit blocks
58+
; CHECK-NEXT: Dominator Tree Construction
59+
; CHECK-NEXT: Natural Loop Information
60+
; CHECK-NEXT: structurize SPIRV
61+
; CHECK-NEXT: Dominator Tree Construction
62+
; CHECK-NEXT: Promote Memory to Register
63+
; CHECK-NEXT: SPIR-V Regularizer
64+
; CHECK-NEXT: SPIRV prepare functions
65+
; CHECK-NEXT: FunctionPass Manager
66+
; CHECK-NEXT: SPIRV strip convergent intrinsics
67+
; CHECK-NEXT: Dominator Tree Construction
68+
; CHECK-NEXT: Natural Loop Information
69+
; CHECK-NEXT: CodeGen Prepare
70+
; CHECK-NEXT: Lower invoke and unwind, for unwindless code generators
71+
; CHECK-NEXT: Remove unreachable blocks from the CFG
72+
; CHECK-NEXT: SPIRV emit intrinsics
73+
; CHECK-NEXT: FunctionPass Manager
74+
; CHECK-NEXT: Dominator Tree Construction
75+
; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
76+
; CHECK-NEXT: Function Alias Analysis Results
77+
; CHECK-NEXT: ObjC ARC contraction
78+
; CHECK-NEXT: Prepare callbr
79+
; CHECK-NEXT: Safe Stack instrumentation pass
80+
; CHECK-NEXT: Insert stack protectors
81+
; CHECK-NEXT: Module Verifier
82+
; CHECK-NEXT: Analysis containing CSE Info
83+
; CHECK-NEXT: Natural Loop Information
84+
; CHECK-NEXT: Post-Dominator Tree Construction
85+
; CHECK-NEXT: Branch Probability Analysis
86+
; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
87+
; CHECK-NEXT: Function Alias Analysis Results
88+
; CHECK-NEXT: IRTranslator
89+
; CHECK-NEXT: Analysis for ComputingKnownBits
90+
; CHECK-NEXT: MachineDominator Tree Construction
91+
; CHECK-NEXT: Analysis containing CSE Info
92+
; CHECK-NEXT: SPIRVPreLegalizerCombiner
93+
; CHECK-NEXT: SPIRV pre legalizer
94+
; CHECK-NEXT: Legalizer
95+
; CHECK-NEXT: SPIRV post legalizer
96+
; CHECK-NEXT: Analysis for ComputingKnownBits
97+
; CHECK-NEXT: Lazy Branch Probability Analysis
98+
; CHECK-NEXT: Lazy Block Frequency Analysis
99+
; CHECK-NEXT: InstructionSelect
100+
; CHECK-NEXT: ResetMachineFunction
101+
; CHECK-NEXT: Finalize ISel and expand pseudo-instructions
102+
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
103+
; CHECK-NEXT: Early Tail Duplication
104+
; CHECK-NEXT: Optimize machine instruction PHIs
105+
; CHECK-NEXT: Slot index numbering
106+
; CHECK-NEXT: Merge disjoint stack slots
107+
; CHECK-NEXT: Local Stack Slot Allocation
108+
; CHECK-NEXT: Remove dead machine instructions
109+
; CHECK-NEXT: MachineDominator Tree Construction
110+
; CHECK-NEXT: Machine Natural Loop Construction
111+
; CHECK-NEXT: Machine Block Frequency Analysis
112+
; CHECK-NEXT: Early Machine Loop Invariant Code Motion
113+
; CHECK-NEXT: MachineDominator Tree Construction
114+
; CHECK-NEXT: Machine Block Frequency Analysis
115+
; CHECK-NEXT: Machine Common Subexpression Elimination
116+
; CHECK-NEXT: MachinePostDominator Tree Construction
117+
; CHECK-NEXT: Machine Cycle Info Analysis
118+
; CHECK-NEXT: Machine code sinking
119+
; CHECK-NEXT: Peephole Optimizations
120+
; CHECK-NEXT: Remove dead machine instructions
121+
; CHECK-NEXT: Remove Redundant DEBUG_VALUE analysis
122+
; CHECK-NEXT: Fixup Statepoint Caller Saved
123+
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
124+
; CHECK-NEXT: Machine Optimization Remark Emitter
125+
; CHECK-NEXT: Prologue/Epilogue Insertion & Frame Finalization
126+
; CHECK-NEXT: Tail Duplication
127+
; CHECK-NEXT: Post-RA pseudo instruction expansion pass
128+
; CHECK-NEXT: Analyze Machine Code For Garbage Collection
129+
; CHECK-NEXT: Insert fentry calls
130+
; CHECK-NEXT: Insert XRay ops
131+
; CHECK-NEXT: Machine Sanitizer Binary Metadata
132+
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
133+
; CHECK-NEXT: Machine Optimization Remark Emitter
134+
; CHECK-NEXT: Stack Frame Layout Analysis
135+
; CHECK-NEXT: SPIRV module analysis
136+
; CHECK-NEXT: FunctionPass Manager
137+
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
138+
; CHECK-NEXT: Machine Optimization Remark Emitter
139+
; CHECK-NEXT: SPIRV Assembly Printer
140+
; CHECK-NEXT: Free MachineFunction

0 commit comments

Comments
 (0)