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()) {
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 * {
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);
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));
168void 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)) {
203 FunctionType::get(OldF->getReturnType(), ArgTypes, OldF->isVarArg());
208 for (
auto &Arg : OldF->args()) {
210 NewFArgIt->setName(ArgName);
211 VMap[&Arg] = &(*NewFArgIt++);
215 CloneFunctionChangeType::LocalChangesOnly, Returns);
217 Old2NewFuncs[OldF] = NewF;
219 NewF = Old2NewFuncs[OldF];
239 ElementCount VecElemCount = cast<VectorType>(Arg0Ty)->getElementCount();
247bool SPIRVRegularizer::runOnFunction(
Function &
F) {
248 runLowerConstExpr(
F);
250 for (
auto &OldNew : Old2NewFuncs) {
260 return new SPIRVRegularizer();
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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
iv Induction Variable Users
Select target instructions out of generic instructions
This header defines various interfaces for pass management in LLVM.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
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.
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="", Instruction *InsertBefore=nullptr)
Base class for instruction visitors.
RetTy visitCallInst(CallInst &I)
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
const BasicBlock * getParent() const
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
unsigned getNumOperands() 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.
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.
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.
char * itaniumDemangle(std::string_view mangled_name)
Returns a non-NULL pointer to a NUL-terminated C style string that should be explicitly freed,...