Go to the documentation of this file.
24 #define DEBUG_TYPE "spirv-regularizer"
42 StringRef getPassName()
const override {
return "SPIR-V Regularizer"; }
69 void SPIRVRegularizer::runLowerConstExpr(
Function &
F) {
71 std::list<Instruction *> WorkList;
73 WorkList.push_back(&II);
75 auto FBegin =
F.begin();
76 while (!WorkList.empty()) {
79 auto LowerOp = [&II, &FBegin, &
F](
Value *V) ->
Value * {
82 auto *CE = cast<ConstantExpr>(V);
84 auto ReplInst = CE->getAsInstruction();
85 auto InsPoint = II->
getParent() == &*FBegin ? II : &FBegin->back();
88 std::vector<Instruction *>
Users;
90 for (
auto U : CE->users()) {
91 LLVM_DEBUG(
dbgs() <<
"[lowerConstantExpressions] Use: " << *U <<
'\n');
92 auto InstUser = dyn_cast<Instruction>(U);
94 if (InstUser && InstUser->getParent()->getParent() == &
F)
95 Users.push_back(InstUser);
98 if (ReplInst->getParent() ==
User->getParent() &&
99 User->comesBefore(ReplInst))
100 ReplInst->moveBefore(
User);
106 WorkList.pop_front();
107 auto LowerConstantVec = [&II, &LowerOp, &WorkList,
109 unsigned NumOfOp) ->
Value * {
111 return isa<ConstantExpr>(V) || isa<Function>(V);
115 std::list<Value *> OpList;
117 std::back_inserter(OpList),
118 [LowerOp](
Value *V) { return LowerOp(V); });
119 Value *Repl =
nullptr;
121 auto *PhiII = dyn_cast<PHINode>(II);
123 PhiII ? &PhiII->getIncomingBlock(NumOfOp)->back() : II;
124 std::list<Instruction *> ReplList;
125 for (
auto V : OpList) {
126 if (
auto *Inst = dyn_cast<Instruction>(V))
127 ReplList.push_back(Inst);
132 WorkList.splice(WorkList.begin(), ReplList);
137 for (
unsigned OI = 0, OE = II->
getNumOperands(); OI != OE; ++OI) {
139 if (
auto *Vec = dyn_cast<ConstantVector>(
Op)) {
140 Value *ReplInst = LowerConstantVec(Vec, OI);
143 }
else if (
auto CE = dyn_cast<ConstantExpr>(
Op)) {
144 WorkList.push_front(cast<Instruction>(LowerOp(CE)));
145 }
else if (
auto MDAsVal = dyn_cast<MetadataAsValue>(
Op)) {
146 auto ConstMD = dyn_cast<ConstantAsMetadata>(MDAsVal->getMetadata());
150 Value *ReplInst =
nullptr;
151 if (
auto *Vec = dyn_cast<ConstantVector>(
C))
152 ReplInst = LowerConstantVec(Vec, OI);
153 if (
auto *CE = dyn_cast<ConstantExpr>(
C))
154 ReplInst = LowerOp(CE);
160 WorkList.push_front(cast<Instruction>(ReplInst));
168 void SPIRVRegularizer::visitCallInst(
CallInst &CI) {
173 auto MangledName =
F->getName();
180 if (DemangledName.startswith(
"fmin") || DemangledName.startswith(
"fmax") ||
181 DemangledName.startswith(
"min") || DemangledName.startswith(
"max"))
182 visitCallScalToVec(&CI, MangledName, DemangledName);
191 auto IsArg0Vector = isa<VectorType>(Arg0Ty);
192 for (
unsigned I = 1,
E = CI->
arg_size(); Uniform && (
I !=
E); ++
I)
199 if (!Old2NewFuncs.count(OldF)) {
208 for (
auto &
Arg : OldF->args()) {
209 auto ArgName =
Arg.getName();
210 NewFArgIt->setName(ArgName);
211 VMap[&
Arg] = &(*NewFArgIt++);
217 Old2NewFuncs[OldF] = NewF;
219 NewF = Old2NewFuncs[OldF];
239 ElementCount VecElemCount = cast<VectorType>(Arg0Ty)->getElementCount();
248 runLowerConstExpr(
F);
250 for (
auto &OldNew : Old2NewFuncs) {
260 return new SPIRVRegularizer();
This is an optimization pass for GlobalISel generic memory operations.
void mutateFunctionType(FunctionType *FTy)
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
static InsertElementInst * Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt32Ty(LLVMContext &C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
(vector float) vec_cmpeq(*A, *B) C
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Represent the analysis usage information of a pass.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
FunctionPass * createSPIRVRegularizerPass()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
AttributeList getAttributes() const
Return the attribute list for this Function.
inst_range instructions(Function *F)
This is an important base class in LLVM.
This is an important class for using LLVM in a threaded context.
void initializeSPIRVRegularizerPass(PassRegistry &)
Constant Vector Declarations.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void setOperand(unsigned i, Value *Val)
StringRef - Represent a constant reference to a string, i.e.
INITIALIZE_PASS(SPIRVRegularizer, DEBUG_TYPE, "SPIR-V Regularizer", false, false) void SPIRVRegularizer
Type * getType() const
All values are typed, get the type of this value.
LLVMContext & getContext() const
All values hold a context through their type.
Base class for instruction visitors.
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
static bool runOnFunction(Function &F, bool PostInlining)
unsigned arg_size() const
FunctionType * getFunctionType() const
Returns the FunctionType for me.
instcombine should handle this transform
This instruction constructs a fixed permutation of two input vectors.
unsigned getNumOperands() const
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
const BasicBlock * getParent() const
iv Induction Variable Users
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
char * itaniumDemangle(const char *mangled_name, char *buf, size_t *n, int *status)
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
FunctionPass class - This class is used to implement most global optimizations.
This class represents a function call, abstracting a target machine's calling convention.
void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, ValueToValueMapTy &VMap, CloneFunctionChangeType Changes, SmallVectorImpl< ReturnInst * > &Returns, const char *NameSuffix="", ClonedCodeInfo *CodeInfo=nullptr, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Clone OldFunc into NewFunc, transforming the old arguments into references to VMap values.
void takeName(Value *V)
Transfer the name from V to this value.
Value * getOperand(unsigned i) const
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
LLVM Value Representation.
In order to facilitate speculative execution, many instructions do not invoke immediate undefined beh...
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.