LLVM: lib/Target/DirectX/DXILDataScalarization.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

26

27#define DEBUG_TYPE "dxil-data-scalarization"

29

30using namespace llvm;

31

33

34public:

37

38 static char ID;

39};

40

42

44public:

47

48

68

69private:

70 typedef std::pair<AllocaInst *, SmallVector<Value *, 4>> AllocaAndGEPs;

72 VectorToArrayMap;

73

74 VectorToArrayMap VectorAllocaMap;

75 AllocaAndGEPs createArrayFromVector(IRBuilder<> &Builder, Value *Vec,

76 const Twine &Name);

79

82};

83

85 bool MadeChange = false;

90 }

91 VectorAllocaMap.clear();

92 return MadeChange;

93}

94

96DataScalarizerVisitor::lookupReplacementGlobal(Value *CurrOperand) {

98 auto It = GlobalMap.find(OldGlobal);

99 if (It != GlobalMap.end()) {

100 return It->second;

101 }

102 }

103 return nullptr;

104}

105

106

109 return true;

112 return false;

113}

114

115

121 Type *NewElementType =

123 return ArrayType::get(NewElementType, ArrayTy->getNumElements());

124 }

125

126 return T;

127}

128

132 return false;

133

137 Builder.CreateAlloca(NewType, nullptr, AI.getName() + ".scalarized");

141 return true;

142}

143

147 if (CE && CE->getOpcode() == Instruction::GetElementPtr) {

156 return true;

157 }

158 if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand))

160 return false;

161}

162

164

165 Value *PtrOperand = SI.getPointerOperand();

167 if (CE && CE->getOpcode() == Instruction::GetElementPtr) {

171 StoreInst *NewStore = Builder.CreateStore(SI.getValueOperand(), OldGEP);

173 SI.replaceAllUsesWith(NewStore);

174 SI.eraseFromParent();

176 return true;

177 }

178 if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand))

179 SI.setOperand(SI.getPointerOperandIndex(), NewGlobal);

180

181 return false;

182}

183

184DataScalarizerVisitor::AllocaAndGEPs

185DataScalarizerVisitor::createArrayFromVector(IRBuilder<> &Builder, Value *Vec,

186 const Twine &Name = "") {

187

188 if (VectorAllocaMap.contains(Vec))

189 return VectorAllocaMap[Vec];

190

191 auto InsertPoint = Builder.GetInsertPoint();

192

193

194 Builder.SetInsertPointPastAllocas(Builder.GetInsertBlock()->getParent());

197 Builder.CreateAlloca(ArrTy, nullptr, Name + ".alloca");

199

200

201

202

204 Builder.SetInsertPoint(Instr->getNextNode());

206 for (unsigned I = 0; I < ArrNumElems; ++I) {

207 Value *EE = Builder.CreateExtractElement(Vec, I, Name + ".extract");

208 GEPs[I] = Builder.CreateInBoundsGEP(

209 ArrTy, ArrAlloca, {Builder.getInt32(0), Builder.getInt32(I)},

210 Name + ".index");

212 }

213

214 VectorAllocaMap.insert({Vec, {ArrAlloca, GEPs}});

216 return {ArrAlloca, GEPs};

217}

218

219

220

221static std::pair<Value *, Value *>

223 const Twine &Name = "") {

225 Value *GEP = Builder.CreateInBoundsGEP(

226 ArrTy, ArrAlloca, {Builder.getInt32(0), Index}, Name + ".index");

229 return std::make_pair(GEP, Load);

230}

231

232bool DataScalarizerVisitor::replaceDynamicInsertElementInst(

235

239

240 AllocaAndGEPs ArrAllocaAndGEPs =

241 createArrayFromVector(Builder, Vec, IEI.getName());

242 AllocaInst *ArrAlloca = ArrAllocaAndGEPs.first;

245

246 auto GEPAndLoad =

248 Value *GEP = GEPAndLoad.first;

250

255 IEI.getName() + ".load");

257 IEI.getName() + ".insert");

258 }

259

260

261

263

266 return true;

267}

268

270

273 return false;

274 return replaceDynamicInsertElementInst(IEI);

275}

276

