Index: llvm/include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- llvm/include/llvm/Analysis/TargetTransformInfo.h +++ llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -398,7 +398,11 @@ /// Branch divergence has a significantly negative impact on GPU performance /// when threads in the same wavefront take different paths due to conditional /// branches. - bool hasBranchDivergence() const; + /// + /// If \p F is passed, provides a context function. If \p F is known to only + /// execute in a single threaded environment, the target may choose to skip + /// uniformity analysis and assume all values are uniform. + bool hasBranchDivergence(const Function *F = nullptr) const; /// Returns whether V is a source of divergence. /// @@ -1681,7 +1685,7 @@ ArrayRef Operands, TargetCostKind CostKind) = 0; virtual BranchProbability getPredictableBranchThreshold() = 0; - virtual bool hasBranchDivergence() = 0; + virtual bool hasBranchDivergence(const Function *F = nullptr) = 0; virtual bool isSourceOfDivergence(const Value *V) = 0; virtual bool isAlwaysUniform(const Value *V) = 0; virtual bool isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const = 0; @@ -2052,7 +2056,9 @@ BranchProbability getPredictableBranchThreshold() override { return Impl.getPredictableBranchThreshold(); } - bool hasBranchDivergence() override { return Impl.hasBranchDivergence(); } + bool hasBranchDivergence(const Function *F = nullptr) override { + return Impl.hasBranchDivergence(F); + } bool isSourceOfDivergence(const Value *V) override { return Impl.isSourceOfDivergence(V); } Index: llvm/include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -87,7 +87,7 @@ return BranchProbability(99, 100); } - bool hasBranchDivergence() const { return false; } + bool hasBranchDivergence(const Function *F = nullptr) const { return false; } bool isSourceOfDivergence(const Value *V) const { return false; } Index: llvm/include/llvm/CodeGen/BasicTTIImpl.h =================================================================== --- llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -276,7 +276,7 @@ E, AddressSpace, Alignment, MachineMemOperand::MONone, Fast); } - bool hasBranchDivergence() { return false; } + bool hasBranchDivergence(const Function *F = nullptr) { return false; } bool isSourceOfDivergence(const Value *V) { return false; } Index: llvm/lib/Analysis/TargetTransformInfo.cpp =================================================================== --- llvm/lib/Analysis/TargetTransformInfo.cpp +++ llvm/lib/Analysis/TargetTransformInfo.cpp @@ -259,8 +259,8 @@ : TTIImpl->getPredictableBranchThreshold(); } -bool TargetTransformInfo::hasBranchDivergence() const { - return TTIImpl->hasBranchDivergence(); +bool TargetTransformInfo::hasBranchDivergence(const Function *F) const { + return TTIImpl->hasBranchDivergence(F); } bool TargetTransformInfo::isSourceOfDivergence(const Value *V) const { Index: llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h +++ llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h @@ -100,7 +100,7 @@ public: explicit GCNTTIImpl(const AMDGPUTargetMachine *TM, const Function &F); - bool hasBranchDivergence() { return true; } + bool hasBranchDivergence(const Function *F = nullptr) const; void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, Index: llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp @@ -297,6 +297,10 @@ HasFP64FP16Denormals = Mode.allFP64FP16Denormals(); } +bool GCNTTIImpl::hasBranchDivergence(const Function *F) const { + return true; +} + unsigned GCNTTIImpl::getNumberOfRegisters(unsigned RCID) const { // NB: RCID is not an RCID. In fact it is 0 or 1 for scalar or vector // registers. See getRegisterClassForType for the implementation. Index: llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.h =================================================================== --- llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.h +++ llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.h @@ -92,9 +92,7 @@ return true; } bool supportsEfficientVectorElementLoadStore() { return false; } - bool hasBranchDivergence() { - return false; - } + bool hasBranchDivergence(const Function *F = nullptr) { return false; } bool enableAggressiveInterleaving(bool LoopHasReductions) { return false; } Index: llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h =================================================================== --- llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h +++ llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h @@ -41,7 +41,7 @@ : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl()), TLI(ST->getTargetLowering()) {} - bool hasBranchDivergence() { return true; } + bool hasBranchDivergence(const Function *F = nullptr) { return true; } bool isSourceOfDivergence(const Value *V);