[mlir] Add GlobalOp, GlobalLoadConstOp to ml_program.
The approach I took was to define a dialect 'extern' attribute that a GlobalOp can take as a value to signify external linkage. I think this approach should compose well and should also work with wherever the OpaqueElements work goes in the future (since that is just another kind of attribute). I special cased the GlobalOp parser/printer for this case because it is significantly easier on the eyes. In the discussion, Jeff Niu had proposed an alternative syntax for GlobalOp that I ended up not taking. I did try to implement it but a) I don't think it made anything easier to read in the common case, and b) it made the parsing/printing logic a lot more complicated (I think I would need a completely custom parser/printer to do it well). Please have a look at the common cases where the global type and initial value type match: I don't think how I have it is too bad. The less common cases seem ok to me. I chose to only implement the direct, constant load op since that is non side effecting and there was still discussion pending on that. Differential Revision: https://reviews.llvm.org/D124318
This commit is contained in:
		
							parent
							
								
									b21c03854c
								
							
						
					
					
						commit
						2bb252852c
					
				| 
						 | 
				
			
			@ -1,3 +1,10 @@
 | 
			
		|||
set(LLVM_TARGET_DEFINITIONS MLProgramOps.td)
 | 
			
		||||
add_mlir_dialect(MLProgramOps ml_program)
 | 
			
		||||
add_mlir_doc(MLProgramOps MLProgramOps Dialects/ -gen-dialect-doc)
 | 
			
		||||
 | 
			
		||||
set(LLVM_TARGET_DEFINITIONS MLProgramAttributes.td)
 | 
			
		||||
mlir_tablegen(MLProgramAttributes.h.inc -gen-attrdef-decls)
 | 
			
		||||
mlir_tablegen(MLProgramAttributes.cpp.inc -gen-attrdef-defs)
 | 
			
		||||
add_public_tablegen_target(MLIRMLProgramAttributesIncGen)
 | 
			
		||||
add_dependencies(mlir-headers MLIRMLProgramAttributesIncGen)
 | 
			
		||||
add_mlir_doc(MLProgramAttributes MLProgramAttributes Dialects/ -gen-attrdef-doc)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
#ifndef MLIR_DIALECT_MLPROGRAM_IR_MLPROGRAM_H_
 | 
			
		||||
#define MLIR_DIALECT_MLPROGRAM_IR_MLPROGRAM_H_
 | 
			
		||||
 | 
			
		||||
#include "mlir/Dialect/MLProgram/IR/MLProgramAttributes.h"
 | 
			
		||||
#include "mlir/IR/Dialect.h"
 | 
			
		||||
#include "mlir/IR/FunctionInterfaces.h"
 | 
			
		||||
#include "mlir/IR/OpDefinition.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
//===- MLProgramAttributes.h - Attribute Classes ----------------*- C++ -*-===//
 | 
			
		||||
//
 | 
			
		||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
			
		||||
// See https://llvm.org/LICENSE.txt for license information.
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
			
		||||
//
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
#ifndef MLIR_DIALECT_MLPROGRAM_IR_MLPROGRAMATTRIBUTES_H_
 | 
			
		||||
#define MLIR_DIALECT_MLPROGRAM_IR_MLPROGRAMATTRIBUTES_H_
 | 
			
		||||
 | 
			
		||||
#include "mlir/IR/Attributes.h"
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
// Tablegen Attribute Declarations
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
#define GET_ATTRDEF_CLASSES
 | 
			
		||||
#include "mlir/Dialect/MLProgram/IR/MLProgramAttributes.h.inc"
 | 
			
		||||
 | 
			
		||||
#endif // MLIR_DIALECT_MLPROGRAM_IR_MLPROGRAMATTRIBUTES_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
//===- MLProgramAttributed.td - Attr definitions -----------*- tablegen -*-===//
 | 
			
		||||
//
 | 
			
		||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
			
		||||
