| // RUN: iree-compile %s --iree-execution-model=host-only | custom-module-basic-run - example.main | FileCheck %s | |
| module @example { | |
| //===--------------------------------------------------------------------===// | |
| // Imports | |
| //===--------------------------------------------------------------------===// | |
| // External function declarations for the methods implemented in the custom | |
| // module C++ file. Note that they are prefixed with the `custom.` module | |
| // name. | |
| // Creates a new string with a copy of the given string data. | |
| // No NUL terminator is required. | |
| func.func private @custom.string.create(!util.buffer) -> !custom.string | |
| // Returns the length of the string in characters. | |
| func.func private @custom.string.length(!custom.string) -> index attributes { | |
| // Explicitly force the returned type to be i64 regardless of whether the | |
| // VM is in 32 or 64 bit mode and what conversion would make index. | |
| vm.signature = (!vm.ref<!custom.string>) -> i64 | |
| } | |
| // Prints the contents of the string to stdout. | |
| func.func private @custom.string.print(!custom.string) | |
| // Prints the contents of the string only in debug mode and otherwise prints | |
| // "optimized". | |
| func.func private @custom.string.dprint(!custom.string) attributes { | |
| // Indicates the import is optional and if not present the specified | |
| // fallback method will be called instead. | |
| vm.fallback = @custom_string_dprint | |
| } | |
| func.func private @custom_string_dprint(%ignored: !custom.string) { | |
| // Called when the import is not available at runtime (in this case when the | |
| // runtime is compiled in release mode). This is a silly example but makes | |
| // it easier to test. | |
| %data = util.buffer.constant : !util.buffer = "optimized" | |
| %str = call @custom.string.create(%data) : (!util.buffer) -> !custom.string | |
| call @custom.string.print(%str) : (!custom.string) -> () | |
| return | |
| } | |
| //===--------------------------------------------------------------------===// | |
| // Sample methods | |
| //===--------------------------------------------------------------------===// | |
| // Note that there can be any number of publicly-exported methods; this simple | |
| // sample just has one to keep things simple. | |
| // CHECK-LABEL: INVOKE BEGIN example.main | |
| func.func @main() { | |
| // Create string from a byte buffer encoding the characters. | |
| %hello_data = util.buffer.constant : !util.buffer = "hello" | |
| // CHECK-NEXT: CREATE hello | |
| %hello_str = call @custom.string.create(%hello_data) : (!util.buffer) -> !custom.string | |
| // Print the string to stdout. | |
| // CHECK-NEXT: PRINT hello | |
| call @custom.string.print(%hello_str) : (!custom.string) -> () | |
| // Query the length of the string. | |
| // We don't do anything with it here but just demonstrate how index works. | |
| // CHECK-NEXT: LENGTH hello = 5 | |
| %strlen = call @custom.string.length(%hello_str) : (!custom.string) -> index | |
| util.optimization_barrier %strlen : index | |
| // Print "debug" if the runtime is compiled in debug mode and otherwise | |
| // prints "optimized". | |
| // CHECK: PRINT {{debug|optimized}} | |
| %debug_data = util.buffer.constant : !util.buffer = "debug" | |
| %debug_str = call @custom.string.create(%debug_data) : (!util.buffer) -> !custom.string | |
| call @custom.string.dprint(%debug_str) : (!custom.string) -> () | |
| return | |
| } | |
| // CHECK-NEXT: INVOKE END | |
| } |