-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[AMDGPU][TTI] Add target hook for the custom instruction uniformity #137639
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,12 +29,39 @@ bool llvm::GenericUniformityAnalysisImpl<SSAContext>::markDefsDivergent( | |
return markDivergent(cast<Value>(&Instr)); | ||
} | ||
|
||
template <> | ||
bool llvm::GenericUniformityAnalysisImpl<SSAContext>::isDivergentUse( | ||
const Use &U) const { | ||
const auto *V = U.get(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no auto |
||
if (isDivergent(V)) | ||
return true; | ||
if (const auto *DefInstr = dyn_cast<Instruction>(V)) { | ||
const auto *UseInstr = cast<Instruction>(U.getUser()); | ||
return isTemporalDivergent(*UseInstr->getParent(), *DefInstr); | ||
} | ||
return false; | ||
} | ||
|
||
template <> | ||
bool llvm::GenericUniformityAnalysisImpl<SSAContext>::isAnyOperandUniform( | ||
const Instruction &I) const { | ||
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { | ||
if (!isa<Instruction>(I.getOperand(i)) && !isa<Argument>(I.getOperand(i))) | ||
continue; | ||
if (!isDivergentUse(I.getOperandUse(i))) | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
template <> void llvm::GenericUniformityAnalysisImpl<SSAContext>::initialize() { | ||
for (auto &I : instructions(F)) { | ||
if (TTI->isSourceOfDivergence(&I)) | ||
markDivergent(I); | ||
else if (TTI->isAlwaysUniform(&I)) | ||
addUniformOverride(I); | ||
else if (TTI->isSpecialUniformIntrinsic(I)) | ||
addSpecialUniformIntrinsic(I); | ||
} | ||
for (auto &Arg : F.args()) { | ||
if (TTI->isSourceOfDivergence(&Arg)) { | ||
|
@@ -48,6 +75,11 @@ void llvm::GenericUniformityAnalysisImpl<SSAContext>::pushUsers( | |
const Value *V) { | ||
for (const auto *User : V->users()) { | ||
if (const auto *UserInstr = dyn_cast<const Instruction>(User)) { | ||
if (SpecialUniformIntrinsics.count(UserInstr) && | ||
isAnyOperandUniform(*UserInstr)) { | ||
Comment on lines
+78
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is too specific of a "specially uniform" check. I'd expect this operand validation to be an operation dependent property There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I think as @jayfoad suggested. Probably I should let this be decided by the target. The only thing is that it would be costlier, and the decision of uniformity will be taken outside of UA, which I am not sure is acceptable? |
||
addUniformOverride(*UserInstr); | ||
continue; | ||
} | ||
markDivergent(*UserInstr); | ||
} | ||
} | ||
|
@@ -88,19 +120,6 @@ void llvm::GenericUniformityAnalysisImpl< | |
} | ||
} | ||
|
||
template <> | ||
bool llvm::GenericUniformityAnalysisImpl<SSAContext>::isDivergentUse( | ||
const Use &U) const { | ||
const auto *V = U.get(); | ||
if (isDivergent(V)) | ||
return true; | ||
if (const auto *DefInstr = dyn_cast<Instruction>(V)) { | ||
const auto *UseInstr = cast<Instruction>(U.getUser()); | ||
return isTemporalDivergent(*UseInstr->getParent(), *DefInstr); | ||
} | ||
return false; | ||
} | ||
|
||
// This ensures explicit instantiation of | ||
// GenericUniformityAnalysisImpl::ImplDeleter::operator() | ||
template class llvm::GenericUniformityInfo<SSAContext>; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 | ||
; RUN: opt -mtriple amdgcn-- -passes='print<uniformity>' -disable-output %s 2>&1 | FileCheck %s | ||
|
||
; CHECK: ALL VALUES UNIFORM | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These aren't always always uniform, so need test coverage for all the conditions that would make this divergent |
||
define amdgpu_kernel void @v_permlane16_b32(ptr addrspace(1) %out, i32 %src0, i32 %src1, i32 %src2) #0 { | ||
%v = call i32 @llvm.amdgcn.permlane16.i32(i32 %src0, i32 %src0, i32 %src1, i32 %src2, i1 false, i1 false) #0 | ||
store i32 %v, ptr addrspace(1) %out | ||
ret void | ||
} | ||
|
||
; CHECK: ALL VALUES UNIFORM | ||
define amdgpu_kernel void @v_permlanex16_b32(ptr addrspace(1) %out, i32 %src0, i32 %src1, i32 %src2) #0 { | ||
%v = call i32 @llvm.amdgcn.permlanex16.i32(i32 %src0, i32 %src0, i32 %src1, i32 %src2, i1 false, i1 false) #0 | ||
store i32 %v, ptr addrspace(1) %out | ||
ret void | ||
} | ||
|
||
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: | ||
; CHECK: {{.*}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear to me what 'special' means. Is there a better name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The term
special
means here thatintrinsic can be uniform
though not all of its operands are uniform.Right, I am also not convinced of this name. will rename it later based on refined functionality.