blob: 14d3565bc0c9fb312d6ffa2818470247eaabff02 [file] [log] [blame] [edit]
// RUN: %eopt --print-activity-analysis --split-input-file %s 2>&1 | FileCheck %s
// CHECK-LABEL: @callgraph_sparse:
// CHECK: "callres": Active
func.func private @mysquare(%arg0: f64) -> f64 {
%mul = arith.mulf %arg0, %arg0 : f64
return %mul : f64
}
func.func @callgraph_sparse(%arg0: f64) -> f64 {
%squared = call @mysquare(%arg0) {tag = "callres"} : (f64) -> f64
return %squared : f64
}
// -----
func.func private @noop(%arg0: memref<f64>) {
return
}
// CHECK-LABEL: @callgraph_dense:
// CHECK: "sin": Active
func.func @callgraph_dense(%arg0: f64) -> f64 {
%m = memref.alloc() : memref<f64>
memref.store %arg0, %m[] : memref<f64>
call @noop(%m) : (memref<f64>) -> ()
%loaded = memref.load %m[] : memref<f64>
%sin = math.sin %loaded {tag = "sin"} : f64
return %sin : f64
}
// -----
func.func private @identity(%arg0: memref<f64>) -> memref<f64> {
%space = memref.alloc() : memref<memref<f64>>
memref.store %arg0, %space[] : memref<memref<f64>>
%loaded = memref.load %space[] : memref<memref<f64>>
memref.dealloc %space : memref<memref<f64>>
return %loaded : memref<f64>
}
// CHECK-LABEL: @aliased_store:
// CHECK: "retval": Active
func.func @aliased_store(%arg0: f64) -> f64 {
%ptr = memref.alloc() : memref<f64>
memref.store %arg0, %ptr[] : memref<f64>
%new_ptr = call @identity(%ptr) : (memref<f64>) -> memref<f64>
%val = memref.load %new_ptr[] {tag = "retval"} : memref<f64>
return %val : f64
}
// -----
func.func private @write(%arg0: f64, %ptr: memref<f64>) {
memref.store %arg0, %ptr[] : memref<f64>
return
}
func.func private @read(%ptr: memref<f64>) -> f64 {
%val = memref.load %ptr[] : memref<f64>
return %val : f64
}
// CHECK-LABEL: @across_func_boundaries
// CHECK: "retval": Active
func.func @across_func_boundaries(%arg0: f64) -> f64 {
%ptr = memref.alloc() : memref<f64>
call @write(%arg0, %ptr) : (f64, memref<f64>) -> ()
%val = call @read(%ptr) {tag = "retval"} : (memref<f64>) -> f64
return %val : f64
}
func.func private @no_write(%arg0: f64, %ptr: memref<f64>) {
%cst = arith.constant 3.0 : f64
memref.store %cst, %ptr[] : memref<f64>
return
}
// CHECK-LABEL: @across_func_boundaries_const
// CHECK: "retval": Constant
func.func @across_func_boundaries_const(%arg0: f64) -> f64 {
%ptr = memref.alloc() : memref<f64>
call @no_write(%arg0, %ptr) : (f64, memref<f64>) -> ()
%val = call @read(%ptr) {tag = "retval"} : (memref<f64>) -> f64
return %val : f64
}
// -----
// Like across_func_boundaries_const, but in the LLVM dialect
llvm.func private @identity(%arg0: !llvm.ptr) -> !llvm.ptr attributes {} {
%c4 = llvm.mlir.constant (4) : i64
%mem = memref.alloc() : memref<f32>
%nonaliasidx = memref.extract_aligned_pointer_as_index %mem : memref<f32> -> index
%nonaliasi64 = arith.index_cast %nonaliasidx : index to i64
%nonalias = llvm.inttoptr %nonaliasi64 : i64 to !llvm.ptr
%inner = llvm.mlir.constant (4.5 : f32) : f32
llvm.store %inner, %nonalias : f32, !llvm.ptr
llvm.return %nonalias : !llvm.ptr
}
// CHECK-LABEL: @nonaliased_store:
// CHECK: "retval": Constant
func.func @nonaliased_store(%arg0: f32) -> f32 {
%c1 = llvm.mlir.constant (1) : i64
%ptr = llvm.alloca %c1 x f32 : (i64) -> !llvm.ptr
llvm.store %arg0, %ptr : f32, !llvm.ptr
%new_ptr = llvm.call @identity(%ptr) : (!llvm.ptr) -> !llvm.ptr
%val = llvm.load %new_ptr {tag = "retval"} : !llvm.ptr -> f32
return %val : f32
}