23#define DEBUG_TYPE "spirv-regularizer"
33 StringRef getPassName()
const override {
return "SPIR-V Regularizer"; }
45char SPIRVRegularizer::ID = 0;
58void SPIRVRegularizer::runLowerConstExpr(
Function &
F) {
60 std::list<Instruction *> WorkList;
62 WorkList.push_back(&
II);
64 auto FBegin =
F.begin();
65 while (!WorkList.empty()) {
66 Instruction *II = WorkList.front();
68 auto LowerOp = [&II, &FBegin, &F](Value *V) -> Value * {
71 auto *CE = cast<ConstantExpr>(V);
72 LLVM_DEBUG(dbgs() <<
"[lowerConstantExpressions] " << *CE);
73 auto ReplInst = CE->getAsInstruction();
74 auto InsPoint = II->getParent() == &*FBegin ? II : &FBegin->back();
75 ReplInst->insertBefore(InsPoint->getIterator());
76 LLVM_DEBUG(dbgs() <<
" -> " << *ReplInst <<
'\n');
77 std::vector<Instruction *> Users;
79 for (auto U : CE->users()) {
80 LLVM_DEBUG(dbgs() <<
"[lowerConstantExpressions] Use: " << *U <<
'\n');
81 auto InstUser = dyn_cast<Instruction>(U);
83 if (InstUser && InstUser->getParent()->getParent() == &F)
84 Users.push_back(InstUser);
86 for (auto &User : Users) {
87 if (ReplInst->getParent() == User->getParent() &&
88 User->comesBefore(ReplInst))
89 ReplInst->moveBefore(User->getIterator());
90 User->replaceUsesOfWith(CE, ReplInst);
96 auto LowerConstantVec = [&
II, &LowerOp, &WorkList,
98 unsigned NumOfOp) ->
Value * {
99 if (std::all_of(Vec->op_begin(), Vec->op_end(), [](Value *V) {
100 return isa<ConstantExpr>(V) || isa<Function>(V);
104 std::list<Value *> OpList;
106 std::back_inserter(OpList),
107 [LowerOp](
Value *V) { return LowerOp(V); });
108 Value *Repl =
nullptr;
112 PhiII ? &PhiII->getIncomingBlock(NumOfOp)->back() :
II;
113 std::list<Instruction *> ReplList;
114 for (
auto V : OpList) {
116 ReplList.push_back(Inst);
122 WorkList.splice(WorkList.begin(), ReplList);
127 for (
unsigned OI = 0, OE =
II->getNumOperands(); OI != OE; ++OI) {
128 auto *
Op =
II->getOperand(OI);
130 Value *ReplInst = LowerConstantVec(Vec, OI);
132 II->replaceUsesOfWith(
Op, ReplInst);
140 Value *ReplInst =
nullptr;
142 ReplInst = LowerConstantVec(Vec, OI);
144 ReplInst = LowerOp(CE);
149 II->setOperand(OI, RepMDVal);
160void SPIRVRegularizer::runLowerI1Comparisons(
Function &
F) {
166 bool IsI1 =
Cmp->getOperand(0)->getType()->isIntegerTy(1);
170 auto Pred =
Cmp->getPredicate();
172 Pred >= ICmpInst::ICMP_UGT && Pred <= ICmpInst::ICMP_SLE;
182 case ICmpInst::ICMP_UGT:
183 case ICmpInst::ICMP_SLT:
185 Result = Builder.CreateAnd(
P, Builder.CreateNot(Q));
187 case ICmpInst::ICMP_ULT:
188 case ICmpInst::ICMP_SGT:
190 Result = Builder.CreateAnd(Q, Builder.CreateNot(
P));
192 case ICmpInst::ICMP_ULE:
193 case ICmpInst::ICMP_SGE:
195 Result = Builder.CreateOr(Q, Builder.CreateNot(
P));
197 case ICmpInst::ICMP_UGE:
198 case ICmpInst::ICMP_SLE:
200 Result = Builder.CreateOr(
P, Builder.CreateNot(Q));
207 Cmp->replaceAllUsesWith(Result);
208 Cmp->eraseFromParent();
212bool SPIRVRegularizer::runOnFunction(Function &
F) {
213 runLowerI1Comparisons(
F);
214 runLowerConstExpr(
F);
219 return new SPIRVRegularizer();
Expand Atomic instructions
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool runOnFunction(Function &F, bool PostInlining)
This header defines various interfaces for pass management in LLVM.
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Represent the analysis usage information of a pass.
Constant Vector Declarations.
FixedVectorType * getType() const
Specialize the getType() method to always return a FixedVectorType, which reduces the amount of casti...
This is an important base class in LLVM.
FunctionPass class - This class is used to implement most global optimizations.
static InsertElementInst * Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This is an important class for using LLVM in a threaded context.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
StringRef - Represent a constant reference to a string, i.e.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
FunctionPass * createSPIRVRegularizerPass()
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.