277bool DataScalarizerVisitor::replaceDynamicExtractElementInst(

280

281 AllocaAndGEPs ArrAllocaAndGEPs =

283 AllocaInst *ArrAlloca = ArrAllocaAndGEPs.first;

284

287 Value *Load = GEPAndLoad.second;

288

291 return true;

292}

293

295

298 return false;

299 return replaceDynamicExtractElementInst(EEI);

300}

301

306

307

308

310 PtrOpGEPCE && PtrOpGEPCE->getOpcode() == Instruction::GetElementPtr) {

314

321 "Expected newly-created GEP to be an instruction");

323

328 return true;

329 }

330

332 Value *NewPtrOperand = PtrOperand;

333 if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand))

334 NewPtrOperand = NewGlobal;

335

336 bool NeedsTransform = NewPtrOperand != PtrOperand || NewGEPType != GEPType;

337 if (!NeedsTransform)

338 return false;

339

342 Value *NewGEP = Builder.CreateGEP(NewGEPType, NewPtrOperand, Indices,

344

346

348 OldGEPI->eraseFromParent();

349

350 return true;

351}

352

355

358 }

359

360

363 }

364

365

367

370 for (unsigned I = 0; I < ConstVecInit->getNumOperands(); ++I)

371 ArrayElements.push_back(ConstVecInit->getOperand(I));

374 for (unsigned I = 0; I < ConstDataVecInit->getNumElements(); ++I)

375 ArrayElements.push_back(ConstDataVecInit->getElementAsConstant(I));

376 } else {

377 assert(false && "Expected a ConstantVector or ConstantDataVector for "

378 "vector initializer!");

379 }

380

382 }

383

384

387 assert(ArrayInit && "Expected a ConstantArray for array initializer!");

388

390 for (unsigned I = 0; I < ArrayTy->getNumElements(); ++I) {

391

393 ArrayInit->getOperand(I), ArrayTy->getElementType(),

395 NewArrayElements.push_back(NewElemInit);

396 }

397

399 }

400

401

403}

404

406 bool MadeChange = false;

411 Type *OrigType = G.getValueType();

412

414 if (OrigType != NewType) {

415

416

418 M, NewType, G.isConstant(), G.getLinkage(),

419 nullptr, G.getName() + ".scalarized", &G,

420 G.getThreadLocalMode(), G.getAddressSpace(),

421 G.isExternallyInitialized());

422

423

425 if (G.getAlignment() > 0) {

427 }

428

429 if (G.hasInitializer()) {

433 }

434

435

436

437 Impl.GlobalMap[&G] = NewGlobal;

438 }

439 }

440

442 if (F.isDeclaration())

443 continue;

444 MadeChange |= Impl.visit(F);

445 }

446

447

448 for (auto &[Old, New] : Impl.GlobalMap) {

449 Old->eraseFromParent();

450 MadeChange = true;

451 }

452 return MadeChange;

453}

454

458 if (!MadeChanges)

461 return PA;

462}

463

467

469

471 "DXIL Data Scalarization", false, false)

474

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static bool findAndReplaceVectors(Module &M)

Definition DXILDataScalarization.cpp:405

static bool isVectorOrArrayOfVectors(Type *T)

Definition DXILDataScalarization.cpp:107

static Type * equivalentArrayTypeFromVector(Type *T)

Definition DXILDataScalarization.cpp:116

static std::pair< Value *, Value * > dynamicallyLoadArray(IRBuilder<> &Builder, AllocaInst *ArrAlloca, Value *Index, const Twine &Name="")

