LLVM: lib/TableGen/SetTheory.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

25#include

26#include

27#include

28#include

29

30using namespace llvm;

31

32

33namespace {

34

37

38

43 }

44};

45

46

51 PrintFatalError(Loc, "Set difference needs at least two arguments: " +

53 RecSet Add, Sub;

56 for (const auto &I : Add)

57 if (!Sub.count(I))

58 Elts.insert(I);

59 }

60};

61

62

67 PrintFatalError(Loc, "Set intersection requires two arguments: " +

69 RecSet S1, S2;

71 ST.evaluate(Expr->arg_begin()[1], S2, Loc);

72 for (const auto &I : S1)

73 if (S2.count(I))

74 Elts.insert(I);

75 }

76};

77

78

80 virtual void apply2(SetTheory &ST, const DagInit *Expr, RecSet &Set,

82

86 PrintFatalError(Loc, "Operator requires (Op Set, Int) arguments: " +

88 RecSet Set;

89 ST.evaluate(Expr->arg_begin()[0], Set, Loc);

90 const auto *II = dyn_cast(Expr->arg_begin()[1]);

91 if (II)

92 PrintFatalError(Loc, "Second argument must be an integer: " +

94 apply2(ST, Expr, Set, II->getValue(), Elts, Loc);

95 }

96};

97

98

99struct ShlOp : public SetIntBinOp {

100 void apply2(SetTheory &ST, const DagInit *Expr, RecSet &Set, int64_t N,

102 if (N < 0)

105 if (unsigned(N) < Set.size())

106 Elts.insert(Set.begin() + N, Set.end());

107 }

108};

109

110

111struct TruncOp : public SetIntBinOp {

112 void apply2(SetTheory &ST, const DagInit *Expr, RecSet &Set, int64_t N,

114 if (N < 0)

117 if (unsigned(N) > Set.size())

118 N = Set.size();

119 Elts.insert(Set.begin(), Set.begin() + N);

120 }

121};

122

123

124struct RotOp : public SetIntBinOp {

126

127 RotOp(bool Rev) : Reverse(Rev) {}

128

129 void apply2(SetTheory &ST, const DagInit *Expr, RecSet &Set, int64_t N,

131 if (Reverse)

132 N = -N;

133

134 if (Set.empty())

135 return;

136 if (N < 0)

137 N = Set.size() - (-N % Set.size());

138 else

139 N %= Set.size();

140 Elts.insert(Set.begin() + N, Set.end());

141 Elts.insert(Set.begin(), Set.begin() + N);

142 }

143};

144

145

146struct DecimateOp : public SetIntBinOp {

147 void apply2(SetTheory &ST, const DagInit *Expr, RecSet &Set, int64_t N,

149 if (N <= 0)

152 for (unsigned I = 0; I < Set.size(); I += N)

153 Elts.insert(Set[I]);

154 }

155};

156

157

161

163 unsigned MaxSize = 0;

165 ST.evaluate(Arg, Value, Loc);

166 MaxSize = std::max(MaxSize, unsigned(Value.size()));

167 }

168

169 for (unsigned n = 0; n != MaxSize; ++n)

170 for (const RecSet &Value : Values)

171 if (n < Value.size())

172 Elts.insert(Value[n]);

173 }

174};

175

176

180 int Step = 1;

182 PrintFatalError(Loc, "Bad args to (sequence \"Format\", From, To): " +

185 if (const auto *II = dyn_cast(Expr->arg_begin()[3]))

186 Step = II->getValue();

187 else

190 }

191

193 if (const auto *SI = dyn_cast(Expr->arg_begin()[0]))

194 Format = std::string(SI->getValue());

195 else

197

198 int64_t From, To;

199 if (const auto *II = dyn_cast(Expr->arg_begin()[1]))

200 From = II->getValue();

201 else

203 if (From < 0 || From >= (1 << 30))

205

206 if (const auto *II = dyn_cast(Expr->arg_begin()[2]))

207 To = II->getValue();

208 else

210 if (To < 0 || To >= (1 << 30))

212

214 cast(Expr->getOperator())->getDef()->getRecords();

215

216 Step *= From <= To ? 1 : -1;

217 while (true) {

218 if (Step > 0 && From > To)

219 break;

220 else if (Step < 0 && From < To)

221 break;

222 std::string Name;

226 if (!Rec)

229

230 if (const RecVec *Result = ST.expand(Rec))

232 else

233 Elts.insert(Rec);

234

235 From += Step;

236 }

237 }

238};

239

240

243

244 FieldExpander(StringRef fn) : FieldName(fn) {}

245

