Skip to content

Commit 3eaa53e

Browse files
committed
Reapply "[IRBuilder] Virtualize IRBuilder"
Relative to the original commit, this fixes some warnings, and is based on the deletion of the IRBuilder copy constructor in D74693. The automatic copy constructor would no longer be safe. ----- Related llvm-dev thread: http://lists.llvm.org/pipermail/llvm-dev/2020-February/138951.html This patch moves the IRBuilder from templating over the constant folder and inserter towards making both of these virtual. There are a couple of motivations for this: 1. It's not possible to share code between use-sites that use different IRBuilder folders/inserters (short of templating the code and moving it into headers). 2. Methods currently defined on IRBuilderBase (which is not templated) do not use the custom inserter, resulting in subtle bugs (e.g. incorrect InstCombine worklist management). It would be possible to move those into the templated IRBuilder, but... 3. The vast majority of the IRBuilder implementation has to live in the header, because it depends on the template arguments. 4. We have many unnecessary dependencies on IRBuilder.h, because it is not easy to forward-declare. (Significant parts of the backend depend on it via TargetLowering.h, for example.) This patch addresses the issue by making the following changes: * IRBuilderDefaultInserter::InsertHelper becomes virtual. IRBuilderBase accepts a reference to it. * IRBuilderFolder is introduced as a virtual base class. It is implemented by ConstantFolder (default), NoFolder and TargetFolder. IRBuilderBase has a reference to this as well. * All the logic is moved from IRBuilder to IRBuilderBase. This means that methods can in the future replace their IRBuilder<> & uses (or other specific IRBuilder types) with IRBuilderBase & and thus be usable with different IRBuilders. * The IRBuilder class is now a thin wrapper around IRBuilderBase. Essentially it only stores the folder and inserter and takes care of constructing the base builder. What this patch doesn't do, but should be simple followups after this change: * Fixing use of the inserter for creation methods originally defined on IRBuilderBase. * Replacing IRBuilder<> uses in arguments with IRBuilderBase, where useful. * Moving code from the IRBuilder header to the source file. From the user perspective, these changes should be mostly transparent: The only thing that consumers using a custom inserted may need to do is inherit from IRBuilderDefaultInserter publicly and mark their InsertHelper as public. Differential Revision: https://reviews.llvm.org/D73835
1 parent 55cfb1f commit 3eaa53e

File tree

10 files changed

+451
-255
lines changed

10 files changed

+451
-255
lines changed

clang/lib/CodeGen/CGBuilder.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,15 @@ class CodeGenFunction;
2222
/// This is an IRBuilder insertion helper that forwards to
2323
/// CodeGenFunction::InsertHelper, which adds necessary metadata to
2424
/// instructions.
25-
class CGBuilderInserter : protected llvm::IRBuilderDefaultInserter {
25+
class CGBuilderInserter final : public llvm::IRBuilderDefaultInserter {
2626
public:
2727
CGBuilderInserter() = default;
2828
explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {}
2929

30-
protected:
3130
/// This forwards to CodeGenFunction::InsertHelper.
3231
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
3332
llvm::BasicBlock *BB,
34-
llvm::BasicBlock::iterator InsertPt) const;
33+
llvm::BasicBlock::iterator InsertPt) const override;
3534
private:
3635
CodeGenFunction *CGF = nullptr;
3736
};

llvm/include/llvm/Analysis/TargetFolder.h

Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@
2222
#include "llvm/Analysis/ConstantFolding.h"
2323
#include "llvm/IR/Constants.h"
2424
#include "llvm/IR/InstrTypes.h"
25+
#include "llvm/IR/IRBuilderFolder.h"
2526