Returns a pair of Value* with the first being a GEP into ArrAlloca using indices {0,...

Definition DXILDataScalarization.cpp:222

static const int MaxVecSize

Definition DXILDataScalarization.cpp:28

static Constant * transformInitializer(Constant *Init, Type *OrigType, Type *NewType, LLVMContext &Ctx)

Definition DXILDataScalarization.cpp:353

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.

static char ID

Definition DXILDataScalarization.cpp:38

bool runOnModule(Module &M) override

runOnModule - Virtual method overriden by subclasses to process the module being operated on.

Definition DXILDataScalarization.cpp:464

DXILDataScalarizationLegacy()

Definition DXILDataScalarization.cpp:36

bool visitCallInst(CallInst &ICI)

Definition DXILDataScalarization.cpp:65

bool visitInstruction(Instruction &I)

Definition DXILDataScalarization.cpp:50

bool visitBinaryOperator(BinaryOperator &BO)

Definition DXILDataScalarization.cpp:55

bool visitInsertElementInst(InsertElementInst &IEI)

Definition DXILDataScalarization.cpp:269

bool visitGetElementPtrInst(GetElementPtrInst &GEPI)

Definition DXILDataScalarization.cpp:302

DataScalarizerVisitor()

Definition DXILDataScalarization.cpp:45

bool visitStoreInst(StoreInst &SI)

Definition DXILDataScalarization.cpp:163

bool visitFreezeInst(FreezeInst &FI)

Definition DXILDataScalarization.cpp:66

bool visitBitCastInst(BitCastInst &BCI)

Definition DXILDataScalarization.cpp:58

bool visitCastInst(CastInst &CI)

Definition DXILDataScalarization.cpp:57

bool visitFCmpInst(FCmpInst &FCI)

Definition DXILDataScalarization.cpp:53

bool visitLoadInst(LoadInst &LI)

Definition DXILDataScalarization.cpp:144

bool visitSelectInst(SelectInst &SI)

Definition DXILDataScalarization.cpp:51

bool visit(Function &F)

Definition DXILDataScalarization.cpp:84

bool visitUnaryOperator(UnaryOperator &UO)

Definition DXILDataScalarization.cpp:54

bool visitICmpInst(ICmpInst &ICI)

Definition DXILDataScalarization.cpp:52

bool visitShuffleVectorInst(ShuffleVectorInst &SVI)

Definition DXILDataScalarization.cpp:61

bool visitAllocaInst(AllocaInst &AI)

Definition DXILDataScalarization.cpp:129

bool visitPHINode(PHINode &PHI)

Definition DXILDataScalarization.cpp:62

bool visitExtractElementInst(ExtractElementInst &EEI)

Definition DXILDataScalarization.cpp:294

friend bool findAndReplaceVectors(llvm::Module &M)

Definition DXILDataScalarization.cpp:405

an instruction to allocate memory on the stack

Align getAlign() const

Return the alignment of the memory that is being allocated by the instruction.

Type * getAllocatedType() const

Return the type that is being allocated by the instruction.

void setAlignment(Align Align)

static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)

This static method is the primary way to construct an ArrayType.

LLVM Basic Block Representation.

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 LLVM_ABI ConstantAggregateZero * get(Type *Ty)

static LLVM_ABI 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 &)

Definition DXILDataScalarization.cpp:455

bool contains(const_arg_type_t< KeyT > Val) const

Return true if the specified key is in the map, false otherwise.

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 ...

LLVM_ABI Type * getSourceElementType() const

Value * getPointerOperand()

GEPNoWrapFlags getNoWrapFlags() const

an instruction for type-safe pointer arithmetic to access elements of arrays and structs

iterator_range< op_iterator > indices()

Type * getSourceElementType() const

LLVM_ABI GEPNoWrapFlags getNoWrapFlags() const

Get the nowrap flags for the GEP instruction.

void setUnnamedAddr(UnnamedAddr Val)

LLVM_ABI void setInitializer(Constant *InitVal)

setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...

void setAlignment(Align Align)

Sets the alignment attribute of the GlobalVariable.

This instruction compares its operands according to the predicate given to the constructor.

Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")

ConstantInt * getInt32(uint32_t C)

Get a constant 32-bit value.

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)

void SetInsertPoint(BasicBlock *TheBB)

This specifies that created instructions should be appended to the end of the specified block.

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)

LLVM_ABI void insertBefore(InstListType::iterator InsertPos)

Insert an unlinked instruction into a basic block immediately before the specified position.

LLVM_ABI 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)

Value * getPointerOperand()

static unsigned getPointerOperandIndex()

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.

static LLVM_ABI PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

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)

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

The instances of the Type class are immutable: once they are created, they are never changed.

Type * getArrayElementType() const

LLVM_ABI uint64_t getArrayNumElements() const

static LLVM_ABI 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

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

LLVM_ABI void replaceAllUsesWith(Value *V)

Change all uses of this to point to a new Value.

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

self_iterator getIterator()

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

ModulePass * createDXILDataScalarizationLegacyPass()

Pass to scalarize llvm global data into a DXIL legal form.

Definition DXILDataScalarization.cpp:475

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...

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.