|  | // 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 | 
|  | } |