2627
namespace llvm {
2728

2829
class DataLayout;
2930

3031
/// TargetFolder - Create constants with target dependent folding.
31-
class TargetFolder {
32+
class TargetFolder final : public IRBuilderFolder {
3233
const DataLayout &DL;
3334

3435
/// Fold - Fold the constant using target specific information.
@@ -38,6 +39,8 @@ class TargetFolder {
3839
return C;
3940
}
4041

42+
virtual void anchor();
43+
4144
public:
4245
explicit TargetFolder(const DataLayout &DL) : DL(DL) {}
4346

@@ -46,66 +49,70 @@ class TargetFolder {
4649
//===--------------------------------------------------------------------===//
4750

4851
Constant *CreateAdd(Constant *LHS, Constant *RHS,
49-
bool HasNUW = false, bool HasNSW = false) const {
52+
bool HasNUW = false, bool HasNSW = false) const override {
5053
return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW));
5154
}
52-
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
55+
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override {
5356
return Fold(ConstantExpr::getFAdd(LHS, RHS));
5457
}
5558
Constant *CreateSub(Constant *LHS, Constant *RHS,
56-
bool HasNUW = false, bool HasNSW = false) const {
59+
bool HasNUW = false, bool HasNSW = false) const override {
5760
return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW));
5861
}
59-
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
62+
Constant *CreateFSub(Constant *LHS, Constant *RHS) const override {
6063
return Fold(ConstantExpr::getFSub(LHS, RHS));
6164
}
6265
Constant *CreateMul(Constant *LHS, Constant *RHS,
63-
bool HasNUW = false, bool HasNSW = false) const {
66+
bool HasNUW = false, bool HasNSW = false) const override {
6467
return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW));
6568
}
66-
Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
69+
Constant *CreateFMul(Constant *LHS, Constant *RHS) const override {
6770
return Fold(ConstantExpr::getFMul(LHS, RHS));
6871
}
69-
Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
72+
Constant *CreateUDiv(Constant *LHS, Constant *RHS,
73+
bool isExact = false) const override {
7074
return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact));
7175
}
72-
Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
76+
Constant *CreateSDiv(Constant *LHS, Constant *RHS,
77+
bool isExact = false) const override {
7378
return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact));
7479
}
75-
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
80+
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const override {
7681
return Fold(ConstantExpr::getFDiv(LHS, RHS));
7782
}
78-
Constant *CreateURem(Constant *LHS, Constant *RHS) const {
83+
Constant *CreateURem(Constant *LHS, Constant *RHS) const override {
7984
return Fold(ConstantExpr::getURem(LHS, RHS));
8085
}
81-
Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
86+
Constant *CreateSRem(Constant *LHS, Constant *RHS) const override {
8287
return Fold(ConstantExpr::getSRem(LHS, RHS));
8388
}
84-
Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
89+
Constant *CreateFRem(Constant *LHS, Constant *RHS) const override {
8590
return Fold(ConstantExpr::getFRem(LHS, RHS));
8691
}
8792
Constant *CreateShl(Constant *LHS, Constant *RHS,
88-
bool HasNUW = false, bool HasNSW = false) const {
93+
bool HasNUW = false, bool HasNSW = false) const override {
8994
return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW));
9095
}
91-
Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
96+
Constant *CreateLShr(Constant *LHS, Constant *RHS,
97+
bool isExact = false) const override {
9298
return Fold(ConstantExpr::getLShr(LHS, RHS, isExact));
9399
}
94-
Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
100+
Constant *CreateAShr(Constant *LHS, Constant *RHS,
101+
bool isExact = false) const override {
95102
return Fold(ConstantExpr::getAShr(LHS, RHS, isExact));
96103
}
97-
Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
104+
Constant *CreateAnd(Constant *LHS, Constant *RHS) const override {
98105
return Fold(ConstantExpr::getAnd(LHS, RHS));
99106
}
100-
Constant *CreateOr(Constant *LHS, Constant *RHS) const {
107+
Constant *CreateOr(Constant *LHS, Constant *RHS) const override {
101108
return Fold(ConstantExpr::getOr(LHS, RHS));
102109
}
103-
Constant *CreateXor(Constant *LHS, Constant *RHS) const {
110+
Constant *CreateXor(Constant *LHS, Constant *RHS) const override {
104111
return Fold(ConstantExpr::getXor(LHS, RHS));
105112
}
106113

107114
Constant *CreateBinOp(Instruction::BinaryOps Opc,
108-
Constant *LHS, Constant *RHS) const {
115+
Constant *LHS, Constant *RHS) const override {
109116
return Fold(ConstantExpr::get(Opc, LHS, RHS));
110117
}
111118

@@ -114,17 +121,17 @@ class TargetFolder {
114121
//===--------------------------------------------------------------------===//
115122

116123
Constant *CreateNeg(Constant *C,
117-
bool HasNUW = false, bool HasNSW = false) const {
124+
bool HasNUW = false, bool HasNSW = false) const override {
118125
return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW));
119126
}
120-
Constant *CreateFNeg(Constant *C) const {
127+
Constant *CreateFNeg(Constant *C) const override {
121128
return Fold(ConstantExpr::getFNeg(C));
122129
}
123-
Constant *CreateNot(Constant *C) const {
130+
Constant *CreateNot(Constant *C) const override {
124131
return Fold(ConstantExpr::getNot(C));
125132
}
126133

127-
Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
134+
Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const override {
128135
return Fold(ConstantExpr::get(Opc, C));
129136
}
130137

@@ -133,33 +140,34 @@ class TargetFolder {
133140
//===--------------------------------------------------------------------===//
134141

135142
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
136-
ArrayRef<Constant *> IdxList) const {
143+
ArrayRef<Constant *> IdxList) const override {
137144
return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
138145
}
139-
Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
146+
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
147+
Constant *Idx) const override {
140148
// This form of the function only exists to avoid ambiguous overload
141149
// warnings about whether to convert Idx to ArrayRef<Constant *> or
142150
// ArrayRef<Value *>.
143151
return Fold(ConstantExpr::getGetElementPtr(Ty, C, Idx));
144152
}
145153
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
146-
ArrayRef<Value *> IdxList) const {
154+
ArrayRef<Value *> IdxList) const override {
147155
return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
148156
}
149157

150-
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
151-
ArrayRef<Constant *> IdxList) const {
158+
Constant *CreateInBoundsGetElementPtr(
159+
Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
152160
return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
153161
}
154162
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
155-
Constant *Idx) const {
163+
Constant *Idx) const override {
156164
// This form of the function only exists to avoid ambiguous overload
157165
// warnings about whether to convert Idx to ArrayRef<Constant *> or
158166
// ArrayRef<Value *>.
159167
return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx));
160168
}
161-
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
162-
ArrayRef<Value *> IdxList) const {
169+
Constant *CreateInBoundsGetElementPtr(
170+
Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
163171
return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
164172
}
165173

@@ -168,54 +176,54 @@ class TargetFolder {
168176
//===--------------------------------------------------------------------===//
169177

170178
Constant *CreateCast(Instruction::CastOps Op, Constant *C,
171-
Type *DestTy) const {
179+
Type *DestTy) const override {
172180
if (C->getType() == DestTy)
173181
return C; // avoid calling Fold
174182
return Fold(ConstantExpr::getCast(Op, C, DestTy));
175183
}
176184
Constant *CreateIntCast(Constant *C, Type *DestTy,
177-
bool isSigned) const {
185+
bool isSigned) const override {
178186
if (C->getType() == DestTy)
179187
return C; // avoid calling Fold
180188
return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
181189
}
182-
Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
190+
Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
183191
if (C->getType() == DestTy)
184192
return C; // avoid calling Fold
185193
return Fold(ConstantExpr::getPointerCast(C, DestTy));
186194
}
187-
Constant *CreateFPCast(Constant *C, Type *DestTy) const {
195+
Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
188196
if (C->getType() == DestTy)
189197
return C; // avoid calling Fold
190198
return Fold(ConstantExpr::getFPCast(C, DestTy));
191199
}
192-
Constant *CreateBitCast(Constant *C, Type *DestTy) const {
200+
Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
193201
return CreateCast(Instruction::BitCast, C, DestTy);
194202
}
195-
Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
203+
Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
196204
return CreateCast(Instruction::IntToPtr, C, DestTy);
197205
}
198-
Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
206+
Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
199207
return CreateCast(Instruction::PtrToInt, C, DestTy);
200208
}
201-
Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
209+
Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
202210
if (C->getType() == DestTy)
203211
return C; // avoid calling Fold
204212
return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
205213
}
206-
Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
214+
Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
207215
if (C->getType() == DestTy)
208216
return C; // avoid calling Fold
209217
return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
210218
}
211-
Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
219+
Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
212220
if (C->getType() == DestTy)
213221
return C; // avoid calling Fold
214222
return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
215223
}
216224

