Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ struct FunctionPathAndClusterInfo {
DenseMap<UniqueBBID, uint64_t> NodeCounts;
// Edge counts for each edge, stored as a nested map.
DenseMap<UniqueBBID, DenseMap<UniqueBBID, uint64_t>> EdgeCounts;
// Hash for each basic block. The Hashes are stored for every original block
// (not cloned blocks), hence the map key being unsigned instead of
// UniqueBBID.
DenseMap<unsigned, uint64_t> BBHashes;
};

class BasicBlockSectionsProfileReader {
Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,25 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
}
continue;
}
case 'h': { // Basic block hash secifier.
// Skip the profile when the profile iterator (FI) refers to the
// past-the-end element.
if (FI == ProgramPathAndClusterInfo.end())
continue;
for (auto BBIDHashStr : Values) {
auto [BBIDStr, HashStr] = BBIDHashStr.split(':');
unsigned long long BBID = 0, Hash = 0;
if (getAsUnsignedInteger(BBIDStr, 10, BBID))
return createProfileParseError(Twine("unsigned integer expected: '") +
BBIDStr + "'");
if (getAsUnsignedInteger(HashStr, 16, Hash))
return createProfileParseError(
Twine("unsigned integer expected in hex format: '") + HashStr +
"'");
FI->second.BBHashes[BBID] = Hash;
}
continue;
}
default:
return createProfileParseError(Twine("invalid specifier: '") +
Twine(Specifier) + "'");
Expand Down
51 changes: 51 additions & 0 deletions llvm/test/CodeGen/X86/basic-block-sections-bb-hash.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
; BB section test with basic block hashes.
;
; RUN: llc %s -O0 -mtriple=x86_64-pc-linux -function-sections -filetype=obj -basic-block-address-map -emit-bb-hash -o %t.o
; RUN: obj2yaml %t.o -o %t.yaml
;
;; Profile for version 1:
; RUN: echo 'v1' > %t
; RUN: echo 'f foo' >> %t
; RUN: echo 'g 0:10,1:9,2:1 1:8,3:8 2:2,3:2 3:11' >> %t
; RUN: echo 'c 0 2 3' >> %t

; These commands read BB hashes from SHT_LLVM_BB_ADDR_MAP
; and put them into the basic blocks sections profile.
; RUN: grep -E '^\s+(- ID:|Hash:)' %t.yaml | \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please explain these commands with a comment? Looks like it's reading the SHT_LLVM_BB_ADDR_MAP for hashes and then putting them into the basic blocks sections profile.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. We have added the comment.

; RUN: grep -B1 'Hash:' | \
; RUN: sed 's/^\s*//; s/^- ID: *//; s/Hash: *0x//' | \
; RUN: paste -d: - - | \
; RUN: tr '\n' ' ' | \
; RUN: sed 's/ $/\n/; s/^/h /' >> %t
;
; RUN: llc < %s -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t | FileCheck %s
;
define void @foo(i1 zeroext) nounwind {
%2 = alloca i8, align 1
%3 = zext i1 %0 to i8
store i8 %3, ptr %2, align 1
%4 = load i8, ptr %2, align 1
%5 = trunc i8 %4 to i1
br i1 %5, label %6, label %8

6: ; preds = %1
%7 = call i32 @bar()
br label %10

8: ; preds = %1
%9 = call i32 @baz()
br label %10

10: ; preds = %8, %6
ret void
}

declare i32 @bar() #1

declare i32 @baz() #1

; CHECK: .section .text.foo,"ax",@progbits
; CHECK: callq baz
; CHECK: retq
; CHECK: .section .text.split.foo,"ax",@progbits
; CHECK: callq bar
14 changes: 14 additions & 0 deletions llvm/test/CodeGen/X86/basic-block-sections-clusters-error.ll
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@
; RUN: echo 'g 0:4,1:2:3' >> %t15
; RUN: not --crash llc < %s -O0 -mtriple=x86_64 -function-sections -basic-block-sections=%t15 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR15
; CHECK-ERROR15: LLVM ERROR: invalid profile {{.*}} at line 4: unsigned integer expected: '2:3'
; RUN: echo 'v1' > %t16
; RUN: echo 'f dummy1' >> %t16
; RUN: echo 'c 0 1' >> %t16
; RUN: echo 'g 0:4,1:2' >> %t16
; RUN: echo 'h a:1111111111111111 1:ffffffffffffffff' >> %t16
; RUN: not --crash llc < %s -O0 -mtriple=x86_64 -function-sections -basic-block-sections=%t16 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR16
; CHECK-ERROR16: LLVM ERROR: invalid profile {{.*}} at line 5: unsigned integer expected: 'a'
; RUN: echo 'v1' > %t17
; RUN: echo 'f dummy1' >> %t17
; RUN: echo 'c 0 1' >> %t17
; RUN: echo 'g 0:4,1:2' >> %t17
; RUN: echo 'h 0:111111111111111g 1:ffffffffffffffff' >> %t17
; RUN: not --crash llc < %s -O0 -mtriple=x86_64 -function-sections -basic-block-sections=%t17 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR17
; CHECK-ERROR17: LLVM ERROR: invalid profile {{.*}} at line 5: unsigned integer expected in hex format: '111111111111111g'


define i32 @dummy1(i32 %x, i32 %y, i32 %z) {
Expand Down