Skip to content

Commit 8631b4f

Browse files
authored
[flang] Set low probability for array repacking code. (#144830)
This allows LLVM to place the most probably cold blocks that do the repacking out of the line of the potentially hot code.
1 parent baf35d7 commit 8631b4f

File tree

4 files changed

+92
-46
lines changed

4 files changed

+92
-46
lines changed

flang/include/flang/Optimizer/Dialect/FIROps.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2381,6 +2381,16 @@ def fir_IfOp
23812381
static constexpr llvm::StringRef getWeightsAttrAssemblyName() {
23822382
return "weights";
23832383
}
2384+
2385+
/// Sets WeightedRegionBranchOpInterface weights to indicate
2386+
/// that either THEN or ELSE branch is unlikely.
2387+
/// By default, THEN branch is set to be unlikely.
2388+
void setUnlikelyIfWeights(bool unlikelyElse = false) {
2389+
if (unlikelyElse)
2390+
setWeights({1, 0});
2391+
else
2392+
setWeights({0, 1});
2393+
}
23842394
}];
23852395
}
23862396

flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ PackArrayConversion::genRepackedBox(fir::FirOpBuilder &builder,
250250

251251
fir::IfOp ifOp =
252252
builder.create<fir::IfOp>(loc, boxType, doPack, /*withElseRegion=*/true);
253+
// Assume that the repacking is unlikely.
254+
ifOp.setUnlikelyIfWeights();
253255

254256
// Return original box.
255257
builder.setInsertionPointToStart(&ifOp.getElseRegion().front());
@@ -322,20 +324,24 @@ UnpackArrayConversion::matchAndRewrite(fir::UnpackArrayOp op,
322324

323325
auto isNotSame = builder.genPtrCompare(loc, mlir::arith::CmpIPredicate::ne,
324326
tempAddr, originalAddr);
325-
builder.genIfThen(loc, isNotSame).genThen([&]() {});
326-
// Copy from temporary to the original.
327-
if (!op.getNoCopy())
328-
fir::runtime::genShallowCopy(builder, loc, originalBox, tempBox,
329-
/*resultIsAllocated=*/true);
330-
331-
// Deallocate, if it was allocated in heap.
332-
// Note that the stack attribute does not always mean
333-
// that the allocation was actually done in stack memory.
334-
// There are currently cases where we delegate the allocation
335-
// to the runtime that uses heap memory, even when the stack
336-
// attribute is set on fir.pack_array.
337-
if (!op.getStack() || !canAllocateTempOnStack(originalBox))
338-
builder.create<fir::FreeMemOp>(loc, tempAddr);
327+
builder.genIfThen(loc, isNotSame)
328+
.genThen([&]() {
329+
// Copy from temporary to the original.
330+
if (!op.getNoCopy())
331+
fir::runtime::genShallowCopy(builder, loc, originalBox, tempBox,
332+
/*resultIsAllocated=*/true);
333+
334+
// Deallocate, if it was allocated in heap.
335+
// Note that the stack attribute does not always mean
336+
// that the allocation was actually done in stack memory.
337+
// There are currently cases where we delegate the allocation
338+
// to the runtime that uses heap memory, even when the stack
339+
// attribute is set on fir.pack_array.
340+
if (!op.getStack() || !canAllocateTempOnStack(originalBox))
341+
builder.create<fir::FreeMemOp>(loc, tempAddr);
342+
})
343+
.getIfOp()
344+
.setUnlikelyIfWeights();
339345
});
340346
rewriter.eraseOp(op);
341347
return mlir::success();
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
! Check that the branch weights used by the array repacking
2+
! are propagated all the way to LLVM IR:
3+
! RUN: %flang_fc1 -frepack-arrays -emit-llvm %s -o - | FileCheck %s
4+
5+
! CHECK-LABEL: define void @test_(
6+
! CHECK-SAME: ptr [[TMP0:%.*]]) {
7+
! CHECK: [[TMP4:%.*]] = ptrtoint ptr [[TMP0]] to i64
8+
! CHECK: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
9+
! CHECK: br i1 [[TMP5]], label %[[BB6:.*]], label %[[BB46:.*]]
10+
! CHECK: [[BB6]]:
11+
! CHECK: [[TMP7:%.*]] = call i1 @_FortranAIsContiguous(ptr [[TMP0]])
12+
! CHECK: [[TMP8:%.*]] = icmp eq i1 [[TMP7]], false
13+
! CHECK: [[TMP13:%.*]] = and i1 [[TMP8]], [[TMP12:.*]]
14+
! CHECK: br i1 [[TMP13]], label %[[BB14:.*]], label %[[BB46]], !prof [[PROF2:![0-9]+]]
15+
! CHECK: [[BB14]]:
16+
! CHECK: call void @_FortranAShallowCopyDirect
17+
! CHECK: br label %[[BB46]]
18+
! CHECK: [[BB46]]:
19+
! CHECK: br i1 [[TMP5]], label %[[BB48:.*]], label %[[BB57:.*]]
20+
! CHECK: [[BB48]]:
21+
! CHECK: br i1 [[TMP55:.*]], label %[[BB56:.*]], label %[[BB57]], !prof [[PROF2]]
22+
! CHECK: [[BB56]]:
23+
! CHECK: call void @_FortranAShallowCopyDirect
24+
! CHECK: br label %[[BB57]]
25+
! CHECK: [[BB57]]:
26+
! CHECK: ret void
27+
! CHECK: [[PROF2]] = !{!"branch_weights", i32 0, i32 1}
28+
subroutine test(x)
29+
real :: x(:)
30+
end subroutine test

0 commit comments

Comments
 (0)