23#define DEBUG_TYPE "spirv-regularizer"
49char SPIRVRegularizer::ID = 0;
62void SPIRVRegularizer::runLowerConstExpr(
Function &
F) {
64 std::list<Instruction *> WorkList;
66 WorkList.push_back(&
II);
68 auto FBegin =
F.begin();
69 while (!WorkList.empty()) {
75 auto *CE = cast<ConstantExpr>(V);
77 auto ReplInst = CE->getAsInstruction();
78 auto InsPoint =
II->getParent() == &*FBegin ?
II : &FBegin->back();
79 ReplInst->insertBefore(InsPoint->getIterator());
81 std::vector<Instruction *>
Users;
83 for (
auto U : CE->users()) {
84 LLVM_DEBUG(
dbgs() <<
"[lowerConstantExpressions] Use: " << *U <<
'\n');
85 auto InstUser = dyn_cast<Instruction>(U);
87 if (InstUser && InstUser->getParent()->getParent() == &
F)
88 Users.push_back(InstUser);
91 if (ReplInst->getParent() ==
User->getParent() &&
92 User->comesBefore(ReplInst))
93 ReplInst->moveBefore(
User->getIterator());
100 auto LowerConstantVec = [&
II, &LowerOp, &WorkList,
102 unsigned NumOfOp) ->
Value * {
103 if (std::all_of(Vec->op_begin(), Vec->op_end(), [](
Value *V) {
104 return isa<ConstantExpr>(V) || isa<Function>(V);
108 std::list<Value *> OpList;
109 std::transform(Vec->op_begin(), Vec->op_end(),
110 std::back_inserter(OpList),
111 [LowerOp](
Value *V) { return LowerOp(V); });
112 Value *Repl =
nullptr;
114 auto *PhiII = dyn_cast<PHINode>(
II);
116 PhiII ? &PhiII->getIncomingBlock(NumOfOp)->back() :
II;
117 std::list<Instruction *> ReplList;
118 for (
auto V : OpList) {
119 if (
auto *Inst = dyn_cast<Instruction>(V))
120 ReplList.push_back(Inst);
126 WorkList.splice(WorkList.begin(), ReplList);
131 for (
unsigned OI = 0, OE =
II->getNumOperands(); OI != OE; ++OI) {
132 auto *
Op =
II->getOperand(OI);
133 if (
auto *Vec = dyn_cast<ConstantVector>(
Op)) {
134 Value *ReplInst = LowerConstantVec(Vec, OI);
136 II->replaceUsesOfWith(
Op, ReplInst);
137 }
else if (
auto CE = dyn_cast<ConstantExpr>(
Op)) {
138 WorkList.push_front(cast<Instruction>(LowerOp(CE)));
139 }
else if (
auto MDAsVal = dyn_cast<MetadataAsValue>(
Op)) {
140 auto ConstMD = dyn_cast<ConstantAsMetadata>(MDAsVal->getMetadata());
144 Value *ReplInst =
nullptr;
145 if (
auto *Vec = dyn_cast<ConstantVector>(
C))
146 ReplInst = LowerConstantVec(Vec, OI);
147 if (
auto *CE = dyn_cast<ConstantExpr>(
C))
148 ReplInst = LowerOp(CE);
153 II->setOperand(OI, RepMDVal);
154 WorkList.push_front(cast<Instruction>(ReplInst));
162void SPIRVRegularizer::visitCallInst(
CallInst &CI) {
167 auto MangledName =
F->getName();
174 if (DemangledName.starts_with(
"fmin") || DemangledName.starts_with(
"fmax") ||
175 DemangledName.starts_with(
"min") || DemangledName.starts_with(
"max"))
176 visitCallScalToVec(&CI, MangledName, DemangledName);
185 auto IsArg0Vector = isa<VectorType>(Arg0Ty);
186 for (
unsigned I = 1, E = CI->
arg_size(); Uniform && (
I != E); ++
I)
193 auto [It,
Inserted] = Old2NewFuncs.try_emplace(OldF);
198 FunctionType::get(OldF->getReturnType(), ArgTypes, OldF->isVarArg());
203 for (
auto &Arg : OldF->args()) {
205 NewFArgIt->setName(ArgName);
206 VMap[&Arg] = &(*NewFArgIt++);
210 CloneFunctionChangeType::LocalChangesOnly, Returns);
234 ElementCount VecElemCount = cast<VectorType>(Arg0Ty)->getElementCount();
243bool SPIRVRegularizer::runOnFunction(
Function &
F) {
244 runLowerConstExpr(
F);
246 for (
auto &OldNew : Old2NewFuncs) {
256 return new SPIRVRegularizer();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This header defines various interfaces for pass management in LLVM.
iv Induction Variable Users
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> op)
Represent the analysis usage information of a pass.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
void mutateFunctionType(FunctionType *FTy)
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
Constant Vector Declarations.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
FunctionType * getFunctionType() const
Returns the FunctionType for me.
AttributeList getAttributes() const
Return the attribute list for this Function.
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
static InsertElementInst * Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Base class for instruction visitors.
RetTy visitCallInst(CallInst &I)
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
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...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
In order to facilitate speculative execution, many instructions do not invoke immediate undefined beh...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This instruction constructs a fixed permutation of two input vectors.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
self_iterator getIterator()
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
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.
DEMANGLE_ABI char * itaniumDemangle(std::string_view mangled_name, bool ParseParams=true)
Returns a non-NULL pointer to a NUL-terminated C style string that should be explicitly freed,...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createSPIRVRegularizerPass()
LLVM_ABI 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.