24#define DEBUG_TYPE "dxil-data-scalarization"
76DataScalarizerVisitor::lookupReplacementGlobal(
Value *CurrOperand) {
77 if (
GlobalVariable *OldGlobal = dyn_cast<GlobalVariable>(CurrOperand)) {
78 auto It = GlobalMap.
find(OldGlobal);
79 if (It != GlobalMap.
end()) {
88 for (
unsigned I = 0;
I < NumOperands; ++
I) {
91 if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
93 cast<GetElementPtrInst>(CE->getAsInstruction());
104 if (
GlobalVariable *NewGlobal = lookupReplacementGlobal(CurrOpperand))
111 unsigned NumOperands = SI.getNumOperands();
112 for (
unsigned I = 0;
I < NumOperands; ++
I) {
113 Value *CurrOpperand = SI.getOperand(
I);
114 ConstantExpr *CE = dyn_cast<ConstantExpr>(CurrOpperand);
115 if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
117 cast<GetElementPtrInst>(CE->getAsInstruction());
122 SI.replaceAllUsesWith(NewStore);
123 SI.eraseFromParent();
127 if (
GlobalVariable *NewGlobal = lookupReplacementGlobal(CurrOpperand))
128 SI.setOperand(
I, NewGlobal);
137 for (
unsigned I = 0;
I < NumOperands; ++
I) {
139 NewGlobal = lookupReplacementGlobal(CurrOpperand);
148 for (
auto &Index : GEPI.
indices())
161 if (
auto *VecTy = dyn_cast<VectorType>(
T))
162 return ArrayType::get(VecTy->getElementType(),
163 dyn_cast<FixedVectorType>(VecTy)->getNumElements());
164 if (
auto *ArrayTy = dyn_cast<ArrayType>(
T)) {
165 Type *NewElementType =
167 return ArrayType::get(NewElementType, ArrayTy->getNumElements());
176 if (isa<ConstantAggregateZero>(
Init)) {
181 if (isa<UndefValue>(
Init)) {
186 if (isa<VectorType>(OrigType) && isa<ArrayType>(NewType)) {
190 for (
unsigned I = 0;
I < ConstVecInit->getNumOperands(); ++
I)
191 ArrayElements.
push_back(ConstVecInit->getOperand(
I));
193 llvm::dyn_cast<llvm::ConstantDataVector>(
Init)) {
194 for (
unsigned I = 0;
I < ConstDataVecInit->getNumElements(); ++
I)
195 ArrayElements.
push_back(ConstDataVecInit->getElementAsConstant(
I));
197 assert(
false &&
"Expected a ConstantVector or ConstantDataVector for "
198 "vector initializer!");
205 if (
auto *ArrayTy = dyn_cast<ArrayType>(OrigType)) {
206 auto *ArrayInit = dyn_cast<ConstantArray>(
Init);
207 assert(ArrayInit &&
"Expected a ConstantArray for array initializer!");
210 for (
unsigned I = 0;
I < ArrayTy->getNumElements(); ++
I) {
213 ArrayInit->getOperand(
I), ArrayTy->getElementType(),
214 cast<ArrayType>(NewType)->getElementType(), Ctx);
226 bool MadeChange =
false;
231 Type *OrigType =
G.getValueType();
234 if (OrigType != NewType) {
238 M, NewType,
G.isConstant(),
G.getLinkage(),
239 nullptr,
G.getName() +
".scalarized", &
G,
240 G.getThreadLocalMode(),
G.getAddressSpace(),
241 G.isExternallyInitialized());
245 if (
G.getAlignment() > 0) {
249 if (
G.hasInitializer()) {
257 Impl.GlobalMap[&
G] = NewGlobal;
259 if (isa<ConstantExpr>(U) && isa<Operator>(U)) {
262 if (
Instruction *Inst = dyn_cast<Instruction>(UCE))
273 for (
auto &[Old, New] : Impl.GlobalMap) {
274 Old->eraseFromParent();
296 "DXIL Data Scalarization",
false,
false)
static bool findAndReplaceVectors(Module &M)
static const int MaxVecSize
Constant * transformInitializer(Constant *Init, Type *OrigType, Type *NewType, LLVMContext &Ctx)
static Type * replaceVectorWithArray(Type *T, LLVMContext &Ctx)
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
DXILDataScalarizationLegacy()
bool visitCallInst(CallInst &ICI)
bool visitInstruction(Instruction &I)
bool visitBinaryOperator(BinaryOperator &BO)
bool visitInsertElementInst(InsertElementInst &IEI)
bool visitGetElementPtrInst(GetElementPtrInst &GEPI)
bool visitStoreInst(StoreInst &SI)
bool visitFreezeInst(FreezeInst &FI)
bool visitBitCastInst(BitCastInst &BCI)
bool visitCastInst(CastInst &CI)
bool visitFCmpInst(FCmpInst &FCI)
bool visitLoadInst(LoadInst &LI)
bool visitSelectInst(SelectInst &SI)
bool visitUnaryOperator(UnaryOperator &UO)
bool visitICmpInst(ICmpInst &ICI)
bool visitShuffleVectorInst(ShuffleVectorInst &SVI)
bool visit(Instruction &I)
bool visitPHINode(PHINode &PHI)
bool visitExtractElementInst(ExtractElementInst &EEI)
friend bool findAndReplaceVectors(llvm::Module &M)
A container for analyses that lazily runs them and caches their results.
This class represents a no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
static ConstantAggregateZero * get(Type *Ty)
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
A vector constant whose element type is a simple 1/2/4/8-byte integer or float/double,...
A constant value that is initialized with an expression using other constant values.
Constant Vector Declarations.
This is an important base class in LLVM.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
iterator find(const_arg_type_t< KeyT > Val)
This instruction compares its operands according to the predicate given to the constructor.
This class represents a freeze function that returns random concrete value if an operand is either a ...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
iterator_range< op_iterator > indices()
GEPNoWrapFlags getNoWrapFlags() const
Get the nowrap flags for the GEP instruction.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalObject.
void setUnnamedAddr(UnnamedAddr Val)
Type * getValueType() const
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
This instruction compares its operands according to the predicate given to the constructor.
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This instruction inserts a single (scalar) element into a VectorType value.
Base class for instruction visitors.
void visit(Iterator Start, Iterator End)
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
void setAlignment(Align Align)
Align getAlign() const
Return the alignment of the access that is being performed.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This class represents the LLVM 'select' instruction.
This instruction constructs a fixed permutation of two input vectors.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
void setAlignment(Align Align)
The instances of the Type class are immutable: once they are created, they are never changed.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
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.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
StringRef getName() const
Return a constant reference to the value's name.
This is an optimization pass for GlobalISel generic memory operations.
ModulePass * createDXILDataScalarizationLegacyPass()
Pass to scalarize llvm global data into a DXIL legal form.
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...