24#define DEBUG_TYPE "spirv-regularizer"
56char SPIRVRegularizer::ID = 0;
69void SPIRVRegularizer::runLowerConstExpr(
Function &
F) {
71 std::list<Instruction *> WorkList;
73 WorkList.push_back(&
II);
75 auto FBegin =
F.begin();
76 while (!WorkList.empty()) {
82 auto *CE = cast<ConstantExpr>(V);
84 auto ReplInst = CE->getAsInstruction();
85 auto InsPoint =
II->getParent() == &*FBegin ?
II : &FBegin->back();
86 ReplInst->insertBefore(InsPoint);
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 * {
110 if (std::all_of(Vec->op_begin(), Vec->op_end(), [](
Value *V) {
111 return isa<ConstantExpr>(V) || isa<Function>(V);
115 std::list<Value *> OpList;
116 std::transform(Vec->op_begin(), Vec->op_end(),
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);
133 WorkList.splice(WorkList.begin(), ReplList);
138 for (
unsigned OI = 0, OE =
II->getNumOperands(); OI != OE; ++OI) {
139 auto *
Op =
II->getOperand(OI);
140 if (
auto *Vec = dyn_cast<ConstantVector>(
Op)) {
141 Value *ReplInst = LowerConstantVec(Vec, OI);
143 II->replaceUsesOfWith(
Op, ReplInst);
144 }
else if (
auto CE = dyn_cast<ConstantExpr>(
Op)) {
145 WorkList.push_front(cast<Instruction>(LowerOp(CE)));
146 }
else if (
auto MDAsVal = dyn_cast<MetadataAsValue>(
Op)) {
147 auto ConstMD = dyn_cast<ConstantAsMetadata>(MDAsVal->getMetadata());
151 Value *ReplInst =
nullptr;
152 if (
auto *Vec = dyn_cast<ConstantVector>(
C))
153 ReplInst = LowerConstantVec(Vec, OI);
154 if (
auto *CE = dyn_cast<ConstantExpr>(
C))
155 ReplInst = LowerOp(CE);
160 II->setOperand(OI, RepMDVal);
161 WorkList.push_front(cast<Instruction>(ReplInst));
169void SPIRVRegularizer::visitCallInst(
CallInst &CI) {
174 auto MangledName =
F->getName();
181 if (DemangledName.starts_with(
"fmin") || DemangledName.starts_with(
"fmax") ||
182 DemangledName.starts_with(
"min") || DemangledName.starts_with(
"max"))
183 visitCallScalToVec(&CI, MangledName, DemangledName);
192 auto IsArg0Vector = isa<VectorType>(Arg0Ty);
193 for (
unsigned I = 1, E = CI->
arg_size(); Uniform && (
I != E); ++
I)
200 if (!Old2NewFuncs.count(OldF)) {
204 FunctionType::get(OldF->getReturnType(), ArgTypes, OldF->isVarArg());
209 for (
auto &Arg : OldF->args()) {
211 NewFArgIt->setName(ArgName);
212 VMap[&Arg] = &(*NewFArgIt++);
216 CloneFunctionChangeType::LocalChangesOnly, Returns);
218 Old2NewFuncs[OldF] = NewF;
220 NewF = Old2NewFuncs[OldF];
240 ElementCount VecElemCount = cast<VectorType>(Arg0Ty)->getElementCount();
249bool SPIRVRegularizer::runOnFunction(
Function &
F) {
250 runLowerConstExpr(
F);
252 for (
auto &OldNew : Old2NewFuncs) {
262 return new SPIRVRegularizer();
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 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 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.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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 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 IntegerType * getInt32Ty(LLVMContext &C)
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.
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
self_iterator getIterator()
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
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,...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void initializeSPIRVRegularizerPass(PassRegistry &)
FunctionPass * createSPIRVRegularizerPass()
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.