Skip to content

Commit fbd3f78

Browse files
track newly inserted instruction
1 parent ddc0b56 commit fbd3f78

File tree

1 file changed

+26
-12
lines changed

1 file changed

+26
-12
lines changed

llvm/lib/Target/AMDGPU/AMDGPUUniformIntrinsicCombine.cpp

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,39 +41,50 @@ using namespace llvm;
4141
using namespace llvm::AMDGPU;
4242
using namespace llvm::PatternMatch;
4343

44-
/// Map for newly created IR instructions and their uniformity.
45-
using NewUniformityMap = DenseMap<const Value *, bool>;
44+
/// Tracks uniformity of newly created instructions.
45+
/// Wraps a ValueMap so we can enforce consistent mark/erase usage.
46+
struct UniformityTracker : DenseMap<const Value *, bool> {
47+
/// Record that V has known uniformity.
48+
void mark(Value *V, bool IsUniform) { (*this)[V] = IsUniform; }
49+
50+
/// Erase V from the map if it is an instruction with no uses anymore.
51+
void eraseIfDead(Value *V) {
52+
if (auto *I = dyn_cast<Instruction>(V); I && I->use_empty())
53+
this->erase(V);
54+
}
55+
};
4656

4757
/// Wrapper for querying uniformity info that first checks new instructions.
4858
static bool isDivergentUseWithNew(const Use &U, const UniformityInfo &UI,
49-
const NewUniformityMap &NewUMap) {
59+
const UniformityTracker &Tracker) {
5060
Value *V = U.get();
51-
if (auto It = NewUMap.find(V); It != NewUMap.end())
61+
if (auto It = Tracker.find(V); It != Tracker.end())
5262
return !It->second; // divergent if marked false
5363
return UI.isDivergentUse(U);
5464
}
5565

5666
/// Optimizes uniform intrinsics.
5767
static bool optimizeUniformIntrinsic(IntrinsicInst &II,
5868
const UniformityInfo &UI,
59-
NewUniformityMap &NewUMap) {
69+
UniformityTracker &Tracker) {
6070
llvm::Intrinsic::ID IID = II.getIntrinsicID();
6171

6272
switch (IID) {
6373
case Intrinsic::amdgcn_permlane64:
6474
case Intrinsic::amdgcn_readfirstlane:
6575
case Intrinsic::amdgcn_readlane: {
6676
Value *Src = II.getArgOperand(0);
67-
if (isDivergentUseWithNew(II.getOperandUse(0), UI, NewUMap))
77+
if (isDivergentUseWithNew(II.getOperandUse(0), UI, Tracker))
6878
return false;
6979
LLVM_DEBUG(dbgs() << "Replacing " << II << " with " << *Src << '\n');
7080
II.replaceAllUsesWith(Src);
81+
Tracker.eraseIfDead(&II);
7182
II.eraseFromParent();
7283
return true;
7384
}
7485
case Intrinsic::amdgcn_ballot: {
7586
Value *Src = II.getArgOperand(0);
76-
if (isDivergentUseWithNew(II.getOperandUse(0), UI, NewUMap))
87+
if (isDivergentUseWithNew(II.getOperandUse(0), UI, Tracker))
7788
return false;
7889
LLVM_DEBUG(dbgs() << "Found uniform ballot intrinsic: " << II << '\n');
7990

@@ -93,25 +104,28 @@ static bool optimizeUniformIntrinsic(IntrinsicInst &II,
93104
// Case: (icmp eq %ballot, 0) -> xor %ballot_arg, 1
94105
Instruction *NotOp =
95106
BinaryOperator::CreateNot(Src, "", ICmp->getIterator());
96-
// Record uniformity: Src is uniform, and NOT preserves uniformity.
97-
NewUMap[NotOp] = true;
107+
Tracker.mark(NotOp, true); // NOT preserves uniformity
98108
LLVM_DEBUG(dbgs() << "Replacing ICMP_EQ: " << *NotOp << '\n');
99109
ICmp->replaceAllUsesWith(NotOp);
110+
Tracker.eraseIfDead(ICmp);
100111
ICmp->eraseFromParent();
101112
Changed = true;
102113
} else if (Pred == ICmpInst::ICMP_NE && match(OtherOp, m_Zero())) {
103114
// Case: (icmp ne %ballot, 0) -> %ballot_arg
104115
LLVM_DEBUG(dbgs() << "Replacing ICMP_NE with ballot argument: "
105116
<< *Src << '\n');
106117
ICmp->replaceAllUsesWith(Src);
118+
Tracker.eraseIfDead(ICmp);
107119
ICmp->eraseFromParent();
108120
Changed = true;
109121
}
110122
}
111123
}
112124
// Erase the intrinsic if it has no remaining uses.
113-
if (II.use_empty())
125+
if (II.use_empty()) {
126+
Tracker.eraseIfDead(&II);
114127
II.eraseFromParent();
128+
}
115129
return Changed;
116130
}
117131
default:
@@ -123,7 +137,7 @@ static bool optimizeUniformIntrinsic(IntrinsicInst &II,
123137
/// Iterate over intrinsics in the module to optimise.
124138
static bool runUniformIntrinsicCombine(Module &M, ModuleAnalysisManager &AM) {
125139
bool IsChanged = false;
126-
NewUniformityMap NewUMap;
140+
UniformityTracker Tracker;
127141

128142
FunctionAnalysisManager &FAM =
129143
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
@@ -145,7 +159,7 @@ static bool runUniformIntrinsicCombine(Module &M, ModuleAnalysisManager &AM) {
145159
continue;
146160

147161
const auto &UI = FAM.getResult<UniformityInfoAnalysis>(*ParentF);
148-
IsChanged |= optimizeUniformIntrinsic(*II, UI, NewUMap);
162+
IsChanged |= optimizeUniformIntrinsic(*II, UI, Tracker);
149163
}
150164
}
151165
return IsChanged;

0 commit comments

Comments
 (0)