Skip to content

Commit a22ae4f

Browse files
committed
[cxx-interop] Workaround a template instantiation issue, part 2
This is a follow-up to d483a8a. rdar://145512778
1 parent 0b67fe8 commit a22ae4f

File tree

2 files changed

+138
-136
lines changed
  • llvm
    • include/llvm/Transforms/Scalar
    • lib/Transforms/Scalar

2 files changed

+138
-136
lines changed

llvm/include/llvm/Transforms/Scalar/GVN.h

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/ADT/SmallVector.h"
2222
#include "llvm/IR/Dominators.h"
2323
#include "llvm/IR/InstrTypes.h"
24+
#include "llvm/IR/IntrinsicInst.h"
2425
#include "llvm/IR/PassManager.h"
2526
#include "llvm/IR/ValueHandle.h"
2627
#include "llvm/Support/Allocator.h"
@@ -444,4 +445,141 @@ struct llvm::GVNPass::Expression {
444445
}
445446
};
446447

448+
449+
/// Represents a particular available value that we know how to materialize.
450+
/// Materialization of an AvailableValue never fails. An AvailableValue is
451+
/// implicitly associated with a rematerialization point which is the
452+
/// location of the instruction from which it was formed.
453+
struct llvm::gvn::AvailableValue {
454+
enum class ValType {
455+
SimpleVal, // A simple offsetted value that is accessed.
456+
LoadVal, // A value produced by a load.
457+
MemIntrin, // A memory intrinsic which is loaded from.
458+
UndefVal, // A UndefValue representing a value from dead block (which
459+
// is not yet physically removed from the CFG).
460+
SelectVal, // A pointer select which is loaded from and for which the load
461+
// can be replace by a value select.
462+
};
463+
464+
/// Val - The value that is live out of the block.
465+
Value *Val;
466+
/// Kind of the live-out value.
467+
ValType Kind;
468+
469+
/// Offset - The byte offset in Val that is interesting for the load query.
470+
unsigned Offset = 0;
471+
/// V1, V2 - The dominating non-clobbered values of SelectVal.
472+
Value *V1 = nullptr, *V2 = nullptr;
473+
474+
static AvailableValue get(Value *V, unsigned Offset = 0) {
475+
AvailableValue Res;
476+
Res.Val = V;
477+
Res.Kind = ValType::SimpleVal;
478+
Res.Offset = Offset;
479+
return Res;
480+
}
481+
482+
static AvailableValue getMI(MemIntrinsic *MI, unsigned Offset = 0) {
483+
AvailableValue Res;
484+
Res.Val = MI;
485+
Res.Kind = ValType::MemIntrin;
486+
Res.Offset = Offset;
487+
return Res;
488+
}
489+
490+
static AvailableValue getLoad(LoadInst *Load, unsigned Offset = 0) {
491+
AvailableValue Res;
492+
Res.Val = Load;
493+
Res.Kind = ValType::LoadVal;
494+
Res.Offset = Offset;
495+
return Res;
496+
}
497+
498+
static AvailableValue getUndef() {
499+
AvailableValue Res;
500+
Res.Val = nullptr;
501+
Res.Kind = ValType::UndefVal;
502+
Res.Offset = 0;
503+
return Res;
504+
}
505+
506+
static AvailableValue getSelect(SelectInst *Sel, Value *V1, Value *V2) {
507+
AvailableValue Res;
508+
Res.Val = Sel;
509+
Res.Kind = ValType::SelectVal;
510+
Res.Offset = 0;
511+
Res.V1 = V1;
512+
Res.V2 = V2;
513+
return Res;
514+
}
515+
516+
bool isSimpleValue() const { return Kind == ValType::SimpleVal; }
517+
bool isCoercedLoadValue() const { return Kind == ValType::LoadVal; }
518+
bool isMemIntrinValue() const { return Kind == ValType::MemIntrin; }
519+
bool isUndefValue() const { return Kind == ValType::UndefVal; }
520+
bool isSelectValue() const { return Kind == ValType::SelectVal; }
521+
522+
Value *getSimpleValue() const {
523+
assert(isSimpleValue() && "Wrong accessor");
524+
return Val;
525+
}
526+
527+
LoadInst *getCoercedLoadValue() const {
528+
assert(isCoercedLoadValue() && "Wrong accessor");
529+
return cast<LoadInst>(Val);
530+
}
531+
532+
MemIntrinsic *getMemIntrinValue() const {
533+
assert(isMemIntrinValue() && "Wrong accessor");
534+
return cast<MemIntrinsic>(Val);
535+
}
536+
537+
SelectInst *getSelectValue() const {
538+
assert(isSelectValue() && "Wrong accessor");
539+
return cast<SelectInst>(Val);
540+
}
541+
542+
/// Emit code at the specified insertion point to adjust the value defined
543+
/// here to the specified type. This handles various coercion cases.
544+
Value *MaterializeAdjustedValue(LoadInst *Load, Instruction *InsertPt,
545+
GVNPass &gvn) const;
546+
};
547+
548+
/// Represents an AvailableValue which can be rematerialized at the end of
549+
/// the associated BasicBlock.
550+
struct llvm::gvn::AvailableValueInBlock {
551+
/// BB - The basic block in question.
552+
BasicBlock *BB = nullptr;
553+
554+
/// AV - The actual available value
555+
AvailableValue AV;
556+
557+
static AvailableValueInBlock get(BasicBlock *BB, AvailableValue &&AV) {
558+
AvailableValueInBlock Res;
559+
Res.BB = BB;
560+
Res.AV = std::move(AV);
561+
return Res;
562+
}
563+
564+
static AvailableValueInBlock get(BasicBlock *BB, Value *V,
565+
unsigned Offset = 0) {
566+
return get(BB, AvailableValue::get(V, Offset));
567+
}
568+
569+
static AvailableValueInBlock getUndef(BasicBlock *BB) {
570+
return get(BB, AvailableValue::getUndef());
571+
}
572+
573+
static AvailableValueInBlock getSelect(BasicBlock *BB, SelectInst *Sel,
574+
Value *V1, Value *V2) {
575+
return get(BB, AvailableValue::getSelect(Sel, V1, V2));
576+
}
577+
578+
/// Emit code at the end of this block to adjust the value defined here to
579+
/// the specified type. This handles various coercion cases.
580+
Value *MaterializeAdjustedValue(LoadInst *Load, GVNPass &gvn) const {
581+
return AV.MaterializeAdjustedValue(Load, BB->getTerminator(), gvn);
582+
}
583+
};
584+
447585
#endif // LLVM_TRANSFORMS_SCALAR_GVN_H

