Skip to content

Commit 3c7f740

Browse files
committed
[TypePromotion] Use SetVectors instead of PtrSets
Remove the chance of non-deterministic insertion of zexts of the sources by using a SetVector instead of SmallPtrSet. Do the same for sinks for consistency and to negate the small issue from possibly happening. The SafeWrap instructions are now also stored in a SmallVector. The IRPromoter members of these structures have been changed to references. Differential Revision: https://reviews.llvm.org/D72322
1 parent 58e2e92 commit 3c7f740

File tree

1 file changed

+30
-40
lines changed

1 file changed

+30
-40
lines changed

llvm/lib/CodeGen/TypePromotion.cpp

+30-40
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,15 @@ class IRPromoter {
107107
LLVMContext &Ctx;
108108
IntegerType *OrigTy = nullptr;
109109
unsigned PromotedWidth = 0;
110+
SetVector<Value*> &Visited;
111+
SetVector<Value*> &Sources;
112+
SetVector<Instruction*> &Sinks;
113+
SmallVectorImpl<Instruction*> &SafeWrap;
110114
IntegerType *ExtTy = nullptr;
111115
SmallPtrSet<Value*, 8> NewInsts;
112116
SmallPtrSet<Instruction*, 4> InstsToRemove;
113117
DenseMap<Value*, SmallVector<Type*, 4>> TruncTysMap;
114118
SmallPtrSet<Value*, 8> Promoted;
115-
SetVector<Value*> *Visited;
116-
SmallPtrSetImpl<Value*> *Sources;
117-
SmallPtrSetImpl<Instruction*> *Sinks;
118-
SmallPtrSetImpl<Instruction*> *SafeToPromote;
119-
SmallPtrSetImpl<Instruction*> *SafeWrap;
120119

121120
void ReplaceAllUsersOfWith(Value *From, Value *To);
122121
void PrepareWrappingAdds(void);
@@ -127,18 +126,18 @@ class IRPromoter {
127126
void Cleanup(void);
128127

129128
public:
130-
IRPromoter(LLVMContext &C, IntegerType *Ty, unsigned Width) :
131-
Ctx(C), OrigTy(Ty), PromotedWidth(Width) {
129+
IRPromoter(LLVMContext &C, IntegerType *Ty, unsigned Width,
130+
SetVector<Value*> &visited, SetVector<Value*> &sources,
131+
SetVector<Instruction*> &sinks,
132+
SmallVectorImpl<Instruction*> &wrap) :
133+
Ctx(C), OrigTy(Ty), PromotedWidth(Width), Visited(visited),
134+
Sources(sources), Sinks(sinks), SafeWrap(wrap) {
132135
ExtTy = IntegerType::get(Ctx, PromotedWidth);
133136
assert(OrigTy->getPrimitiveSizeInBits() < ExtTy->getPrimitiveSizeInBits()
134137
&& "Original type not smaller than extended type");
135138
}
136139

137-
void Mutate(SetVector<Value*> &Visited,
138-
SmallPtrSetImpl<Value*> &Sources,
139-
SmallPtrSetImpl<Instruction*> &Sinks,
140-
SmallPtrSetImpl<Instruction*> &SafeToPromote,
141-
SmallPtrSetImpl<Instruction*> &SafeWrap);
140+
void Mutate();
142141
};
143142

144143
class TypePromotion : public FunctionPass {
@@ -147,7 +146,7 @@ class TypePromotion : public FunctionPass {
147146
unsigned RegisterBitWidth = 0;
148147
SmallPtrSet<Value*, 16> AllVisited;
149148
SmallPtrSet<Instruction*, 8> SafeToPromote;
150-
SmallPtrSet<Instruction*, 4> SafeWrap;
149+
SmallVector<Instruction*, 4> SafeWrap;
151150

152151
// Does V have the same size result type as TypeSize.
153152
bool EqualTypeSize(Value *V);
@@ -382,7 +381,7 @@ bool TypePromotion::isSafeWrap(Instruction *I) {
382381

383382
LLVM_DEBUG(dbgs() << "IR Promotion: Allowing safe overflow for "
384383
<< *I << "\n");
385-
SafeWrap.insert(I);
384+
SafeWrap.push_back(I);
386385
return true;
387386
}
388387

@@ -451,7 +450,7 @@ void IRPromoter::PrepareWrappingAdds() {
451450
// create an equivalent instruction using a positive immediate.
452451
// That positive immediate can then be zext along with all the other
453452
// immediates later.
454-
for (auto *I : *SafeWrap) {
453+
for (auto *I : SafeWrap) {
455454
if (I->getOpcode() != Instruction::Add)
456455
continue;
457456

@@ -473,7 +472,7 @@ void IRPromoter::PrepareWrappingAdds() {
473472
LLVM_DEBUG(dbgs() << "IR Promotion: New equivalent: " << *NewVal << "\n");
474473
}
475474
for (auto *I : NewInsts)
476-
Visited->insert(I);
475+
Visited.insert(I);
477476
}
478477

479478
void IRPromoter::ExtendSources() {
@@ -500,7 +499,7 @@ void IRPromoter::ExtendSources() {
500499

501500
// Now, insert extending instructions between the sources and their users.
502501
LLVM_DEBUG(dbgs() << "IR Promotion: Promoting sources:\n");
503-
for (auto V : *Sources) {
502+
for (auto V : Sources) {
504503
LLVM_DEBUG(dbgs() << " - " << *V << "\n");
505504
if (auto *I = dyn_cast<Instruction>(V))
506505
InsertZExt(I, I);
@@ -521,12 +520,12 @@ void IRPromoter::PromoteTree() {
521520

522521
// Mutate the types of the instructions within the tree. Here we handle
523522
// constant operands.
524-
for (auto *V : *Visited) {
525-
if (Sources->count(V))
523+
for (auto *V : Visited) {
524+
if (Sources.count(V))
526525
continue;
527526

528527
auto *I = cast<Instruction>(V);
529-
if (Sinks->count(I))
528+
if (Sinks.count(I))
530529
continue;
531530

532531
for (unsigned i = 0, e = I->getNumOperands(); i < e; ++i) {
@@ -558,7 +557,7 @@ void IRPromoter::TruncateSinks() {
558557
if (!isa<Instruction>(V) || !isa<IntegerType>(V->getType()))
559558
return nullptr;
560559

561-
if ((!Promoted.count(V) && !NewInsts.count(V)) || Sources->count(V))
560+
if ((!Promoted.count(V) && !NewInsts.count(V)) || Sources.count(V))
562561
return nullptr;
563562

564563
LLVM_DEBUG(dbgs() << "IR Promotion: Creating " << *TruncTy << " Trunc for "
@@ -572,7 +571,7 @@ void IRPromoter::TruncateSinks() {
572571

573572
// Fix up any stores or returns that use the results of the promoted
574573
// chain.
575-
for (auto I : *Sinks) {
574+
for (auto I : Sinks) {
576575
LLVM_DEBUG(dbgs() << "IR Promotion: For Sink: " << *I << "\n");
577576

578577
// Handle calls separately as we need to iterate over arg operands.
@@ -613,7 +612,7 @@ void IRPromoter::Cleanup() {
613612
LLVM_DEBUG(dbgs() << "IR Promotion: Cleanup..\n");
614613
// Some zexts will now have become redundant, along with their trunc
615614
// operands, so remove them
616-
for (auto V : *Visited) {
615+
for (auto V : Visited) {
617616
if (!isa<ZExtInst>(V))
618617
continue;
619618

@@ -652,8 +651,8 @@ void IRPromoter::ConvertTruncs() {
652651
LLVM_DEBUG(dbgs() << "IR Promotion: Converting truncs..\n");
653652
IRBuilder<> Builder{Ctx};
654653

655-
for (auto *V : *Visited) {
656-
if (!isa<TruncInst>(V) || Sources->count(V))
654+
for (auto *V : Visited) {
655+
if (!isa<TruncInst>(V) || Sources.count(V))
657656
continue;
658657

659658
auto *Trunc = cast<TruncInst>(V);
@@ -673,20 +672,10 @@ void IRPromoter::ConvertTruncs() {
673672
}
674673
}
675674

676-
void IRPromoter::Mutate(SetVector<Value*> &Visited,
677-
SmallPtrSetImpl<Value*> &Sources,
678-
SmallPtrSetImpl<Instruction*> &Sinks,
679-
SmallPtrSetImpl<Instruction*> &SafeToPromote,
680-
SmallPtrSetImpl<Instruction*> &SafeWrap) {
675+
void IRPromoter::Mutate() {
681676
LLVM_DEBUG(dbgs() << "IR Promotion: Promoting use-def chains from "
682677
<< OrigTy->getBitWidth() << " to " << PromotedWidth << "-bits\n");
683678

684-
this->Visited = &Visited;
685-
this->Sources = &Sources;
686-
this->Sinks = &Sinks;
687-
this->SafeToPromote = &SafeToPromote;
688-
this->SafeWrap = &SafeWrap;
689-
690679
// Cache original types of the values that will likely need truncating
691680
for (auto *I : Sinks) {
692681
if (auto *Call = dyn_cast<CallInst>(I)) {
@@ -830,8 +819,8 @@ bool TypePromotion::TryToPromote(Value *V, unsigned PromotedWidth) {
830819
<< TypeSize << " bits to " << PromotedWidth << "\n");
831820

832821
SetVector<Value*> WorkList;
833-
SmallPtrSet<Value*, 8> Sources;
834-
SmallPtrSet<Instruction*, 4> Sinks;
822+
SetVector<Value*> Sources;
823+
SetVector<Instruction*> Sinks;
835824
SetVector<Value*> CurrentVisited;
836825
WorkList.insert(V);
837826

@@ -936,8 +925,9 @@ bool TypePromotion::TryToPromote(Value *V, unsigned PromotedWidth) {
936925
if (ToPromote < 2)
937926
return false;
938927

939-
IRPromoter Promoter(*Ctx, cast<IntegerType>(OrigTy), PromotedWidth);
940-
Promoter.Mutate(CurrentVisited, Sources, Sinks, SafeToPromote, SafeWrap);
928+
IRPromoter Promoter(*Ctx, cast<IntegerType>(OrigTy), PromotedWidth,
929+
CurrentVisited, Sources, Sinks, SafeWrap);
930+
Promoter.Mutate();
941931
return true;
942932
}
943933

0 commit comments

Comments
 (0)