// See https://llvm.org/LICENSE.txt for license information.
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
			
		||||
//
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
#ifndef MLPROGRAM_ATTRIBUTES
 | 
			
		||||
#define MLPROGRAM_ATTRIBUTES
 | 
			
		||||
 | 
			
		||||
include "mlir/IR/AttrTypeBase.td"
 | 
			
		||||
include "mlir/Dialect/MLProgram/IR/MLProgramBase.td"
 | 
			
		||||
 | 
			
		||||
// Base class for MLProgram dialect attributes.
 | 
			
		||||
class MLProgram_Attr<string name, list<Trait> traits = []>
 | 
			
		||||
    : AttrDef<MLProgram_Dialect, name, traits> {
 | 
			
		||||
  let mnemonic = ?;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
// ExternAttr
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
def MLProgram_ExternAttr : MLProgram_Attr<"Extern"> {
 | 
			
		||||
  let summary = "Value used for a global signalling external resolution";
 | 
			
		||||
  let description = [{
 | 
			
		||||
  When used as the value for a GlobalOp, this indicates that the actual
 | 
			
		||||
  value should be resolved externally in an implementation defined manner.
 | 
			
		||||
  The `sym_name` of the global is the key for locating the value.
 | 
			
		||||
 | 
			
		||||
  Examples:
 | 
			
		||||
 | 
			
		||||
  ```mlir
 | 
			
		||||
  extern : tensor<4xi32>
 | 
			
		||||
  ```
 | 
			
		||||
  }];
 | 
			
		||||
 | 
			
		||||
  let parameters = (ins AttributeSelfTypeParameter<"">:$type);
 | 
			
		||||
  let mnemonic = "extern";
 | 
			
		||||
  let assemblyFormat = "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // MLPROGRAM_ATTRIBUTES
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ def MLProgram_Dialect : Dialect {
 | 
			
		|||
    it is recommended to inquire further prior to using this dialect.
 | 
			
		||||
  }];
 | 
			
		||||
 | 
			
		||||
  let useDefaultAttributePrinterParser = 1;
 | 
			
		||||
  let emitAccessorPrefix = kEmitAccessorPrefix_Prefixed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,6 +96,101 @@ def MLProgram_FuncOp : MLProgram_Op<"func", [
 | 
			
		|||
  let hasCustomAssemblyFormat = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
// GlobalOp
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
def MLProgram_GlobalOp : MLProgram_Op<"global", [
 | 
			
		||||
    Symbol
 | 
			
		||||
  ]> {
 | 
			
		||||
  let summary = "Module level declaration of a global variable";
 | 
			
		||||
  let description = [{
 | 
			
		||||
    Declares a named global variable (or constant).
 | 
			
		||||
 | 
			
		||||
    A global contains a value of a specified type which can be accessed at
 | 
			
		||||
    runtime via appropriate load/store operations. It can be mutable or
 | 
			
		||||
    constant, optionally taking an initial value or declared as
 | 
			
		||||
    extern (in which case, the initial value is found in external storage
 | 
			
		||||
    by symbol name).
 | 
			
		||||
 | 
			
		||||
    Generally, the type of the global and the type of the initial value
 | 
			
		||||
    will be the same. However, for type hierarchies which can have a more
 | 
			
		||||
    generalized bounding type that can be assigned from a narrow type, this
 | 
			
		||||
    is allowed (but not verified).
 | 
			
		||||
 | 
			
		||||
    Examples:
 | 
			
		||||
 | 
			
		||||
    ```mlir
 | 
			
		||||
    // Constant global.
 | 
			
		||||
    ml_program.global @foobar(dense<4> : tensor<4xi32>) : tensor<?xi32>
 | 
			
		||||
 | 
			
		||||
    // Constant with external linkage.
 | 
			
		||||
    ml_program.global mutable @foobar(#ml_program.extern<tensor<4xi32>>)
 | 
			
		||||
      : tensor<?xi32>
 | 
			
		||||
 | 
			
		||||
    // Mutable global with an undefined initial value.
 | 
			
		||||
    ml_program.global mutable @foobar : tensor<?xi32>
 | 
			
		||||
    ```
 | 
			
		||||
  }];
 | 
			
		||||
 | 
			
		||||
  let arguments = (ins
 | 
			
		||||
    SymbolNameAttr:$sym_name,
 | 
			
		||||
    TypeAttr:$type,
 | 
			
		||||
    UnitAttr:$is_mutable,
 | 
			
		||||
    OptionalAttr<AnyAttr>:$value,
 | 
			
		||||
    OptionalAttr<StrAttr>:$sym_visibility
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  let assemblyFormat = [{
 | 
			
		||||
    custom<SymbolVisibility>($sym_visibility)
 | 
			
		||||
    (`mutable` $is_mutable^)?
 | 
			
		||||
    $sym_name ``
 | 
			
		||||
    custom<TypedInitialValue>($type, $value)
 | 
			
		||||
    attr-dict
 | 
			
		||||
  }];
 | 
			
		||||
 | 
			
		||||
  let hasVerifier = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
// GlobalLoadConstOp
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
def MLProgram_GlobalLoadConstOp : MLProgram_Op<"global_load_const", [
 | 
			
		||||
    NoSideEffect,
 | 
			
		||||
    DeclareOpInterfaceMethods<SymbolUserOpInterface>
 | 
			
		||||
  ]> {
 | 
			
		||||
  let summary = "Direct load a constant value from a global";
 | 
			
		||||
  let description = [{
 | 
			
		||||
    Loads a constant (immutable) value from a global directly by symbol.
 | 
			
		||||
 | 
			
		||||
    This op is only legal for globals that are not mutable and exists because
 | 
			
		||||
    such a load can be considered to have no side effects.
 | 
			
		||||
 | 
			
		||||
    Example:
 | 
			
		||||
 | 
			
		||||
    ```mlir
 | 
			
		||||
    %0 = ml_program.global_load_const @foobar : tensor<?xi32>
 | 
			
		||||
    ```
 | 
			
		||||
  }];
 | 
			
		||||
 | 
			
		||||
  let arguments = (ins
 | 
			
		||||
    FlatSymbolRefAttr:$global
 | 
			
		||||
  );
 | 
			
		||||
  let results = (outs
 | 
			
		||||
    AnyType:$result
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  let assemblyFormat = [{
 | 
			
		||||
    $global attr-dict `:` type($result)
 | 
			
		||||
  }];
 | 
			
		||||
 | 
			
		||||
  let extraClassDeclaration = [{
 | 
			
		||||
    /// Gets the corresponding GlobalOp (or nullptr).
 | 
			
		||||
    GlobalOp getGlobalOp(SymbolTableCollection &symbolTable);
 | 
			
		||||
  }];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
// SubgraphOp
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ add_mlir_dialect_library(MLIRMLProgram
 | 
			
		|||
 | 
			
		||||
  DEPENDS
 | 
			
		||||
  MLIRMLProgramOpsIncGen
 | 
			
		||||
  MLIRMLProgramAttributesIncGen
 | 
			
		||||
 | 
			
		||||
  LINK_LIBS PUBLIC
 | 
			
		||||
  MLIRDialect
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,15 +7,42 @@
 | 
			
		|||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
#include "mlir/Dialect/MLProgram/IR/MLProgram.h"
 | 
			
		||||
#include "mlir/IR/DialectImplementation.h"
 | 
			
		||||
#include "llvm/ADT/TypeSwitch.h"
 | 
			
		||||
 | 
			
		||||
using namespace mlir;
 | 
			
		||||
using namespace mlir::ml_program;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
/// Tablegen Definitions
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
#include "mlir/Dialect/MLProgram/IR/MLProgramOpsDialect.cpp.inc"
 | 
			
		||||
#define GET_ATTRDEF_CLASSES
 | 
			
		||||
#include "mlir/Dialect/MLProgram/IR/MLProgramAttributes.cpp.inc"
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
struct MLProgramOpAsmDialectInterface : public OpAsmDialectInterface {
 | 
			
		||||
  using OpAsmDialectInterface::OpAsmDialectInterface;
 | 
			
		||||
 | 
			
		||||
  AliasResult getAlias(Attribute attr, raw_ostream &os) const override {
 | 
			
		||||
    if (attr.isa<ExternAttr>()) {
 | 
			
		||||
      os << "extern";
 | 
			
		||||
      return AliasResult::OverridableAlias;
 | 
			
		||||
    }
 | 
			
		||||
    return AliasResult::NoAlias;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
void ml_program::MLProgramDialect::initialize() {
 | 
			
		||||
#define GET_ATTRDEF_LIST
 | 
			
		||||
  addAttributes<
 | 
			
		||||
#include "mlir/Dialect/MLProgram/IR/MLProgramAttributes.cpp.inc"
 | 
			
		||||
      >();
 | 
			
		||||
  addOperations<
 | 
			
		||||
#define GET_OP_LIST
 | 
			
		||||
#include "mlir/Dialect/MLProgram/IR/MLProgramOps.cpp.inc"
 | 
			
		||||
      >();
 | 
			
		||||
  addInterfaces<MLProgramOpAsmDialectInterface>();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,69 @@
 | 
			
		|||
using namespace mlir;
 | 
			
		||||
using namespace mlir::ml_program;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
// Custom asm helpers
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
/// some.op custom<TypeOrAttr>($type, $attr)
 | 
			
		||||
///
 | 
			
		||||
/// Uninitialized:
 | 
			
		||||
///   some.op : tensor<3xi32>
 | 
			
		||||
/// Initialized to narrower type than op:
 | 
			
		||||
///   some.op (dense<0> : tensor<3xi32>) : tensor<?xi32>
 | 
			
		||||
static ParseResult parseTypedInitialValue(OpAsmParser &parser,
 | 
			
		||||
                                          TypeAttr &typeAttr, Attribute &attr) {
 | 
			
		||||
  if (succeeded(parser.parseOptionalLParen())) {
 | 
			
		||||
    if (failed(parser.parseAttribute(attr)))
 | 
			
		||||
      return failure();
 | 
			
		||||
    if (failed(parser.parseRParen()))
 | 
			
		||||
      return failure();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Type type;
 | 
			
		||||
  if (failed(parser.parseColonType(type)))
 | 
			
		||||
    return failure();
 | 
			
		||||
  typeAttr = TypeAttr::get(type);
 | 
			
		||||
  return success();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void printTypedInitialValue(OpAsmPrinter &p, Operation *op,
 | 
			
		||||
                                   TypeAttr type, Attribute attr) {
 | 
			
		||||
  if (attr) {
 | 
			
		||||
    p << "(";
 | 
			
		||||
    p.printAttribute(attr);
 | 
			
		||||
    p << ")";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  p << " : ";
 | 
			
		||||
  p.printAttribute(type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// some.op custom<SymbolVisibility>($sym_visibility) $sym_name
 | 
			
		||||
/// ->
 | 
			
		||||
/// some.op public @foo
 | 
			
		||||
/// some.op private @foo
 | 
			
		||||
static ParseResult parseSymbolVisibility(OpAsmParser &parser,
 | 
			
		||||
                                         StringAttr &symVisibilityAttr) {
 | 
			
		||||
  StringRef symVisibility;
 | 
			
		||||
  (void)parser.parseOptionalKeyword(&symVisibility,
 | 
			
		||||
                                    {"public", "private", "nested"});
 | 
			
		||||
  if (symVisibility.empty())
 | 
			
		||||
    return parser.emitError(parser.getCurrentLocation())
 | 
			
		||||
           << "expected 'public', 'private', or 'nested'";
 | 
			
		||||
  if (!symVisibility.empty())
 | 
			
		||||
    symVisibilityAttr = parser.getBuilder().getStringAttr(symVisibility);
 | 
			
		||||
  return success();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void printSymbolVisibility(OpAsmPrinter &p, Operation *op,
 | 
			
		||||
                                  StringAttr symVisibilityAttr) {
 | 
			
		||||
  if (!symVisibilityAttr)
 | 
			
		||||
    p << "public";
 | 
			
		||||
  else
 | 
			
		||||
    p << symVisibilityAttr.getValue();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
// TableGen'd op method definitions
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			@ -38,6 +101,43 @@ void FuncOp::print(OpAsmPrinter &p) {
 | 
			
		|||
  function_interface_impl::printFunctionOp(p, *this, /*isVariadic=*/false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
// GlobalOp
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
LogicalResult GlobalOp::verify() {
 | 
			
		||||
  if (!getIsMutable() && !getValue())
 | 
			
		||||
    return emitOpError() << "immutable global must have an initial value";
 | 
			
		||||
  return success();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
// GlobalLoadConstOp
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
GlobalOp GlobalLoadConstOp::getGlobalOp(SymbolTableCollection &symbolTable) {
 | 
			
		||||
  return symbolTable.lookupNearestSymbolFrom<GlobalOp>(
 | 
			
		||||
      getOperation()->getParentOp(), getGlobalAttr());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LogicalResult
 | 
			
		||||
GlobalLoadConstOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
 | 
			
		||||
  GlobalOp referrent = getGlobalOp(symbolTable);
 | 
			
		||||
  if (!referrent)
 | 
			
		||||
    return emitOpError() << "undefined global: " << getGlobal();
 | 
			
		||||
 | 
			
		||||
  if (referrent.getIsMutable())
 | 
			
		||||
    return emitOpError() << "cannot load as const from mutable global "
 | 
			
		||||
                         << getGlobal();
 | 
			
		||||
 | 
			
		||||
  if (referrent.getType() != getResult().getType())
 | 
			
		||||
    return emitOpError() << "cannot load from global typed "
 | 
			
		||||
                         << referrent.getType() << " as "
 | 
			
		||||
                         << getResult().getType();
 | 
			
		||||
 | 
			
		||||
  return success();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
// SubgraphOp
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
// RUN: mlir-opt %s --allow-unregistered-dialect | mlir-opt --allow-unregistered-dialect | FileCheck %s
 | 
			
		||||
 | 
			
		||||
// CHECK: #ml_program.extern : i32
 | 
			
		||||
"unregistered.attributes"() {
 | 
			
		||||
  value = #ml_program.extern : i32
 | 
			
		||||
} : () -> ()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,3 +31,30 @@ ml_program.subgraph @output_type_match(%arg0 : i64) -> i32 {
 | 
			
		|||
  // expected-error @+1 {{doesn't match function result}}
 | 
			
		||||
  ml_program.output %arg0 : i64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// -----
 | 
			
		||||
// expected-error @+1 {{immutable global must have an initial value}}
 | 
			
		||||
ml_program.global private @const : i32
 | 
			
		||||
 | 
			
		||||
// -----
 | 
			
		||||
ml_program.func @undef_global() -> i32 {
 | 
			
		||||
  // expected-error @+1 {{undefined global: nothere}}
 | 
			
		||||
  %0 = ml_program.global_load_const @nothere : i32
 | 
			
		||||
  ml_program.return %0 : i32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// -----
 | 
			
		||||
ml_program.global private mutable @var : i32
 | 
			
		||||
ml_program.func @mutable_const_load() -> i32 {
 | 
			
		||||
  // expected-error @+1 {{op cannot load as const from mutable global var}}
 | 
			
		||||
  %0 = ml_program.global_load_const @var : i32
 | 
			
		||||
  ml_program.return %0 : i32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// -----
 | 
			
		||||
ml_program.global private @var(42 : i64) : i64
 | 
			
		||||
ml_program.func @const_load_type_mismatch() -> i32 {
 | 
			
		||||
  // expected-error @+1 {{cannot load from global typed 'i64' as 'i32'}}
 | 
			
		||||
  %0 = ml_program.global_load_const @var : i32
 | 
			
		||||
  ml_program.return %0 : i32
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,3 +18,12 @@ ml_program.subgraph @compute_subgraph(%arg0 : i32) -> i32 {
 | 
			
		|||
  %0 = "unregistered.dummy"(%arg0) : (i32) -> i32
 | 
			
		||||
  ml_program.output %0 : i32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CHECK: ml_program.global private @global_same_type(dense<4> : tensor<4xi32>) : tensor<4xi32>
 | 
			
		||||
ml_program.global private @global_same_type(dense<4> : tensor<4xi32>) : tensor<4xi32>
 | 
			
		||||
 | 
			
		||||
// CHECK: ml_program.global private mutable @global_mutable_undef : tensor<?xi32>
 | 
			
		||||
ml_program.global private mutable @global_mutable_undef : tensor<?xi32>
 | 
			
		||||
 | 
			
		||||
// CHECK: ml_program.global private mutable @global_extern(#extern) : tensor<?xi32>
 | 
			
		||||
ml_program.global private mutable @global_extern(#ml_program.extern : tensor<4xi32>) : tensor<?xi32>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8560,6 +8560,7 @@ td_library(
 | 
			
		|||
    name = "MLProgramOpsTdFiles",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "include/mlir/Dialect/MLProgram/IR/MLProgramBase.td",
 | 
			
		||||
        "include/mlir/Dialect/MLProgram/IR/MLProgramAttributes.td",
 | 
			
		||||
        "include/mlir/Dialect/MLProgram/IR/MLProgramOps.td",
 | 
			
		||||
    ],
 | 
			
		||||
    includes = ["include"],
 | 
			
		||||
| 
						 | 
				
			
			@ -8599,6 +8600,24 @@ gentbl_cc_library(
 | 
			
		|||
    deps = [":MLProgramOpsTdFiles"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
gentbl_cc_library(
 | 
			
		||||
    name = "MLProgramAttributesIncGen",
 | 
			
		||||
    strip_include_prefix = "include",
 | 
			
		||||
    tbl_outs = [
 | 
			
		||||
        (
 | 
			
		||||
            ["-gen-attrdef-decls"],
 | 
			
		||||
            "include/mlir/Dialect/MLProgram/IR/MLProgramAttributes.h.inc",
 | 
			
		||||
        ),
 | 
			
		||||
        (
 | 
			
		||||
            ["-gen-attrdef-defs"],
 | 
			
		||||
            "include/mlir/Dialect/MLProgram/IR/MLProgramAttributes.cpp.inc",
 | 
			
		||||
        ),
 | 
			
		||||
    ],
 | 
			
		||||
    tblgen = ":mlir-tblgen",
 | 
			
		||||
    td_file = "include/mlir/Dialect/MLProgram/IR/MLProgramAttributes.td",
 | 
			
		||||
    deps = [":MLProgramOpsTdFiles"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_library(
 | 
			
		||||
    name = "MLProgramDialect",
 | 
			
		||||
    srcs = glob([
 | 
			
		||||
| 
						 | 
				
			
			@ -8612,6 +8631,7 @@ cc_library(
 | 
			
		|||
    deps = [
 | 
			
		||||
        ":ControlFlowInterfaces",
 | 
			
		||||
        ":IR",
 | 
			
		||||
        ":MLProgramAttributesIncGen",
 | 
			
		||||
        ":MLProgramOpsIncGen",
 | 
			
		||||
        ":Pass",
 | 
			
		||||
        ":Support",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue