/// 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.
///
ArrayRef<const Value *> 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;
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);
}
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; }
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; }
: 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 {
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.
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,
return true;
}
bool supportsEfficientVectorElementLoadStore() { return false; }
- bool hasBranchDivergence() {
- return false;
- }
+ bool hasBranchDivergence(const Function *F = nullptr) { return false; }
bool enableAggressiveInterleaving(bool LoopHasReductions) {
return false;
}
: 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);