Skip to content

Commit 000279d

Browse files
[NFC][TTI] Introduce getInstructionUniformity API for uniformity analysis (#168903)
This patch introduces a new TargetTransformInfo hook `getInstructionUniformity()` that provides a unified interface for querying target-specific uniformity information about instructions and values. The new hook returns an `InstructionUniformity` enum with three values: - Default: Result is uniform if all operands are uniform (standard propagation) - AlwaysUniform: Result is always uniform regardless of operands - NeverUniform: Result can never be assumed uniform This API wraps the existing `isAlwaysUniform()` and `isSourceOfDivergence()` hooks, providing a single entry point for uniformity queries. Both LLVM IR-level (via TTI) and MIR-level (via TargetInstrInfo) uniformity analysis have been updated to use the new hook. Target implementations: - AMDGPU: Wraps existing `isAlwaysUniform()` and `isSourceOfDivergence()` hooks - NVPTX: Wraps existing `isSourceOfDivergence()` hook This is an NFC change - all implementations return conservative defaults or wrap existing functionality. Ref patch:#137639
1 parent deac791 commit 000279d

File tree

10 files changed

+72
-38
lines changed

10 files changed

+72
-38
lines changed

llvm/include/llvm/Analysis/TargetTransformInfo.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/ADT/APInt.h"
2525
#include "llvm/ADT/ArrayRef.h"
2626
#include "llvm/ADT/BitmaskEnum.h"
27+
#include "llvm/ADT/Uniformity.h"
2728
#include "llvm/Analysis/IVDescriptors.h"
2829
#include "llvm/Analysis/InterestingMemoryOperand.h"
2930
#include "llvm/IR/FMF.h"
@@ -511,16 +512,14 @@ class TargetTransformInfo {
511512
/// uniformity analysis and assume all values are uniform.
512513
LLVM_ABI bool hasBranchDivergence(const Function *F = nullptr) const;
513514

514-
/// Returns whether V is a source of divergence.
515-
///
516-
/// This function provides the target-dependent information for
517-
/// the target-independent UniformityAnalysis.
518-
LLVM_ABI bool isSourceOfDivergence(const Value *V) const;
519-
520-
// Returns true for the target specific
521-
// set of operations which produce uniform result
522-
// even taking non-uniform arguments
523-
LLVM_ABI bool isAlwaysUniform(const Value *V) const;
515+
/// Get target-specific uniformity information for an instruction.
516+
/// This allows targets to provide more fine-grained control over
517+
/// uniformity analysis by specifying whether specific instructions
518+
/// should always or never be considered uniform, or require custom
519+
/// operand-based analysis.
520+
/// \param V The value to query for uniformity information.
521+
/// \return InstructionUniformity.
522+
LLVM_ABI InstructionUniformity getInstructionUniformity(const Value *V) const;
524523

525524
/// Query the target whether the specified address space cast from FromAS to
526525
/// ToAS is valid.

llvm/include/llvm/Analysis/TargetTransformInfoImpl.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ class TargetTransformInfoImplBase {
131131
return false;
132132
}
133133

134-
virtual bool isSourceOfDivergence(const Value *V) const { return false; }
135-
136-
virtual bool isAlwaysUniform(const Value *V) const { return false; }
134+
virtual InstructionUniformity getInstructionUniformity(const Value *V) const {
135+
return InstructionUniformity::Default;
136+
}
137137

138138
virtual bool isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const {
139139
return false;

llvm/include/llvm/CodeGen/BasicTTIImpl.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,6 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
410410
return false;
411411
}
412412

413-
bool isSourceOfDivergence(const Value *V) const override { return false; }
414-
415-
bool isAlwaysUniform(const Value *V) const override { return false; }
416-
417413
bool isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const override {
418414
return false;
419415
}

llvm/lib/Analysis/TargetTransformInfo.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -294,16 +294,14 @@ bool TargetTransformInfo::hasBranchDivergence(const Function *F) const {
294294
return TTIImpl->hasBranchDivergence(F);
295295
}
296296

297-
bool TargetTransformInfo::isSourceOfDivergence(const Value *V) const {
297+
InstructionUniformity
298+
llvm::TargetTransformInfo::getInstructionUniformity(const Value *V) const {
299+
// Calls with the NoDivergenceSource attribute are always uniform.
298300
if (const auto *Call = dyn_cast<CallBase>(V)) {
299301
if (Call->hasFnAttr(Attribute::NoDivergenceSource))
300-
return false;
302+
return InstructionUniformity::AlwaysUniform;
301303
}
302-
return TTIImpl->isSourceOfDivergence(V);
303-
}
304-
305-
bool llvm::TargetTransformInfo::isAlwaysUniform(const Value *V) const {
306-
return TTIImpl->isAlwaysUniform(V);
304+
return TTIImpl->getInstructionUniformity(V);
307305
}
308306

309307
bool llvm::TargetTransformInfo::isValidAddrSpaceCast(unsigned FromAS,

llvm/lib/Analysis/UniformityAnalysis.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,22 @@ bool llvm::GenericUniformityAnalysisImpl<SSAContext>::markDefsDivergent(
3131

3232
template <> void llvm::GenericUniformityAnalysisImpl<SSAContext>::initialize() {
3333
for (auto &I : instructions(F)) {
34-
if (TTI->isSourceOfDivergence(&I))
35-
markDivergent(I);
36-
else if (TTI->isAlwaysUniform(&I))
34+
InstructionUniformity IU = TTI->getInstructionUniformity(&I);
35+
switch (IU) {
36+
case InstructionUniformity::AlwaysUniform:
3737
addUniformOverride(I);
38+
continue;
39+
case InstructionUniformity::NeverUniform:
40+
markDivergent(I);
41+
continue;
42+
case InstructionUniformity::Default:
43+
break;
44+
}
3845
}
3946
for (auto &Arg : F.args()) {
40-
if (TTI->isSourceOfDivergence(&Arg)) {
47+
if (TTI->getInstructionUniformity(&Arg) ==
48+
InstructionUniformity::NeverUniform)
4149
markDivergent(&Arg);
42-
}
4350
}
4451
}
4552

llvm/lib/CodeGen/MachineUniformityAnalysis.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,16 @@ void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::initialize() {
5353
for (const MachineBasicBlock &block : F) {
5454
for (const MachineInstr &instr : block) {
5555
auto uniformity = InstrInfo.getInstructionUniformity(instr);
56-
if (uniformity == InstructionUniformity::AlwaysUniform) {
57-
addUniformOverride(instr);
58-
continue;
59-
}
6056

61-
if (uniformity == InstructionUniformity::NeverUniform) {
57+
switch (uniformity) {
58+
case InstructionUniformity::AlwaysUniform:
59+
addUniformOverride(instr);
60+
break;
61+
case InstructionUniformity::NeverUniform:
6262
markDivergent(instr);
63+
break;
64+
case InstructionUniformity::Default:
65+
break;
6366
}
6467
}
6568
}

llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,3 +1651,14 @@ unsigned GCNTTIImpl::getNumberOfParts(Type *Tp) const {
16511651
}
16521652
return BaseT::getNumberOfParts(Tp);
16531653
}
1654+
1655+
InstructionUniformity
1656+
GCNTTIImpl::getInstructionUniformity(const Value *V) const {
1657+
if (isAlwaysUniform(V))
1658+
return InstructionUniformity::AlwaysUniform;
1659+
1660+
if (isSourceOfDivergence(V))
1661+
return InstructionUniformity::NeverUniform;
1662+
1663+
return InstructionUniformity::Default;
1664+
}

llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@ class GCNTTIImpl final : public BasicTTIImplBase<GCNTTIImpl> {
101101

102102
std::pair<InstructionCost, MVT> getTypeLegalizationCost(Type *Ty) const;
103103

104+
/// \returns true if V might be divergent even when all of its operands
105+
/// are uniform.
106+
bool isSourceOfDivergence(const Value *V) const;
107+
108+
/// Returns true for the target specific set of operations which produce
109+
/// uniform result even taking non-uniform arguments.
110+
bool isAlwaysUniform(const Value *V) const;
111+
104112
public:
105113
explicit GCNTTIImpl(const AMDGPUTargetMachine *TM, const Function &F);
106114

@@ -174,8 +182,6 @@ class GCNTTIImpl final : public BasicTTIImplBase<GCNTTIImpl> {
174182
const Value *Op1) const override;
175183

176184
bool isReadRegisterSourceOfDivergence(const IntrinsicInst *ReadReg) const;
177-
bool isSourceOfDivergence(const Value *V) const override;
178-
bool isAlwaysUniform(const Value *V) const override;
179185

180186
bool isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const override {
181187
// Address space casts must cast between different address spaces.
@@ -302,6 +308,8 @@ class GCNTTIImpl final : public BasicTTIImplBase<GCNTTIImpl> {
302308
/// together under a single i32 value. Otherwise fall back to base
303309
/// implementation.
304310
unsigned getNumberOfParts(Type *Tp) const override;
311+
312+
InstructionUniformity getInstructionUniformity(const Value *V) const override;
305313
};
306314

307315
} // end namespace llvm

llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,3 +674,11 @@ void NVPTXTTIImpl::collectKernelLaunchBounds(
674674
if (MaxNTID.size() > 2)
675675
LB.push_back({"maxntidz", MaxNTID[2]});
676676
}
677+
678+
InstructionUniformity
679+
NVPTXTTIImpl::getInstructionUniformity(const Value *V) const {
680+
if (isSourceOfDivergence(V))
681+
return InstructionUniformity::NeverUniform;
682+
683+
return InstructionUniformity::Default;
684+
}

llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ class NVPTXTTIImpl final : public BasicTTIImplBase<NVPTXTTIImpl> {
3737
const NVPTXSubtarget *getST() const { return ST; };
3838
const NVPTXTargetLowering *getTLI() const { return TLI; };
3939

40+
/// \returns true if the result of the value could potentially be
41+
/// different across threads in a warp.
42+
bool isSourceOfDivergence(const Value *V) const;
43+
4044
public:
4145
explicit NVPTXTTIImpl(const NVPTXTargetMachine *TM, const Function &F)
4246
: BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl()),
@@ -46,8 +50,6 @@ class NVPTXTTIImpl final : public BasicTTIImplBase<NVPTXTTIImpl> {
4650
return true;
4751
}
4852

49-
bool isSourceOfDivergence(const Value *V) const override;
50-
5153
unsigned getFlatAddressSpace() const override {
5254
return AddressSpace::ADDRESS_SPACE_GENERIC;
5355
}
@@ -201,6 +203,8 @@ class NVPTXTTIImpl final : public BasicTTIImplBase<NVPTXTTIImpl> {
201203
// Self-referential globals are not supported.
202204
return false;
203205
}
206+
207+
InstructionUniformity getInstructionUniformity(const Value *V) const override;
204208
};
205209

206210
} // end namespace llvm

0 commit comments

Comments
 (0)