12
12
// / some instruction whose operand was previously recognized as statically
13
13
// / uniform is later on no longer recognized as statically uniform. However, the
14
14
// / semantics of how programs execute don't (and must not, for this precise
15
- // / reason[0] ) care about static uniformity, they only ever care about dynamic
15
+ // / reason) care about static uniformity, they only ever care about dynamic
16
16
// / uniformity. And every instruction that's downstream and cares about dynamic
17
17
// / uniformity must be convergent (and isel will introduce v_readfirstlane for
18
18
// / them if their operands can't be proven statically uniform).
@@ -42,17 +42,7 @@ using namespace llvm::AMDGPU;
42
42
using namespace llvm ::PatternMatch;
43
43
44
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
- };
45
+ using UniformityTracker = ValueMap<const Value *, bool >;
56
46
57
47
// / Wrapper for querying uniformity info that first checks new instructions.
58
48
static bool isDivergentUseWithNew (const Use &U, const UniformityInfo &UI,
@@ -78,7 +68,6 @@ static bool optimizeUniformIntrinsic(IntrinsicInst &II,
78
68
return false ;
79
69
LLVM_DEBUG (dbgs () << " Replacing " << II << " with " << *Src << ' \n ' );
80
70
II.replaceAllUsesWith (Src);
81
- Tracker.eraseIfDead (&II);
82
71
II.eraseFromParent ();
83
72
return true ;
84
73
}
@@ -104,28 +93,24 @@ static bool optimizeUniformIntrinsic(IntrinsicInst &II,
104
93
// Case: (icmp eq %ballot, 0) -> xor %ballot_arg, 1
105
94
Instruction *NotOp =
106
95
BinaryOperator::CreateNot (Src, " " , ICmp->getIterator ());
107
- Tracker. mark ( NotOp, true ) ; // NOT preserves uniformity
96
+ Tracker[ NotOp] = true ; // NOT preserves uniformity
108
97
LLVM_DEBUG (dbgs () << " Replacing ICMP_EQ: " << *NotOp << ' \n ' );
109
98
ICmp->replaceAllUsesWith (NotOp);
110
- Tracker.eraseIfDead (ICmp);
111
99
ICmp->eraseFromParent ();
112
100
Changed = true ;
113
101
} else if (Pred == ICmpInst::ICMP_NE && match (OtherOp, m_Zero ())) {
114
102
// Case: (icmp ne %ballot, 0) -> %ballot_arg
115
103
LLVM_DEBUG (dbgs () << " Replacing ICMP_NE with ballot argument: "
116
104
<< *Src << ' \n ' );
117
105
ICmp->replaceAllUsesWith (Src);
118
- Tracker.eraseIfDead (ICmp);
119
106
ICmp->eraseFromParent ();
120
107
Changed = true ;
121
108
}
122
109
}
123
110
}
124
111
// Erase the intrinsic if it has no remaining uses.
125
- if (II.use_empty ()) {
126
- Tracker.eraseIfDead (&II);
112
+ if (II.use_empty ())
127
113
II.eraseFromParent ();
128
- }
129
114
return Changed;
130
115
}
131
116
default :
0 commit comments