247 ST.evaluate(Def->getValueInit(FieldName), Elts, Def->getLoc());

248 }

249};

250

251}

252

253

254void SetTheory::Operator::anchor() {}

255void SetTheory::Expander::anchor() {}

256

258 addOperator("add", std::make_unique());

259 addOperator("sub", std::make_unique());

260 addOperator("and", std::make_unique());

261 addOperator("shl", std::make_unique());

262 addOperator("trunc", std::make_unique());

263 addOperator("rotl", std::make_unique(false));

264 addOperator("rotr", std::make_unique(true));

265 addOperator("decimate", std::make_unique());

266 addOperator("interleave", std::make_unique());

267 addOperator("sequence", std::make_unique());

268}

269

271 Operators[Name] = std::move(Op);

272}

273

275 Expanders[ClassName] = std::move(E);

276}

277

279 addExpander(ClassName, std::make_unique(FieldName));

280}

281

283

284 if (const auto *Def = dyn_cast(Expr)) {

285 if (const RecVec *Result = expand(Def->getDef()))

286 return Elts.insert(Result->begin(), Result->end());

287 Elts.insert(Def->getDef());

288 return;

289 }

290

291

292 if (const auto *LI = dyn_cast(Expr))

293 return evaluate(LI->begin(), LI->end(), Elts, Loc);

294

295

296 const auto *DagExpr = dyn_cast(Expr);

297 if (!DagExpr)

299 const auto *OpInit = dyn_cast(DagExpr->getOperator());

302 auto I = Operators.find(OpInit->getDef()->getName());

303 if (I == Operators.end())

305 I->second->apply(*this, DagExpr, Elts, Loc);

306}

307

309

310 ExpandMap::iterator I = Expansions.find(Set);

311 if (I != Expansions.end())

312 return &I->second;

313

314

315 for (const auto &[SuperClass, Loc] : Set->getSuperClasses()) {

316

317 if (!isa(SuperClass->getNameInit()))

318 continue;

319 auto I = Expanders.find(SuperClass->getName());

320 if (I == Expanders.end())

321 continue;

322

323 RecVec &EltVec = Expansions[Set];

325 I->second->expand(*this, Set, Elts);

326 EltVec.assign(Elts.begin(), Elts.end());

327 return &EltVec;

328 }

329

330

331 return nullptr;

332}

BlockVerifier::State From

uint64_t IntrinsicInst * II

This file defines the SmallVector class.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

This class represents an Operation in the Expression.

(v a, b) - Represent a DAG tree value.

unsigned getNumArgs() const

const_arg_iterator arg_begin() const

const_arg_iterator arg_end() const

const Init * getOperator() const

ArrayRef< const Init * > getArgs() const

std::string getAsString() const override

Convert this value to a literal form.

virtual std::string getAsString() const =0

Convert this value to a literal form.

Base class for operators.

Expander - A callback function that can transform a Record representing a set into a fully expanded l...

virtual void expand(SetTheory &, const Record *, RecSet &Elts)=0

Operator - A callback representing a DAG operator.

virtual void apply(SetTheory &, const DagInit *Expr, RecSet &Elts, ArrayRef< SMLoc > Loc)=0

apply - Apply this operator to Expr's arguments and insert the result in Elts.

void addOperator(StringRef Name, std::unique_ptr< Operator >)

addOperator - Add a DAG operator.

SetTheory()

Create a SetTheory instance with only the standard operators.

const RecVec * expand(const Record *Set)

expand - Expand a record into a set of elements if possible.

SmallSetVector< const Record *, 16 > RecSet

void evaluate(const Init *Expr, RecSet &Elts, ArrayRef< SMLoc > Loc)

evaluate - Evaluate Expr and append the resulting set to Elts.

std::vector< const Record * > RecVec

void addFieldExpander(StringRef ClassName, StringRef FieldName)

addFieldExpander - Add an expander for ClassName that simply evaluates FieldName in the Record to get...

void addExpander(StringRef ClassName, std::unique_ptr< Expander >)

addExpander - Add an expander for Records with the named super class.

iterator end()

Get an iterator to the end of the SetVector.

iterator begin()

Get an iterator to the beginning of the SetVector.

bool insert(const value_type &X)

Insert a new element into the SetVector.

A SetVector that performs no allocations if smaller than a certain size.

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.

LLVM Value Representation.

A raw_ostream that writes to an std::string.

llvm::SmallVector< std::shared_ptr< RecordsSlice >, 4 > Records

NodeAddr< DefNode * > Def

This is an optimization pass for GlobalISel generic memory operations.

detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)

zip iterator for two or more iteratable types.

void PrintFatalError(const Twine &Msg)

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.