1 //===-- SITypeRewriter.cpp - Remove unwanted types ------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This pass removes performs the following type substitution on all
12 /// non-compute shaders:
15 /// - v16i8 is used for constant memory resource descriptors. This type is
16 /// legal for some compute APIs, and we don't want to declare it as legal
17 /// in the backend, because we want the legalizer to expand all v16i8
20 /// - Having v1* types complicates the legalizer and we can easily replace
21 /// - them with the element type.
22 //===----------------------------------------------------------------------===//
25 #include "llvm/IR/IRBuilder.h"
26 #include "llvm/IR/InstVisitor.h"
32 class SITypeRewriter : public FunctionPass,
33 public InstVisitor<SITypeRewriter> {
41 SITypeRewriter() : FunctionPass(ID) { }
42 bool doInitialization(Module &M) override;
43 bool runOnFunction(Function &F) override;
44 const char *getPassName() const override {
45 return "SI Type Rewriter";
47 void visitLoadInst(LoadInst &I);
48 void visitCallInst(CallInst &I);
49 void visitBitCast(BitCastInst &I);
52 } // End anonymous namespace
54 char SITypeRewriter::ID = 0;
56 bool SITypeRewriter::doInitialization(Module &M) {
58 v16i8 = VectorType::get(Type::getInt8Ty(M.getContext()), 16);
59 v4i32 = VectorType::get(Type::getInt32Ty(M.getContext()), 4);
63 bool SITypeRewriter::runOnFunction(Function &F) {
64 AttributeSet Set = F.getAttributes();
65 Attribute A = Set.getAttribute(AttributeSet::FunctionIndex, "ShaderType");
67 unsigned ShaderType = ShaderType::COMPUTE;
68 if (A.isStringAttribute()) {
69 StringRef Str = A.getValueAsString();
70 Str.getAsInteger(0, ShaderType);
72 if (ShaderType == ShaderType::COMPUTE)
81 void SITypeRewriter::visitLoadInst(LoadInst &I) {
82 Value *Ptr = I.getPointerOperand();
83 Type *PtrTy = Ptr->getType();
84 Type *ElemTy = PtrTy->getPointerElementType();
85 IRBuilder<> Builder(&I);
86 if (ElemTy == v16i8) {
87 Value *BitCast = Builder.CreateBitCast(Ptr,
88 PointerType::get(v4i32,PtrTy->getPointerAddressSpace()));
89 LoadInst *Load = Builder.CreateLoad(BitCast);
90 // FIXME: Should the DebugLoc really get dropped here?
91 SmallVector<std::pair<unsigned, Value *>, 8> MD;
92 I.getAllMetadataOtherThanDebugLoc(MD);
93 for (unsigned i = 0, e = MD.size(); i != e; ++i) {
94 Load->setMetadata(MD[i].first, MD[i].second);
96 Value *BitCastLoad = Builder.CreateBitCast(Load, I.getType());
97 I.replaceAllUsesWith(BitCastLoad);
102 void SITypeRewriter::visitCallInst(CallInst &I) {
103 IRBuilder<> Builder(&I);
105 SmallVector <Value*, 8> Args;
106 SmallVector <Type*, 8> Types;
107 bool NeedToReplace = false;
108 Function *F = I.getCalledFunction();
109 std::string Name = F->getName().str();
110 for (unsigned i = 0, e = I.getNumArgOperands(); i != e; ++i) {
111 Value *Arg = I.getArgOperand(i);
112 if (Arg->getType() == v16i8) {
113 Args.push_back(Builder.CreateBitCast(Arg, v4i32));
114 Types.push_back(v4i32);
115 NeedToReplace = true;
116 Name = Name + ".v4i32";
117 } else if (Arg->getType()->isVectorTy() &&
118 Arg->getType()->getVectorNumElements() == 1 &&
119 Arg->getType()->getVectorElementType() ==
120 Type::getInt32Ty(I.getContext())){
121 Type *ElementTy = Arg->getType()->getVectorElementType();
122 std::string TypeName = "i32";
123 InsertElementInst *Def = cast<InsertElementInst>(Arg);
124 Args.push_back(Def->getOperand(1));
125 Types.push_back(ElementTy);
126 std::string VecTypeName = "v1" + TypeName;
127 Name = Name.replace(Name.find(VecTypeName), VecTypeName.length(), TypeName);
128 NeedToReplace = true;
131 Types.push_back(Arg->getType());
135 if (!NeedToReplace) {
138 Function *NewF = Mod->getFunction(Name);
140 NewF = Function::Create(FunctionType::get(F->getReturnType(), Types, false), GlobalValue::ExternalLinkage, Name, Mod);
141 NewF->setAttributes(F->getAttributes());
143 I.replaceAllUsesWith(Builder.CreateCall(NewF, Args));
147 void SITypeRewriter::visitBitCast(BitCastInst &I) {
148 IRBuilder<> Builder(&I);
149 if (I.getDestTy() != v4i32) {
153 if (BitCastInst *Op = dyn_cast<BitCastInst>(I.getOperand(0))) {
154 if (Op->getSrcTy() == v4i32) {
155 I.replaceAllUsesWith(Op->getOperand(0));
161 FunctionPass *llvm::createSITypeRewriter() {
162 return new SITypeRewriter();