LLVM: lib/Target/SPIRV/SPIRVRegularizer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

20

21#include

22

23#define DEBUG_TYPE "spirv-regularizer"

24

25using namespace llvm;

26

27namespace {

30

31public:

32 static char ID;

35 StringRef getPassName() const override { return "SPIR-V Regularizer"; }

36

37 void getAnalysisUsage(AnalysisUsage &AU) const override {

39 }

40 void visitCallInst(CallInst &CI);

41

42private:

45 void runLowerConstExpr(Function &F);

46};

47}

48

49char SPIRVRegularizer::ID = 0;

50

52 false)

53

54

55

56

57

58

59

60

61

62void SPIRVRegularizer::runLowerConstExpr(Function &F) {

64 std::list<Instruction *> WorkList;

66 WorkList.push_back(&II);

67

68 auto FBegin = F.begin();

69 while (!WorkList.empty()) {

70 Instruction *II = WorkList.front();

71

72 auto LowerOp = [&II, &FBegin, &F](Value *V) -> Value * {

73 if (isa(V))

74 return V;

75 auto *CE = cast(V);

76 LLVM_DEBUG(dbgs() << "[lowerConstantExpressions] " << *CE);

77 auto ReplInst = CE->getAsInstruction();

78 auto InsPoint = II->getParent() == &*FBegin ? II : &FBegin->back();

79 ReplInst->insertBefore(InsPoint->getIterator());

80 LLVM_DEBUG(dbgs() << " -> " << *ReplInst << '\n');

81 std::vector<Instruction *> Users;

82

83 for (auto U : CE->users()) {

84 LLVM_DEBUG(dbgs() << "[lowerConstantExpressions] Use: " << *U << '\n');

85 auto InstUser = dyn_cast(U);

86

87 if (InstUser && InstUser->getParent()->getParent() == &F)

88 Users.push_back(InstUser);

89 }

90 for (auto &User : Users) {

91 if (ReplInst->getParent() == User->getParent() &&

92 User->comesBefore(ReplInst))

93 ReplInst->moveBefore(User->getIterator());

94 User->replaceUsesOfWith(CE, ReplInst);

95 }

96 return ReplInst;

97 };

98

99 WorkList.pop_front();

100 auto LowerConstantVec = [&II, &LowerOp, &WorkList,

102 unsigned NumOfOp) -> Value * {

103 if (std::all_of(Vec->op_begin(), Vec->op_end(), [](Value *V) {

104 return isa(V) || isa(V);

105 })) {

106

107

108 std::list<Value *> OpList;

110 std::back_inserter(OpList),

111 [LowerOp](Value *V) { return LowerOp(V); });

112 Value *Repl = nullptr;

113 unsigned Idx = 0;

116 PhiII ? &PhiII->getIncomingBlock(NumOfOp)->back() : II;

117 std::list<Instruction *> ReplList;

118 for (auto V : OpList) {

120 ReplList.push_back(Inst);

125 }

126 WorkList.splice(WorkList.begin(), ReplList);

127 return Repl;

128 }

129 return nullptr;

130 };

131 for (unsigned OI = 0, OE = II->getNumOperands(); OI != OE; ++OI) {

132 auto *Op = II->getOperand(OI);

134 Value *ReplInst = LowerConstantVec(Vec, OI);

135 if (ReplInst)

136 II->replaceUsesOfWith(Op, ReplInst);

141 if (!ConstMD)

142 continue;

143 Constant *C = ConstMD->getValue();

144 Value *ReplInst = nullptr;

146 ReplInst = LowerConstantVec(Vec, OI);

148 ReplInst = LowerOp(CE);

149 if (!ReplInst)

150 continue;

153 II->setOperand(OI, RepMDVal);

155 }

156 }

157 }

158}

159

160

161

162void SPIRVRegularizer::visitCallInst(CallInst &CI) {

164 if (F)

165 return;

166

167 auto MangledName = F->getName();

169 if (!NameStr)

170 return;

171 StringRef DemangledName(NameStr);

172

173

174 if (DemangledName.starts_with("fmin") || DemangledName.starts_with("fmax") ||

175 DemangledName.starts_with("min") || DemangledName.starts_with("max"))

176 visitCallScalToVec(&CI, MangledName, DemangledName);

177 free(NameStr);

178}

179

180void SPIRVRegularizer::visitCallScalToVec(CallInst *CI, StringRef MangledName,

181 StringRef DemangledName) {

182

183 auto Uniform = true;

186 for (unsigned I = 1, E = CI->arg_size(); Uniform && (I != E); ++I)

188 if (Uniform)

189 return;

190

194 if (Inserted) {

197 auto *NewFTy =

198 FunctionType::get(OldF->getReturnType(), ArgTypes, OldF->isVarArg());

199 NewF = Function::Create(NewFTy, OldF->getLinkage(), OldF->getName(),

200 *OldF->getParent());

202 auto NewFArgIt = NewF->arg_begin();

203 for (auto &Arg : OldF->args()) {

204 auto ArgName = Arg.getName();

205 NewFArgIt->setName(ArgName);

206 VMap[&Arg] = &(*NewFArgIt++);

207 }

210 CloneFunctionChangeType::LocalChangesOnly, Returns);

212 It->second = NewF;

213 } else {

214 NewF = It->second;

215 }

217

218

219

220

221

222

223

224

225

226

227

228

229

234 ElementCount VecElemCount = cast(Arg0Ty)->getElementCount();

237 new ShuffleVectorInst(Inst, PVal, ConstVec, "", CI->getIterator());

241}

242

243bool SPIRVRegularizer::runOnFunction(Function &F) {

244 runLowerConstExpr(F);

246 for (auto &OldNew : Old2NewFuncs) {

247 Function *OldF = OldNew.first;

248 Function *NewF = OldNew.second;

251 }

252 return true;

253}

254

256 return new SPIRVRegularizer();

257}

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

Expand Atomic instructions

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static bool runOnFunction(Function &F, bool PostInlining)

This header defines various interfaces for pass management in LLVM.

uint64_t IntrinsicInst * II

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

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.

FixedVectorType * getType() const

Specialize the getType() method to always return a FixedVectorType, which reduces the amount of casti...

static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)

Return a ConstantVector with the specified constant in each element.

This is an important base class in LLVM.

std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)

FunctionPass class - This class is used to implement most global optimizations.

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.

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

virtual void getAnalysisUsage(AnalysisUsage &) const

getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...

static LLVM_ABI PoisonValue * get(Type *T)

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

StringRef - Represent a constant reference to a string, i.e.

static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)

void setOperand(unsigned i, Value *Val)

LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)

Replace uses of one Value with another.

Value * getOperand(unsigned i) const

LLVM Value Representation.

Type * getType() const

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

LLVM_ABI LLVMContext & getContext() const

All values hold a context through their type.

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

LLVM_ABI void takeName(Value *V)

Transfer the name from V to this value.

self_iterator getIterator()

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.

friend class Instruction

Iterator for Instructions in a `BasicBlock.

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.

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

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

FunctionPass * createSPIRVRegularizerPass()

Definition SPIRVRegularizer.cpp:255

DWARFExpression::Operation Op

ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy

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

decltype(auto) cast(const From &Val)

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