1 | //===- Nodes.cpp ----------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "mlir/Tools/PDLL/AST/Nodes.h" |
10 | #include "mlir/Tools/PDLL/AST/Context.h" |
11 | #include "llvm/ADT/SmallPtrSet.h" |
12 | #include "llvm/ADT/TypeSwitch.h" |
13 | #include <optional> |
14 | |
15 | using namespace mlir; |
16 | using namespace mlir::pdll::ast; |
17 | |
18 | /// Copy a string reference into the context with a null terminator. |
19 | static StringRef copyStringWithNull(Context &ctx, StringRef str) { |
20 | if (str.empty()) |
21 | return str; |
22 | |
23 | char *data = ctx.getAllocator().Allocate<char>(Num: str.size() + 1); |
24 | std::copy(first: str.begin(), last: str.end(), result: data); |
25 | data[str.size()] = 0; |
26 | return StringRef(data, str.size()); |
27 | } |
28 | |
29 | //===----------------------------------------------------------------------===// |
30 | // Name |
31 | //===----------------------------------------------------------------------===// |
32 | |
33 | const Name &Name::create(Context &ctx, StringRef name, SMRange location) { |
34 | return *new (ctx.getAllocator().Allocate<Name>()) |
35 | Name(copyStringWithNull(ctx, str: name), location); |
36 | } |
37 | |
38 | //===----------------------------------------------------------------------===// |
39 | // Node |
40 | //===----------------------------------------------------------------------===// |
41 | |
42 | namespace { |
43 | class NodeVisitor { |
44 | public: |
45 | explicit NodeVisitor(function_ref<void(const Node *)> visitFn) |
46 | : visitFn(visitFn) {} |
47 | |
48 | void visit(const Node *node) { |
49 | if (!node || !alreadyVisited.insert(Ptr: node).second) |
50 | return; |
51 | |
52 | visitFn(node); |
53 | TypeSwitch<const Node *>(node) |
54 | .Case< |
55 | // Statements. |
56 | const CompoundStmt, const EraseStmt, const LetStmt, |
57 | const ReplaceStmt, const ReturnStmt, const RewriteStmt, |
58 | |
59 | // Expressions. |
60 | const AttributeExpr, const CallExpr, const DeclRefExpr, |
61 | const MemberAccessExpr, const OperationExpr, const RangeExpr, |
62 | const TupleExpr, const TypeExpr, |
63 | |
64 | // Core Constraint Decls. |
65 | const AttrConstraintDecl, const OpConstraintDecl, |
66 | const TypeConstraintDecl, const TypeRangeConstraintDecl, |
67 | const ValueConstraintDecl, const ValueRangeConstraintDecl, |
68 | |
69 | // Decls. |
70 | const NamedAttributeDecl, const OpNameDecl, const PatternDecl, |
71 | const UserConstraintDecl, const UserRewriteDecl, const VariableDecl, |
72 | |
73 | const Module>( |
74 | caseFn: [&](auto derivedNode) { this->visitImpl(derivedNode); }) |
75 | .Default(defaultFn: [](const Node *) { llvm_unreachable("unknown AST node" ); }); |
76 | } |
77 | |
78 | private: |
79 | void visitImpl(const CompoundStmt *stmt) { |
80 | for (const Node *child : stmt->getChildren()) |
81 | visit(node: child); |
82 | } |
83 | void visitImpl(const EraseStmt *stmt) { visit(node: stmt->getRootOpExpr()); } |
84 | void visitImpl(const LetStmt *stmt) { visit(node: stmt->getVarDecl()); } |
85 | void visitImpl(const ReplaceStmt *stmt) { |
86 | visit(node: stmt->getRootOpExpr()); |
87 | for (const Node *child : stmt->getReplExprs()) |
88 | visit(node: child); |
89 | } |
90 | void visitImpl(const ReturnStmt *stmt) { visit(node: stmt->getResultExpr()); } |
91 | void visitImpl(const RewriteStmt *stmt) { |
92 | visit(node: stmt->getRootOpExpr()); |
93 | visit(node: stmt->getRewriteBody()); |
94 | } |
95 | |
96 | void visitImpl(const AttributeExpr *expr) {} |
97 | void visitImpl(const CallExpr *expr) { |
98 | visit(node: expr->getCallableExpr()); |
99 | for (const Node *child : expr->getArguments()) |
100 | visit(node: child); |
101 | } |
102 | void visitImpl(const DeclRefExpr *expr) { visit(node: expr->getDecl()); } |
103 | void visitImpl(const MemberAccessExpr *expr) { visit(node: expr->getParentExpr()); } |
104 | void visitImpl(const OperationExpr *expr) { |
105 | visit(node: expr->getNameDecl()); |
106 | for (const Node *child : expr->getOperands()) |
107 | visit(node: child); |
108 | for (const Node *child : expr->getResultTypes()) |
109 | visit(node: child); |
110 | for (const Node *child : expr->getAttributes()) |
111 | visit(node: child); |
112 | } |
113 | void visitImpl(const RangeExpr *expr) { |
114 | for (const Node *child : expr->getElements()) |
115 | visit(node: child); |
116 | } |
117 | void visitImpl(const TupleExpr *expr) { |
118 | for (const Node *child : expr->getElements()) |
119 | visit(node: child); |
120 | } |
121 | void visitImpl(const TypeExpr *expr) {} |
122 | |
123 | void visitImpl(const AttrConstraintDecl *decl) { visit(node: decl->getTypeExpr()); } |
124 | void visitImpl(const OpConstraintDecl *decl) { visit(node: decl->getNameDecl()); } |
125 | void visitImpl(const TypeConstraintDecl *decl) {} |
126 | void visitImpl(const TypeRangeConstraintDecl *decl) {} |
127 | void visitImpl(const ValueConstraintDecl *decl) { |
128 | visit(node: decl->getTypeExpr()); |
129 | } |
130 | void visitImpl(const ValueRangeConstraintDecl *decl) { |
131 | visit(node: decl->getTypeExpr()); |
132 | } |
133 | |
134 | void visitImpl(const NamedAttributeDecl *decl) { visit(node: decl->getValue()); } |
135 | void visitImpl(const OpNameDecl *decl) {} |
136 | void visitImpl(const PatternDecl *decl) { visit(node: decl->getBody()); } |
137 | void visitImpl(const UserConstraintDecl *decl) { |
138 | for (const Node *child : decl->getInputs()) |
139 | visit(node: child); |
140 | for (const Node *child : decl->getResults()) |
141 | visit(node: child); |
142 | visit(node: decl->getBody()); |
143 | } |
144 | void visitImpl(const UserRewriteDecl *decl) { |
145 | for (const Node *child : decl->getInputs()) |
146 | visit(node: child); |
147 | for (const Node *child : decl->getResults()) |
148 | visit(node: child); |
149 | visit(node: decl->getBody()); |
150 | } |
151 | void visitImpl(const VariableDecl *decl) { |
152 | visit(node: decl->getInitExpr()); |
153 | for (const ConstraintRef &child : decl->getConstraints()) |
154 | visit(node: child.constraint); |
155 | } |
156 | |
157 | void visitImpl(const Module *module) { |
158 | for (const Node *child : module->getChildren()) |
159 | visit(node: child); |
160 | } |
161 | |
162 | function_ref<void(const Node *)> visitFn; |
163 | SmallPtrSet<const Node *, 16> alreadyVisited; |
164 | }; |
165 | } // namespace |
166 | |
167 | void Node::walk(function_ref<void(const Node *)> walkFn) const { |
168 | return NodeVisitor(walkFn).visit(node: this); |
169 | } |
170 | |
171 | //===----------------------------------------------------------------------===// |
172 | // DeclScope |
173 | //===----------------------------------------------------------------------===// |
174 | |
175 | void DeclScope::add(Decl *decl) { |
176 | const Name *name = decl->getName(); |
177 | assert(name && "expected a named decl" ); |
178 | assert(!decls.count(name->getName()) && "decl with this name already exists" ); |
179 | decls.try_emplace(Key: name->getName(), Args&: decl); |
180 | } |
181 | |
182 | Decl *DeclScope::lookup(StringRef name) { |
183 | if (Decl *decl = decls.lookup(Key: name)) |
184 | return decl; |
185 | return parent ? parent->lookup(name) : nullptr; |
186 | } |
187 | |
188 | //===----------------------------------------------------------------------===// |
189 | // CompoundStmt |
190 | //===----------------------------------------------------------------------===// |
191 | |
192 | CompoundStmt *CompoundStmt::create(Context &ctx, SMRange loc, |
193 | ArrayRef<Stmt *> children) { |
194 | unsigned allocSize = CompoundStmt::totalSizeToAlloc<Stmt *>(Counts: children.size()); |
195 | void *rawData = ctx.getAllocator().Allocate(Size: allocSize, Alignment: alignof(CompoundStmt)); |
196 | |
197 | CompoundStmt *stmt = new (rawData) CompoundStmt(loc, children.size()); |
198 | std::uninitialized_copy(first: children.begin(), last: children.end(), |
199 | result: stmt->getChildren().begin()); |
200 | return stmt; |
201 | } |
202 | |
203 | //===----------------------------------------------------------------------===// |
204 | // LetStmt |
205 | //===----------------------------------------------------------------------===// |
206 | |
207 | LetStmt *LetStmt::create(Context &ctx, SMRange loc, VariableDecl *varDecl) { |
208 | return new (ctx.getAllocator().Allocate<LetStmt>()) LetStmt(loc, varDecl); |
209 | } |
210 | |
211 | //===----------------------------------------------------------------------===// |
212 | // OpRewriteStmt |
213 | //===----------------------------------------------------------------------===// |
214 | |
215 | //===----------------------------------------------------------------------===// |
216 | // EraseStmt |
217 | |
218 | EraseStmt *EraseStmt::create(Context &ctx, SMRange loc, Expr *rootOp) { |
219 | return new (ctx.getAllocator().Allocate<EraseStmt>()) EraseStmt(loc, rootOp); |
220 | } |
221 | |
222 | //===----------------------------------------------------------------------===// |
223 | // ReplaceStmt |
224 | |
225 | ReplaceStmt *ReplaceStmt::create(Context &ctx, SMRange loc, Expr *rootOp, |
226 | ArrayRef<Expr *> replExprs) { |
227 | unsigned allocSize = ReplaceStmt::totalSizeToAlloc<Expr *>(Counts: replExprs.size()); |
228 | void *rawData = ctx.getAllocator().Allocate(Size: allocSize, Alignment: alignof(ReplaceStmt)); |
229 | |
230 | ReplaceStmt *stmt = new (rawData) ReplaceStmt(loc, rootOp, replExprs.size()); |
231 | std::uninitialized_copy(first: replExprs.begin(), last: replExprs.end(), |
232 | result: stmt->getReplExprs().begin()); |
233 | return stmt; |
234 | } |
235 | |
236 | //===----------------------------------------------------------------------===// |
237 | // RewriteStmt |
238 | |
239 | RewriteStmt *RewriteStmt::create(Context &ctx, SMRange loc, Expr *rootOp, |
240 | CompoundStmt *rewriteBody) { |
241 | return new (ctx.getAllocator().Allocate<RewriteStmt>()) |
242 | RewriteStmt(loc, rootOp, rewriteBody); |
243 | } |
244 | |
245 | //===----------------------------------------------------------------------===// |
246 | // ReturnStmt |
247 | //===----------------------------------------------------------------------===// |
248 | |
249 | ReturnStmt *ReturnStmt::create(Context &ctx, SMRange loc, Expr *resultExpr) { |
250 | return new (ctx.getAllocator().Allocate<ReturnStmt>()) |
251 | ReturnStmt(loc, resultExpr); |
252 | } |
253 | |
254 | //===----------------------------------------------------------------------===// |
255 | // AttributeExpr |
256 | //===----------------------------------------------------------------------===// |
257 | |
258 | AttributeExpr *AttributeExpr::create(Context &ctx, SMRange loc, |
259 | StringRef value) { |
260 | return new (ctx.getAllocator().Allocate<AttributeExpr>()) |
261 | AttributeExpr(ctx, loc, copyStringWithNull(ctx, str: value)); |
262 | } |
263 | |
264 | //===----------------------------------------------------------------------===// |
265 | // CallExpr |
266 | //===----------------------------------------------------------------------===// |
267 | |
268 | CallExpr *CallExpr::create(Context &ctx, SMRange loc, Expr *callable, |
269 | ArrayRef<Expr *> arguments, Type resultType, |
270 | bool isNegated) { |
271 | unsigned allocSize = CallExpr::totalSizeToAlloc<Expr *>(Counts: arguments.size()); |
272 | void *rawData = ctx.getAllocator().Allocate(Size: allocSize, Alignment: alignof(CallExpr)); |
273 | |
274 | CallExpr *expr = new (rawData) |
275 | CallExpr(loc, resultType, callable, arguments.size(), isNegated); |
276 | std::uninitialized_copy(first: arguments.begin(), last: arguments.end(), |
277 | result: expr->getArguments().begin()); |
278 | return expr; |
279 | } |
280 | |
281 | //===----------------------------------------------------------------------===// |
282 | // DeclRefExpr |
283 | //===----------------------------------------------------------------------===// |
284 | |
285 | DeclRefExpr *DeclRefExpr::create(Context &ctx, SMRange loc, Decl *decl, |
286 | Type type) { |
287 | return new (ctx.getAllocator().Allocate<DeclRefExpr>()) |
288 | DeclRefExpr(loc, decl, type); |
289 | } |
290 | |
291 | //===----------------------------------------------------------------------===// |
292 | // MemberAccessExpr |
293 | //===----------------------------------------------------------------------===// |
294 | |
295 | MemberAccessExpr *MemberAccessExpr::create(Context &ctx, SMRange loc, |
296 | const Expr *parentExpr, |
297 | StringRef memberName, Type type) { |
298 | return new (ctx.getAllocator().Allocate<MemberAccessExpr>()) MemberAccessExpr( |
299 | loc, parentExpr, memberName.copy(A&: ctx.getAllocator()), type); |
300 | } |
301 | |
302 | //===----------------------------------------------------------------------===// |
303 | // OperationExpr |
304 | //===----------------------------------------------------------------------===// |
305 | |
306 | OperationExpr * |
307 | OperationExpr::create(Context &ctx, SMRange loc, const ods::Operation *odsOp, |
308 | const OpNameDecl *name, ArrayRef<Expr *> operands, |
309 | ArrayRef<Expr *> resultTypes, |
310 | ArrayRef<NamedAttributeDecl *> attributes) { |
311 | unsigned allocSize = |
312 | OperationExpr::totalSizeToAlloc<Expr *, NamedAttributeDecl *>( |
313 | Counts: operands.size() + resultTypes.size(), Counts: attributes.size()); |
314 | void *rawData = |
315 | ctx.getAllocator().Allocate(Size: allocSize, Alignment: alignof(OperationExpr)); |
316 | |
317 | Type resultType = OperationType::get(context&: ctx, name: name->getName(), odsOp); |
318 | OperationExpr *opExpr = new (rawData) |
319 | OperationExpr(loc, resultType, name, operands.size(), resultTypes.size(), |
320 | attributes.size(), name->getLoc()); |
321 | std::uninitialized_copy(first: operands.begin(), last: operands.end(), |
322 | result: opExpr->getOperands().begin()); |
323 | std::uninitialized_copy(first: resultTypes.begin(), last: resultTypes.end(), |
324 | result: opExpr->getResultTypes().begin()); |
325 | std::uninitialized_copy(first: attributes.begin(), last: attributes.end(), |
326 | result: opExpr->getAttributes().begin()); |
327 | return opExpr; |
328 | } |
329 | |
330 | std::optional<StringRef> OperationExpr::getName() const { |
331 | return getNameDecl()->getName(); |
332 | } |
333 | |
334 | //===----------------------------------------------------------------------===// |
335 | // RangeExpr |
336 | //===----------------------------------------------------------------------===// |
337 | |
338 | RangeExpr *RangeExpr::create(Context &ctx, SMRange loc, |
339 | ArrayRef<Expr *> elements, RangeType type) { |
340 | unsigned allocSize = RangeExpr::totalSizeToAlloc<Expr *>(Counts: elements.size()); |
341 | void *rawData = ctx.getAllocator().Allocate(Size: allocSize, Alignment: alignof(TupleExpr)); |
342 | |
343 | RangeExpr *expr = new (rawData) RangeExpr(loc, type, elements.size()); |
344 | std::uninitialized_copy(first: elements.begin(), last: elements.end(), |
345 | result: expr->getElements().begin()); |
346 | return expr; |
347 | } |
348 | |
349 | //===----------------------------------------------------------------------===// |
350 | // TupleExpr |
351 | //===----------------------------------------------------------------------===// |
352 | |
353 | TupleExpr *TupleExpr::create(Context &ctx, SMRange loc, |
354 | ArrayRef<Expr *> elements, |
355 | ArrayRef<StringRef> names) { |
356 | unsigned allocSize = TupleExpr::totalSizeToAlloc<Expr *>(Counts: elements.size()); |
357 | void *rawData = ctx.getAllocator().Allocate(Size: allocSize, Alignment: alignof(TupleExpr)); |
358 | |
359 | auto elementTypes = llvm::map_range( |
360 | C&: elements, F: [](const Expr *expr) { return expr->getType(); }); |
361 | TupleType type = TupleType::get(context&: ctx, elementTypes: llvm::to_vector(Range&: elementTypes), elementNames: names); |
362 | |
363 | TupleExpr *expr = new (rawData) TupleExpr(loc, type); |
364 | std::uninitialized_copy(first: elements.begin(), last: elements.end(), |
365 | result: expr->getElements().begin()); |
366 | return expr; |
367 | } |
368 | |
369 | //===----------------------------------------------------------------------===// |
370 | // TypeExpr |
371 | //===----------------------------------------------------------------------===// |
372 | |
373 | TypeExpr *TypeExpr::create(Context &ctx, SMRange loc, StringRef value) { |
374 | return new (ctx.getAllocator().Allocate<TypeExpr>()) |
375 | TypeExpr(ctx, loc, copyStringWithNull(ctx, str: value)); |
376 | } |
377 | |
378 | //===----------------------------------------------------------------------===// |
379 | // Decl |
380 | //===----------------------------------------------------------------------===// |
381 | |
382 | void Decl::(Context &ctx, StringRef ) { |
383 | docComment = comment.copy(A&: ctx.getAllocator()); |
384 | } |
385 | |
386 | //===----------------------------------------------------------------------===// |
387 | // AttrConstraintDecl |
388 | //===----------------------------------------------------------------------===// |
389 | |
390 | AttrConstraintDecl *AttrConstraintDecl::create(Context &ctx, SMRange loc, |
391 | Expr *typeExpr) { |
392 | return new (ctx.getAllocator().Allocate<AttrConstraintDecl>()) |
393 | AttrConstraintDecl(loc, typeExpr); |
394 | } |
395 | |
396 | //===----------------------------------------------------------------------===// |
397 | // OpConstraintDecl |
398 | //===----------------------------------------------------------------------===// |
399 | |
400 | OpConstraintDecl *OpConstraintDecl::create(Context &ctx, SMRange loc, |
401 | const OpNameDecl *nameDecl) { |
402 | if (!nameDecl) |
403 | nameDecl = OpNameDecl::create(ctx, loc: SMRange()); |
404 | |
405 | return new (ctx.getAllocator().Allocate<OpConstraintDecl>()) |
406 | OpConstraintDecl(loc, nameDecl); |
407 | } |
408 | |
409 | std::optional<StringRef> OpConstraintDecl::getName() const { |
410 | return getNameDecl()->getName(); |
411 | } |
412 | |
413 | //===----------------------------------------------------------------------===// |
414 | // TypeConstraintDecl |
415 | //===----------------------------------------------------------------------===// |
416 | |
417 | TypeConstraintDecl *TypeConstraintDecl::create(Context &ctx, SMRange loc) { |
418 | return new (ctx.getAllocator().Allocate<TypeConstraintDecl>()) |
419 | TypeConstraintDecl(loc); |
420 | } |
421 | |
422 | //===----------------------------------------------------------------------===// |
423 | // TypeRangeConstraintDecl |
424 | //===----------------------------------------------------------------------===// |
425 | |
426 | TypeRangeConstraintDecl *TypeRangeConstraintDecl::create(Context &ctx, |
427 | SMRange loc) { |
428 | return new (ctx.getAllocator().Allocate<TypeRangeConstraintDecl>()) |
429 | TypeRangeConstraintDecl(loc); |
430 | } |
431 | |
432 | //===----------------------------------------------------------------------===// |
433 | // ValueConstraintDecl |
434 | //===----------------------------------------------------------------------===// |
435 | |
436 | ValueConstraintDecl *ValueConstraintDecl::create(Context &ctx, SMRange loc, |
437 | Expr *typeExpr) { |
438 | return new (ctx.getAllocator().Allocate<ValueConstraintDecl>()) |
439 | ValueConstraintDecl(loc, typeExpr); |
440 | } |
441 | |
442 | //===----------------------------------------------------------------------===// |
443 | // ValueRangeConstraintDecl |
444 | //===----------------------------------------------------------------------===// |
445 | |
446 | ValueRangeConstraintDecl * |
447 | ValueRangeConstraintDecl::create(Context &ctx, SMRange loc, Expr *typeExpr) { |
448 | return new (ctx.getAllocator().Allocate<ValueRangeConstraintDecl>()) |
449 | ValueRangeConstraintDecl(loc, typeExpr); |
450 | } |
451 | |
452 | //===----------------------------------------------------------------------===// |
453 | // UserConstraintDecl |
454 | //===----------------------------------------------------------------------===// |
455 | |
456 | std::optional<StringRef> |
457 | UserConstraintDecl::getNativeInputType(unsigned index) const { |
458 | return hasNativeInputTypes ? getTrailingObjects<StringRef>()[index] |
459 | : std::optional<StringRef>(); |
460 | } |
461 | |
462 | UserConstraintDecl *UserConstraintDecl::createImpl( |
463 | Context &ctx, const Name &name, ArrayRef<VariableDecl *> inputs, |
464 | ArrayRef<StringRef> nativeInputTypes, ArrayRef<VariableDecl *> results, |
465 | std::optional<StringRef> codeBlock, const CompoundStmt *body, |
466 | Type resultType) { |
467 | bool hasNativeInputTypes = !nativeInputTypes.empty(); |
468 | assert(!hasNativeInputTypes || nativeInputTypes.size() == inputs.size()); |
469 | |
470 | unsigned allocSize = |
471 | UserConstraintDecl::totalSizeToAlloc<VariableDecl *, StringRef>( |
472 | Counts: inputs.size() + results.size(), |
473 | Counts: hasNativeInputTypes ? inputs.size() : 0); |
474 | void *rawData = |
475 | ctx.getAllocator().Allocate(Size: allocSize, Alignment: alignof(UserConstraintDecl)); |
476 | if (codeBlock) |
477 | codeBlock = codeBlock->copy(A&: ctx.getAllocator()); |
478 | |
479 | UserConstraintDecl *decl = new (rawData) |
480 | UserConstraintDecl(name, inputs.size(), hasNativeInputTypes, |
481 | results.size(), codeBlock, body, resultType); |
482 | std::uninitialized_copy(first: inputs.begin(), last: inputs.end(), |
483 | result: decl->getInputs().begin()); |
484 | std::uninitialized_copy(first: results.begin(), last: results.end(), |
485 | result: decl->getResults().begin()); |
486 | if (hasNativeInputTypes) { |
487 | StringRef *nativeInputTypesPtr = decl->getTrailingObjects<StringRef>(); |
488 | for (unsigned i = 0, e = inputs.size(); i < e; ++i) |
489 | nativeInputTypesPtr[i] = nativeInputTypes[i].copy(A&: ctx.getAllocator()); |
490 | } |
491 | |
492 | return decl; |
493 | } |
494 | |
495 | //===----------------------------------------------------------------------===// |
496 | // NamedAttributeDecl |
497 | //===----------------------------------------------------------------------===// |
498 | |
499 | NamedAttributeDecl *NamedAttributeDecl::create(Context &ctx, const Name &name, |
500 | Expr *value) { |
501 | return new (ctx.getAllocator().Allocate<NamedAttributeDecl>()) |
502 | NamedAttributeDecl(name, value); |
503 | } |
504 | |
505 | //===----------------------------------------------------------------------===// |
506 | // OpNameDecl |
507 | //===----------------------------------------------------------------------===// |
508 | |
509 | OpNameDecl *OpNameDecl::create(Context &ctx, const Name &name) { |
510 | return new (ctx.getAllocator().Allocate<OpNameDecl>()) OpNameDecl(name); |
511 | } |
512 | OpNameDecl *OpNameDecl::create(Context &ctx, SMRange loc) { |
513 | return new (ctx.getAllocator().Allocate<OpNameDecl>()) OpNameDecl(loc); |
514 | } |
515 | |
516 | //===----------------------------------------------------------------------===// |
517 | // PatternDecl |
518 | //===----------------------------------------------------------------------===// |
519 | |
520 | PatternDecl *PatternDecl::create(Context &ctx, SMRange loc, const Name *name, |
521 | std::optional<uint16_t> benefit, |
522 | bool hasBoundedRecursion, |
523 | const CompoundStmt *body) { |
524 | return new (ctx.getAllocator().Allocate<PatternDecl>()) |
525 | PatternDecl(loc, name, benefit, hasBoundedRecursion, body); |
526 | } |
527 | |
528 | //===----------------------------------------------------------------------===// |
529 | // UserRewriteDecl |
530 | //===----------------------------------------------------------------------===// |
531 | |
532 | UserRewriteDecl *UserRewriteDecl::createImpl(Context &ctx, const Name &name, |
533 | ArrayRef<VariableDecl *> inputs, |
534 | ArrayRef<VariableDecl *> results, |
535 | std::optional<StringRef> codeBlock, |
536 | const CompoundStmt *body, |
537 | Type resultType) { |
538 | unsigned allocSize = UserRewriteDecl::totalSizeToAlloc<VariableDecl *>( |
539 | Counts: inputs.size() + results.size()); |
540 | void *rawData = |
541 | ctx.getAllocator().Allocate(Size: allocSize, Alignment: alignof(UserRewriteDecl)); |
542 | if (codeBlock) |
543 | codeBlock = codeBlock->copy(A&: ctx.getAllocator()); |
544 | |
545 | UserRewriteDecl *decl = new (rawData) UserRewriteDecl( |
546 | name, inputs.size(), results.size(), codeBlock, body, resultType); |
547 | std::uninitialized_copy(first: inputs.begin(), last: inputs.end(), |
548 | result: decl->getInputs().begin()); |
549 | std::uninitialized_copy(first: results.begin(), last: results.end(), |
550 | result: decl->getResults().begin()); |
551 | return decl; |
552 | } |
553 | |
554 | //===----------------------------------------------------------------------===// |
555 | // VariableDecl |
556 | //===----------------------------------------------------------------------===// |
557 | |
558 | VariableDecl *VariableDecl::create(Context &ctx, const Name &name, Type type, |
559 | Expr *initExpr, |
560 | ArrayRef<ConstraintRef> constraints) { |
561 | unsigned allocSize = |
562 | VariableDecl::totalSizeToAlloc<ConstraintRef>(Counts: constraints.size()); |
563 | void *rawData = ctx.getAllocator().Allocate(Size: allocSize, Alignment: alignof(VariableDecl)); |
564 | |
565 | VariableDecl *varDecl = |
566 | new (rawData) VariableDecl(name, type, initExpr, constraints.size()); |
567 | std::uninitialized_copy(first: constraints.begin(), last: constraints.end(), |
568 | result: varDecl->getConstraints().begin()); |
569 | return varDecl; |
570 | } |
571 | |
572 | //===----------------------------------------------------------------------===// |
573 | // Module |
574 | //===----------------------------------------------------------------------===// |
575 | |
576 | Module *Module::create(Context &ctx, SMLoc loc, ArrayRef<Decl *> children) { |
577 | unsigned allocSize = Module::totalSizeToAlloc<Decl *>(Counts: children.size()); |
578 | void *rawData = ctx.getAllocator().Allocate(Size: allocSize, Alignment: alignof(Module)); |
579 | |
580 | Module *module = new (rawData) Module(loc, children.size()); |
581 | std::uninitialized_copy(first: children.begin(), last: children.end(), |
582 | result: module->getChildren().begin()); |
583 | return module; |
584 | } |
585 | |