|
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