|
11 | 11 | /// |
12 | 12 | //===----------------------------------------------------------------------===// |
13 | 13 |
|
14 | | -#ifndef CLANG_CIR_DIALECT_IR_CIROPS_TD |
15 | | -#define CLANG_CIR_DIALECT_IR_CIROPS_TD |
| 14 | +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIROPS |
| 15 | +#define LLVM_CLANG_CIR_DIALECT_IR_CIROPS |
16 | 16 |
|
17 | 17 | include "clang/CIR/Dialect/IR/CIRDialect.td" |
18 | 18 | include "clang/CIR/Dialect/IR/CIRTypes.td" |
@@ -115,165 +115,6 @@ def ConstantOp : CIR_Op<"const", |
115 | 115 | let hasFolder = 1; |
116 | 116 | } |
117 | 117 |
|
118 | | -//===----------------------------------------------------------------------===// |
119 | | -// ReturnOp |
120 | | -//===----------------------------------------------------------------------===// |
121 | | - |
122 | | -def ReturnOp : CIR_Op<"return", [ParentOneOf<["FuncOp", "ScopeOp"]>, |
123 | | - Terminator]> { |
124 | | - let summary = "Return from function"; |
125 | | - let description = [{ |
126 | | - The "return" operation represents a return operation within a function. |
127 | | - The operation takes an optional operand and produces no results. |
128 | | - The operand type must match the signature of the function that contains |
129 | | - the operation. |
130 | | - |
131 | | - ```mlir |
132 | | - func @foo() -> i32 { |
133 | | - ... |
134 | | - cir.return %0 : i32 |
135 | | - } |
136 | | - ``` |
137 | | - }]; |
138 | | - |
139 | | - // The return operation takes an optional input operand to return. This |
140 | | - // value must match the return type of the enclosing function. |
141 | | - let arguments = (ins Variadic<CIR_AnyType>:$input); |
142 | | - |
143 | | - // The return operation only emits the input in the format if it is present. |
144 | | - let assemblyFormat = "($input^ `:` type($input))? attr-dict "; |
145 | | - |
146 | | - // Allow building a ReturnOp with no return operand. |
147 | | - let builders = [ |
148 | | - OpBuilder<(ins), [{ build($_builder, $_state, std::nullopt); }]> |
149 | | - ]; |
150 | | - |
151 | | - // Provide extra utility definitions on the c++ operation class definition. |
152 | | - let extraClassDeclaration = [{ |
153 | | - bool hasOperand() { return getNumOperands() != 0; } |
154 | | - }]; |
155 | | - |
156 | | - let hasVerifier = 1; |
157 | | -} |
158 | | - |
159 | | -//===----------------------------------------------------------------------===// |
160 | | -// YieldOp |
161 | | -//===----------------------------------------------------------------------===// |
162 | | - |
163 | | -def YieldOp : CIR_Op<"yield", [ReturnLike, Terminator, |
164 | | - ParentOneOf<["ScopeOp"]>]> { |
165 | | - let summary = "Represents the default branching behaviour of a region"; |
166 | | - let description = [{ |
167 | | - The `cir.yield` operation terminates regions on different CIR operations, |
168 | | - and it is used to represent the default branching behaviour of a region. |
169 | | - Said branching behaviour is determinted by the parent operation. For |
170 | | - example, a yield in a `switch-case` region implies a fallthrough, while |
171 | | - a yield in a `cir.if` region implies a branch to the exit block, and so |
172 | | - on. |
173 | | - |
174 | | - In some cases, it might yield an SSA value and the semantics of how the |
175 | | - values are yielded is defined by the parent operation. For example, a |
176 | | - `cir.ternary` operation yields a value from one of its regions. |
177 | | - |
178 | | - As a general rule, `cir.yield` must be explicitly used whenever a region has |
179 | | - more than one block and no terminator, or within `cir.switch` regions not |
180 | | - `cir.return` terminated. |
181 | | - |
182 | | - Examples: |
183 | | - ```mlir |
184 | | - cir.if %4 { |
185 | | - ... |
186 | | - cir.yield |
187 | | - } |
188 | | - |
189 | | - cir.switch (%5) [ |
190 | | - case (equal, 3) { |
191 | | - ... |
192 | | - cir.yield |
193 | | - }, ... |
194 | | - ] |
195 | | - |
196 | | - cir.scope { |
197 | | - ... |
198 | | - cir.yield |
199 | | - } |
200 | | - |
201 | | - %x = cir.scope { |
202 | | - ... |
203 | | - cir.yield %val |
204 | | - } |
205 | | - |
206 | | - %y = cir.ternary { |
207 | | - ... |
208 | | - cir.yield %val : i32 |
209 | | - } : i32 |
210 | | - ``` |
211 | | - }]; |
212 | | - |
213 | | - let arguments = (ins Variadic<CIR_AnyType>:$args); |
214 | | - let assemblyFormat = "($args^ `:` type($args))? attr-dict"; |
215 | | - let builders = [ |
216 | | - OpBuilder<(ins), [{ /* nothing to do */ }]>, |
217 | | - ]; |
218 | | -} |
219 | | - |
220 | | -//===----------------------------------------------------------------------===// |
221 | | -// ScopeOp |
222 | | -//===----------------------------------------------------------------------===// |
223 | | - |
224 | | -def ScopeOp : CIR_Op<"scope", [ |
225 | | - DeclareOpInterfaceMethods<RegionBranchOpInterface>, |
226 | | - RecursivelySpeculatable, AutomaticAllocationScope, NoRegionArguments]> { |
227 | | - let summary = "Represents a C/C++ scope"; |
228 | | - let description = [{ |
229 | | - `cir.scope` contains one region and defines a strict "scope" for all new |
230 | | - values produced within its blocks. |
231 | | - |
232 | | - The region can contain an arbitrary number of blocks but usually defaults |
233 | | - to one and can optionally return a value (useful for representing values |
234 | | - coming out of C++ full-expressions) via `cir.yield`: |
235 | | - |
236 | | - |
237 | | - ```mlir |
238 | | - %rvalue = cir.scope { |
239 | | - ... |
240 | | - cir.yield %value |
241 | | - } |
242 | | - ``` |
243 | | - |
244 | | - The blocks can be terminated by `cir.yield`, `cir.return` or `cir.throw`. |
245 | | - If `cir.scope` yields no value, the `cir.yield` can be left out, and |
246 | | - will be inserted implicitly. |
247 | | - }]; |
248 | | - |
249 | | - let results = (outs Optional<CIR_AnyType>:$results); |
250 | | - let regions = (region AnyRegion:$scopeRegion); |
251 | | - |
252 | | - let hasVerifier = 1; |
253 | | - let skipDefaultBuilders = 1; |
254 | | - let assemblyFormat = [{ |
255 | | - custom<OmittedTerminatorRegion>($scopeRegion) (`:` type($results)^)? attr-dict |
256 | | - }]; |
257 | | - |
258 | | - let extraClassDeclaration = [{ |
259 | | - /// Determine whether the scope is empty, meaning it contains a single block |
260 | | - /// terminated by a cir.yield. |
261 | | - bool isEmpty() { |
262 | | - auto &entry = getRegion().front(); |
263 | | - return getRegion().hasOneBlock() && |
264 | | - llvm::isa<YieldOp>(entry.front()); |
265 | | - } |
266 | | - }]; |
267 | | - |
268 | | - let builders = [ |
269 | | - // Scopes for yielding values. |
270 | | - OpBuilder<(ins |
271 | | - "llvm::function_ref<void(mlir::OpBuilder &, mlir::Type &, mlir::Location)>":$scopeBuilder)>, |
272 | | - // Scopes without yielding values. |
273 | | - OpBuilder<(ins "llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>":$scopeBuilder)> |
274 | | - ]; |
275 | | -} |
276 | | - |
277 | 118 | //===----------------------------------------------------------------------===// |
278 | 119 | // GlobalOp |
279 | 120 | //===----------------------------------------------------------------------===// |
@@ -317,86 +158,25 @@ def GlobalOp : CIR_Op<"global"> { |
317 | 158 | // FuncOp |
318 | 159 | //===----------------------------------------------------------------------===// |
319 | 160 |
|
320 | | -// TODO(CIR): FuncOp is still a tiny shell of what it will become. Many more |
321 | | -// properties and attributes will be added as upstreaming continues. |
| 161 | +// TODO(CIR): For starters, cir.func has only name, nothing else. The other |
| 162 | +// properties of a function will be added over time as more of ClangIR is |
| 163 | +// upstreamed. |
322 | 164 |
|
323 | | -def FuncOp : CIR_Op<"func", [ |
324 | | - AutomaticAllocationScope, CallableOpInterface, FunctionOpInterface, |
325 | | - IsolatedFromAbove |
326 | | -]> { |
| 165 | +def FuncOp : CIR_Op<"func"> { |
327 | 166 | let summary = "Declare or define a function"; |
328 | 167 | let description = [{ |
329 | 168 | The `cir.func` operation defines a function, similar to the `mlir::FuncOp` |
330 | 169 | built-in. |
331 | 170 | }]; |
332 | 171 |
|
333 | | - let arguments = (ins SymbolNameAttr:$sym_name, |
334 | | - TypeAttrOf<CIR_FuncType>:$function_type, |
335 | | - OptionalAttr<DictArrayAttr>:$arg_attrs, |
336 | | - OptionalAttr<DictArrayAttr>:$res_attrs); |
337 | | - |
338 | | - let regions = (region AnyRegion:$body); |
| 172 | + let arguments = (ins SymbolNameAttr:$sym_name); |
339 | 173 |
|
340 | 174 | let skipDefaultBuilders = 1; |
341 | 175 |
|
342 | | - let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name, |
343 | | - "FuncType":$type)>]; |
344 | | - |
345 | | - let extraClassDeclaration = [{ |
346 | | - /// Returns the region on the current operation that is callable. This may |
347 | | - /// return null in the case of an external callable object, e.g. an external |
348 | | - /// function. |
349 | | - ::mlir::Region *getCallableRegion(); |
350 | | - |
351 | | - /// Returns the results types that the callable region produces when |
352 | | - /// executed. |
353 | | - llvm::ArrayRef<mlir::Type> getCallableResults() { |
354 | | - return getFunctionType().getReturnTypes(); |
355 | | - } |
356 | | - |
357 | | - /// Returns the argument types of this function. |
358 | | - llvm::ArrayRef<mlir::Type> getArgumentTypes() { |
359 | | - return getFunctionType().getInputs(); |
360 | | - } |
361 | | - |
362 | | - /// Returns 0 or 1 result type of this function (0 in the case of a function |
363 | | - /// returing void) |
364 | | - llvm::ArrayRef<mlir::Type> getResultTypes() { |
365 | | - return getFunctionType().getReturnTypes(); |
366 | | - } |
367 | | - |
368 | | - /// Hook for OpTrait::FunctionOpInterfaceTrait, called after verifying that |
369 | | - /// the 'type' attribute is present and checks if it holds a function type. |
370 | | - /// Ensures getType, getNumFuncArguments, and getNumFuncResults can be |
371 | | - /// called safely. |
372 | | - llvm::LogicalResult verifyType(); |
373 | | - |
374 | | - //===------------------------------------------------------------------===// |
375 | | - // SymbolOpInterface Methods |
376 | | - //===------------------------------------------------------------------===// |
377 | | - |
378 | | - bool isDeclaration(); |
379 | | - }]; |
| 176 | + let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name)>]; |
380 | 177 |
|
381 | 178 | let hasCustomAssemblyFormat = 1; |
382 | 179 | let hasVerifier = 1; |
383 | 180 | } |
384 | 181 |
|
385 | | -//===----------------------------------------------------------------------===// |
386 | | -// TrapOp |
387 | | -//===----------------------------------------------------------------------===// |
388 | | - |
389 | | -def TrapOp : CIR_Op<"trap", [Terminator]> { |
390 | | - let summary = "Exit the program abnormally"; |
391 | | - let description = [{ |
392 | | - The cir.trap operation causes the program to exit abnormally. The |
393 | | - implementations may implement this operation with different mechanisms. For |
394 | | - example, an implementation may implement this operation by calling abort, |
395 | | - while another implementation may implement this operation by executing an |
396 | | - illegal instruction. |
397 | | - }]; |
398 | | - |
399 | | - let assemblyFormat = "attr-dict"; |
400 | | -} |
401 | | - |
402 | | -#endif // CLANG_CIR_DIALECT_IR_CIROPS_TD |
| 182 | +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIROPS |
0 commit comments