LogicalResult ForOp::moveOutOfLoop(ArrayRef<Operation *> ops) {
for (auto op : ops)
- op->moveBefore(this->getOperation());
+ op->moveBefore(*this);
return success();
}
if (!ivArg)
return ForOp();
assert(ivArg.getOwner() && "unlinked block argument");
- auto *containingInst = ivArg.getOwner()->getParentOp();
- return dyn_cast_or_null<ForOp>(containingInst);
+ auto *containingOp = ivArg.getOwner()->getParentOp();
+ return dyn_cast_or_null<ForOp>(containingOp);
}
//===----------------------------------------------------------------------===//
op.getAttrs(), /*elidedAttrs=*/ParallelOp::getOperandSegmentSizeAttr());
}
+Region &ParallelOp::getLoopBody() { return region(); }
+
+bool ParallelOp::isDefinedOutsideOfLoop(Value value) {
+ return !region().isAncestor(value.getParentRegion());
+}
+
+LogicalResult ParallelOp::moveOutOfLoop(ArrayRef<Operation *> ops) {
+ for (auto op : ops)
+ op->moveBefore(*this);
+ return success();
+}
+
ParallelOp mlir::loop::getParallelForInductionVarOwner(Value val) {
auto ivArg = val.dyn_cast<BlockArgument>();
if (!ivArg)
return ParallelOp();
assert(ivArg.getOwner() && "unlinked block argument");
- auto *containingInst = ivArg.getOwner()->getParentOp();
- return dyn_cast<ParallelOp>(containingInst);
+ auto *containingOp = ivArg.getOwner()->getParentOp();
+ return dyn_cast<ParallelOp>(containingOp);
}
//===----------------------------------------------------------------------===//
-// RUN: mlir-opt %s -loop-invariant-code-motion -split-input-file | FileCheck %s
+// RUN: mlir-opt %s -split-input-file -loop-invariant-code-motion | FileCheck %s
func @nested_loops_both_having_invariant_code() {
%m = alloc() : memref<10xf32>
return
}
+// -----
+
func @nested_loops_code_invariant_to_both() {
%m = alloc() : memref<10xf32>
%cf7 = constant 7.0 : f32
return
}
+// -----
+
func @single_loop_nothing_invariant() {
%m1 = alloc() : memref<10xf32>
%m2 = alloc() : memref<10xf32>
return
}
+// -----
+
func @invariant_code_inside_affine_if() {
%m = alloc() : memref<10xf32>
%cf8 = constant 8.0 : f32
// CHECK: %0 = alloc() : memref<10xf32>
// CHECK-NEXT: %cst = constant 8.000000e+00 : f32
// CHECK-NEXT: affine.for %arg0 = 0 to 10 {
- // CHECK-NEXT: %1 = affine.apply #map3(%arg0)
+ // CHECK-NEXT: %1 = affine.apply #map0(%arg0)
// CHECK-NEXT: affine.if #set0(%arg0, %1) {
// CHECK-NEXT: %2 = addf %cst, %cst : f32
// CHECK-NEXT: affine.store %2, %0[%arg0] : memref<10xf32>
return
}
+// -----
+
func @invariant_affine_if() {
%m = alloc() : memref<10xf32>
%cf8 = constant 8.0 : f32
return
}
+// -----
+
func @invariant_affine_if2() {
%m = alloc() : memref<10xf32>
%cf8 = constant 8.0 : f32
return
}
+// -----
+
func @invariant_affine_nested_if() {
%m = alloc() : memref<10xf32>
%cf8 = constant 8.0 : f32
return
}
+// -----
+
func @invariant_affine_nested_if_else() {
%m = alloc() : memref<10xf32>
%cf8 = constant 8.0 : f32
return
}
+// -----
+
func @invariant_loop_dialect() {
%ci0 = constant 0 : index
%ci10 = constant 10 : index
return
}
+// -----
+
func @variant_loop_dialect() {
%ci0 = constant 0 : index
%ci10 = constant 10 : index
return
}
+
+// -----
+
+func @parallel_loop_with_invariant() {
+ %c0 = constant 0 : index
+ %c10 = constant 10 : index
+ %c1 = constant 1 : index
+ %c7 = constant 7 : i32
+ %c8 = constant 8 : i32
+ loop.parallel (%arg0, %arg1) = (%c0, %c0) to (%c10, %c10) step (%c1, %c1) {
+ %v0 = addi %c7, %c8 : i32
+ %v3 = addi %arg0, %arg1 : index
+ }
+
+ // CHECK-LABEL: func @parallel_loop_with_invariant
+ // CHECK: %c0 = constant 0 : index
+ // CHECK-NEXT: %c10 = constant 10 : index
+ // CHECK-NEXT: %c1 = constant 1 : index
+ // CHECK-NEXT: %c7_i32 = constant 7 : i32
+ // CHECK-NEXT: %c8_i32 = constant 8 : i32
+ // CHECK-NEXT: addi %c7_i32, %c8_i32 : i32
+ // CHECK-NEXT: loop.parallel (%arg0, %arg1) = (%c0, %c0) to (%c10, %c10) step (%c1, %c1)
+ // CHECK-NEXT: addi %arg0, %arg1 : index
+ // CHECK-NEXT: yield
+ // CHECK-NEXT: }
+ // CHECK-NEXT: return
+
+ return
+}
+