llvm-project/llvm/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll

94 lines
2.1 KiB
LLVM
Raw Normal View History

; RUN: opt -mergefunc -S < %s | FileCheck %s
define i8 @call_with_range() {
bitcast i8 0 to i8 ; dummy to make the function large enough
%out = call i8 @dummy(), !range !0
ret i8 %out
}
define i8 @call_no_range() {
; CHECK-LABEL: @call_no_range
; CHECK-NEXT: bitcast i8 0 to i8
; CHECK-NEXT: %out = call i8 @dummy()
; CHECK-NEXT: ret i8 %out
bitcast i8 0 to i8
%out = call i8 @dummy()
ret i8 %out
}
define i8 @call_different_range() {
; CHECK-LABEL: @call_different_range
; CHECK-NEXT: bitcast i8 0 to i8
; CHECK-NEXT: %out = call i8 @dummy(), !range !1
; CHECK-NEXT: ret i8 %out
bitcast i8 0 to i8
%out = call i8 @dummy(), !range !1
ret i8 %out
}
define i8 @invoke_with_range() personality i8* undef {
%out = invoke i8 @dummy() to label %next unwind label %lpad, !range !0
next:
ret i8 %out
lpad:
%pad = landingpad { i8*, i32 } cleanup
resume { i8*, i32 } zeroinitializer
}
define i8 @invoke_no_range() personality i8* undef {
; CHECK-LABEL: @invoke_no_range()
; CHECK-NEXT: invoke i8 @dummy
%out = invoke i8 @dummy() to label %next unwind label %lpad
next:
ret i8 %out
lpad:
%pad = landingpad { i8*, i32 } cleanup
resume { i8*, i32 } zeroinitializer
}
define i8 @invoke_different_range() personality i8* undef {
; CHECK-LABEL: @invoke_different_range()
; CHECK-NEXT: invoke i8 @dummy
%out = invoke i8 @dummy() to label %next unwind label %lpad, !range !1
next:
ret i8 %out
lpad:
%pad = landingpad { i8*, i32 } cleanup
resume { i8*, i32 } zeroinitializer
}
define i8 @invoke_with_same_range() personality i8* undef {
; CHECK-LABEL: @invoke_with_same_range()
; CHECK: tail call i8 @invoke_with_range()
%out = invoke i8 @dummy() to label %next unwind label %lpad, !range !0
next:
ret i8 %out
lpad:
%pad = landingpad { i8*, i32 } cleanup
resume { i8*, i32 } zeroinitializer
}
define i8 @call_with_same_range() {
; CHECK-LABEL: @call_with_same_range
; CHECK: tail call i8 @call_with_range
bitcast i8 0 to i8
%out = call i8 @dummy(), !range !0
ret i8 %out
}
Accelerate MergeFunctions with hashing This patch makes the Merge Functions pass faster by calculating and comparing a hash value which captures the essential structure of a function before performing a full function comparison. The hash is calculated by hashing the function signature, then walking the basic blocks of the function in the same order as the main comparison function. The opcode of each instruction is hashed in sequence, which means that different functions according to the existing total order cannot have the same hash, as the comparison requires the opcodes of the two functions to be the same order. The hash function is a static member of the FunctionComparator class because it is tightly coupled to the exact comparison function used. For example, functions which are equivalent modulo a single variant callsite might be merged by a more aggressive MergeFunctions, and the hash function would need to be insensitive to these differences in order to exploit this. The hashing function uses a utility class which accumulates the values into an internal state using a standard bit-mixing function. Note that this is a different interface than a regular hashing routine, because the values to be hashed are scattered amongst the properties of a llvm::Function, not linear in memory. This scheme is fast because only one word of state needs to be kept, and the mixing function is a few instructions. The main runOnModule function first computes the hash of each function, and only further processes functions which do not have a unique function hash. The hash is also used to order the sorted function set. If the hashes differ, their values are used to order the functions, otherwise the full comparison is done. Both of these are helpful in speeding up MergeFunctions. Together they result in speedups of 9% for mysqld (a mostly C application with little redundancy), 46% for libxul in Firefox, and 117% for Chromium. (These are all LTO builds.) In all three cases, the new speed of MergeFunctions is about half that of the module verifier, making it relatively inexpensive even for large LTO builds with hundreds of thousands of functions. The same functions are merged, so this change is free performance. Author: jrkoenig Reviewers: nlewycky, dschuff, jfb Subscribers: llvm-commits, aemerson Differential revision: http://reviews.llvm.org/D11923 llvm-svn: 245140
2015-08-15 09:18:18 +08:00
declare i8 @dummy();
declare i32 @__gxx_personality_v0(...)
IR: Make metadata typeless in assembly Now that `Metadata` is typeless, reflect that in the assembly. These are the matching assembly changes for the metadata/value split in r223802. - Only use the `metadata` type when referencing metadata from a call intrinsic -- i.e., only when it's used as a `Value`. - Stop pretending that `ValueAsMetadata` is wrapped in an `MDNode` when referencing it from call intrinsics. So, assembly like this: define @foo(i32 %v) { call void @llvm.foo(metadata !{i32 %v}, metadata !0) call void @llvm.foo(metadata !{i32 7}, metadata !0) call void @llvm.foo(metadata !1, metadata !0) call void @llvm.foo(metadata !3, metadata !0) call void @llvm.foo(metadata !{metadata !3}, metadata !0) ret void, !bar !2 } !0 = metadata !{metadata !2} !1 = metadata !{i32* @global} !2 = metadata !{metadata !3} !3 = metadata !{} turns into this: define @foo(i32 %v) { call void @llvm.foo(metadata i32 %v, metadata !0) call void @llvm.foo(metadata i32 7, metadata !0) call void @llvm.foo(metadata i32* @global, metadata !0) call void @llvm.foo(metadata !3, metadata !0) call void @llvm.foo(metadata !{!3}, metadata !0) ret void, !bar !2 } !0 = !{!2} !1 = !{i32* @global} !2 = !{!3} !3 = !{} I wrote an upgrade script that handled almost all of the tests in llvm and many of the tests in cfe (even handling many `CHECK` lines). I've attached it (or will attach it in a moment if you're speedy) to PR21532 to help everyone update their out-of-tree testcases. This is part of PR21532. llvm-svn: 224257
2014-12-16 03:07:53 +08:00
!0 = !{i8 0, i8 2}
!1 = !{i8 5, i8 7}