llvm/lib/Transforms/Scalar/GVN.cpp

Lines changed: 0 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -157,142 +157,6 @@ template <> struct DenseMapInfo<GVNPass::Expression> {
157157

158158
} // end namespace llvm
159159

160-
/// Represents a particular available value that we know how to materialize.
161-
/// Materialization of an AvailableValue never fails. An AvailableValue is
162-
/// implicitly associated with a rematerialization point which is the
163-
/// location of the instruction from which it was formed.
164-
struct llvm::gvn::AvailableValue {
165-
enum class ValType {
166-
SimpleVal, // A simple offsetted value that is accessed.
167-
LoadVal, // A value produced by a load.
168-
MemIntrin, // A memory intrinsic which is loaded from.
169-
UndefVal, // A UndefValue representing a value from dead block (which
170-
// is not yet physically removed from the CFG).
171-
SelectVal, // A pointer select which is loaded from and for which the load
172-
// can be replace by a value select.
173-
};
174-
175-
/// Val - The value that is live out of the block.
176-
Value *Val;
177-
/// Kind of the live-out value.
178-
ValType Kind;
179-
180-
/// Offset - The byte offset in Val that is interesting for the load query.
181-
unsigned Offset = 0;
182-
/// V1, V2 - The dominating non-clobbered values of SelectVal.
183-
Value *V1 = nullptr, *V2 = nullptr;
184-
185-
static AvailableValue get(Value *V, unsigned Offset = 0) {
186-
AvailableValue Res;
187-
Res.Val = V;
188-
Res.Kind = ValType::SimpleVal;
189-
Res.Offset = Offset;
190-
return Res;
191-
}
192-
193-
static AvailableValue getMI(MemIntrinsic *MI, unsigned Offset = 0) {
194-
AvailableValue Res;
195-
Res.Val = MI;
196-
Res.Kind = ValType::MemIntrin;
197-
Res.Offset = Offset;
198-
return Res;
199-
}
200-
201-
static AvailableValue getLoad(LoadInst *Load, unsigned Offset = 0) {
202-
AvailableValue Res;
203-
Res.Val = Load;
204-
Res.Kind = ValType::LoadVal;
205-
Res.Offset = Offset;
206-
return Res;
207-
}
208-
209-
static AvailableValue getUndef() {
210-
AvailableValue Res;
211-
Res.Val = nullptr;
212-
Res.Kind = ValType::UndefVal;
213-
Res.Offset = 0;
214-
return Res;
215-
}
216-
217-
static AvailableValue getSelect(SelectInst *Sel, Value *V1, Value *V2) {
218-
AvailableValue Res;
219-
Res.Val = Sel;
220-
Res.Kind = ValType::SelectVal;
221-
Res.Offset = 0;
222-
Res.V1 = V1;
223-
Res.V2 = V2;
224-
return Res;
225-
}
226-
227-
bool isSimpleValue() const { return Kind == ValType::SimpleVal; }
228-
bool isCoercedLoadValue() const { return Kind == ValType::LoadVal; }
229-
bool isMemIntrinValue() const { return Kind == ValType::MemIntrin; }
230-
bool isUndefValue() const { return Kind == ValType::UndefVal; }
231-
bool isSelectValue() const { return Kind == ValType::SelectVal; }
232-
233-
Value *getSimpleValue() const {
234-
assert(isSimpleValue() && "Wrong accessor");
235-
return Val;
236-
}
237-
238-
LoadInst *getCoercedLoadValue() const {
239-
assert(isCoercedLoadValue() && "Wrong accessor");
240-
return cast<LoadInst>(Val);
241-
}
242-
243-
MemIntrinsic *getMemIntrinValue() const {
244-
assert(isMemIntrinValue() && "Wrong accessor");
245-
return cast<MemIntrinsic>(Val);
246-
}
247-
248-
SelectInst *getSelectValue() const {
249-
assert(isSelectValue() && "Wrong accessor");
250-
return cast<SelectInst>(Val);
251-
}
252-
253-
/// Emit code at the specified insertion point to adjust the value defined
254-
/// here to the specified type. This handles various coercion cases.
255-
Value *MaterializeAdjustedValue(LoadInst *Load, Instruction *InsertPt,
256-
GVNPass &gvn) const;
257-
};
258-
259-
/// Represents an AvailableValue which can be rematerialized at the end of
260-
/// the associated BasicBlock.
261-
struct llvm::gvn::AvailableValueInBlock {
262-
/// BB - The basic block in question.
263-
BasicBlock *BB = nullptr;
264-
265-
/// AV - The actual available value
266-
AvailableValue AV;
267-
268-
static AvailableValueInBlock get(BasicBlock *BB, AvailableValue &&AV) {
269-
AvailableValueInBlock Res;
270-
Res.BB = BB;
271-
Res.AV = std::move(AV);
272-
return Res;
273-
}
274-
275-
static AvailableValueInBlock get(BasicBlock *BB, Value *V,
276-
unsigned Offset = 0) {
277-
return get(BB, AvailableValue::get(V, Offset));
278-
}
279-
280-
static AvailableValueInBlock getUndef(BasicBlock *BB) {
281-
return get(BB, AvailableValue::getUndef());
282-
}
283-
284-
static AvailableValueInBlock getSelect(BasicBlock *BB, SelectInst *Sel,
285-
Value *V1, Value *V2) {
286-
return get(BB, AvailableValue::getSelect(Sel, V1, V2));
287-
}
288-
289-
/// Emit code at the end of this block to adjust the value defined here to
290-
/// the specified type. This handles various coercion cases.
291-
Value *MaterializeAdjustedValue(LoadInst *Load, GVNPass &gvn) const {
292-
return AV.MaterializeAdjustedValue(Load, BB->getTerminator(), gvn);
293-
}
294-
};
295-
296160
//===----------------------------------------------------------------------===//
297161
// ValueTable Internal Functions
298162
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)