217225
Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
218-
Type *DestTy) const {
226+
Type *DestTy) const override {
219227
if (C->getType() == DestTy)
220228
return C; // avoid calling Fold
221229
return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy));
@@ -226,43 +234,44 @@ class TargetFolder {
226234
//===--------------------------------------------------------------------===//
227235

228236
Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
229-
Constant *RHS) const {
237+
Constant *RHS) const override {
230238
return Fold(ConstantExpr::getCompare(P, LHS, RHS));
231239
}
232240
Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
233-
Constant *RHS) const {
241+
Constant *RHS) const override {
234242
return Fold(ConstantExpr::getCompare(P, LHS, RHS));
235243
}
236244

237245
//===--------------------------------------------------------------------===//
238246
// Other Instructions
239247
//===--------------------------------------------------------------------===//
240248

241-
Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
249+
Constant *CreateSelect(Constant *C, Constant *True,
250+
Constant *False) const override {
242251
return Fold(ConstantExpr::getSelect(C, True, False));
243252
}
244253

245-
Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
254+
Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const override {
246255
return Fold(ConstantExpr::getExtractElement(Vec, Idx));
247256
}
248257

249258
Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
250-
Constant *Idx) const {
259+
Constant *Idx) const override {
251260
return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
252261
}
253262

254263
Constant *CreateShuffleVector(Constant *V1, Constant *V2,
255-
Constant *Mask) const {
264+
Constant *Mask) const override {
256265
return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
257266
}
258267

259268
Constant *CreateExtractValue(Constant *Agg,
260-
ArrayRef<unsigned> IdxList) const {
269+
ArrayRef<unsigned> IdxList) const override {
261270
return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
262271
}
263272

264273
Constant *CreateInsertValue(Constant *Agg, Constant *Val,
265-
ArrayRef<unsigned> IdxList) const {
274+
ArrayRef<unsigned> IdxList) const override {
266275
return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
267276
}
268277
};

0 commit comments

Comments
 (0)