From ff2b0ce413ded6084e87cd7fbd989dc8c32f2d33 Mon Sep 17 00:00:00 2001 From: DokFaust Date: Sun, 12 Aug 2018 13:23:48 +0200 Subject: [PATCH 001/110] Hooked GDB to JITEventlistener, cleaned up jitlayers interface --- src/codegen.cpp | 5 +++ src/jitlayers.cpp | 95 ++--------------------------------------------- src/jitlayers.h | 2 - 3 files changed, 9 insertions(+), 93 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 1290d3a5992f8..fdfd9bebca3a3 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7471,6 +7471,11 @@ extern "C" void *jl_init_llvm(void) jl_data_layout.reset(DL); #endif +// Register GDB event listener +#ifdef JL_DEBUG_BUILD + jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createGDBRegistrationListener()); +#endif + #ifdef JL_USE_INTEL_JITEVENTS if (jl_using_intel_jitevents) jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createIntelJITEventListener()); diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 4be2ef0c71d65..1a5a02f670b50 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -54,7 +54,6 @@ namespace llvm { #include #include - #include #include #include @@ -284,72 +283,6 @@ void jl_add_optimization_passes(LLVMPassManagerRef PM, int opt_level) { addOptimizationPasses(unwrap(PM), opt_level); } -// ------------------------ TEMPORARILY COPIED FROM LLVM ----------------- -// This must be kept in sync with gdb/gdb/jit.h . -extern "C" { - - typedef enum { - JIT_NOACTION = 0, - JIT_REGISTER_FN, - JIT_UNREGISTER_FN - } jit_actions_t; - - struct jit_code_entry { - struct jit_code_entry *next_entry; - struct jit_code_entry *prev_entry; - const char *symfile_addr; - uint64_t symfile_size; - }; - - struct jit_descriptor { - uint32_t version; - // This should be jit_actions_t, but we want to be specific about the - // bit-width. - uint32_t action_flag; - struct jit_code_entry *relevant_entry; - struct jit_code_entry *first_entry; - }; - - // We put information about the JITed function in this global, which the - // debugger reads. Make sure to specify the version statically, because the - // debugger checks the version before we can set it during runtime. - extern struct jit_descriptor __jit_debug_descriptor; - - LLVM_ATTRIBUTE_NOINLINE extern void __jit_debug_register_code(); -} - -namespace { - -// Use a local variable to hold the addresses to avoid generating a PLT -// on the function call. -// It messes up the GDB lookup logic with dynamically linked LLVM. -// (Ref https://sourceware.org/bugzilla/show_bug.cgi?id=20633) -// Use `volatile` to make sure the call always loads this slot. -void (*volatile jit_debug_register_code)() = __jit_debug_register_code; - -using namespace llvm; -using namespace llvm::object; -using namespace llvm::orc; - -/// Do the registration. -void NotifyDebugger(jit_code_entry *JITCodeEntry) -{ - __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; - - // Insert this entry at the head of the list. - JITCodeEntry->prev_entry = nullptr; - jit_code_entry *NextEntry = __jit_debug_descriptor.first_entry; - JITCodeEntry->next_entry = NextEntry; - if (NextEntry) { - NextEntry->prev_entry = JITCodeEntry; - } - __jit_debug_descriptor.first_entry = JITCodeEntry; - __jit_debug_descriptor.relevant_entry = JITCodeEntry; - jit_debug_register_code(); -} -} -// ------------------------ END OF TEMPORARY COPY FROM LLVM ----------------- - #if defined(_OS_LINUX_) || defined(_OS_WINDOWS_) || defined(_OS_FREEBSD_) // Resolve non-lock free atomic functions in the libatomic1 library. // This is the library that provides support for c11/c++11 atomic operations. @@ -387,7 +320,7 @@ template void JuliaOJIT::DebugObjectRegistrar::registerObject(RTDyldObjHandleT H, const ObjT &Object, const LoadResult &LO) { - OwningBinary SavedObject = LO->getObjectForDebug(*Object); + object::OwningBinary SavedObject = LO->getObjectForDebug(*Object); // If the debug object is unavailable, save (a copy of) the original object // for our backtraces @@ -396,16 +329,15 @@ void JuliaOJIT::DebugObjectRegistrar::registerObject(RTDyldObjHandleT H, const O // ownership of the original buffer auto NewBuffer = MemoryBuffer::getMemBufferCopy(Object->getData(), Object->getFileName()); - auto NewObj = ObjectFile::createObjectFile(NewBuffer->getMemBufferRef()); + auto NewObj = object::ObjectFile::createObjectFile(NewBuffer->getMemBufferRef()); assert(NewObj); - SavedObject = OwningBinary(std::move(*NewObj), + SavedObject = object::OwningBinary(std::move(*NewObj), std::move(NewBuffer)); } else { - NotifyGDB(SavedObject); + JIT.NotifyFinalizer(*(SavedObject.getBinary()), *LO); } - JIT.NotifyFinalizer(*Object, *LO); SavedObjects.push_back(std::move(SavedObject)); ORCNotifyObjectEmitted(JuliaListener.get(), *Object, @@ -436,7 +368,6 @@ void JuliaOJIT::DebugObjectRegistrar::registerObject(RTDyldObjHandleT H, const O } } -// TODO: hook up RegisterJITEventListener, instead of hard-coding the GDB and JuliaListener targets template void JuliaOJIT::DebugObjectRegistrar::operator()(RTDyldObjHandleT H, const ObjSetT &Objects, const LoadResult &LOS) @@ -456,24 +387,6 @@ void JuliaOJIT::DebugObjectRegistrar::operator()(RTDyldObjHandleT H, #endif } -void JuliaOJIT::DebugObjectRegistrar::NotifyGDB(OwningBinary &DebugObj) -{ - const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart(); - size_t Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize(); - - assert(Buffer && "Attempt to register a null object with a debugger."); - jit_code_entry *JITCodeEntry = new jit_code_entry(); - - if (!JITCodeEntry) { - jl_printf(JL_STDERR, "WARNING: Allocation failed when registering a JIT entry!\n"); - } - else { - JITCodeEntry->symfile_addr = Buffer; - JITCodeEntry->symfile_size = Size; - - NotifyDebugger(JITCodeEntry); - } -} object::OwningBinary JuliaOJIT::CompilerT::operator()(Module &M) { diff --git a/src/jitlayers.h b/src/jitlayers.h index aadda5d534cfb..6696a69088d90 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -103,7 +103,6 @@ using RTDyldObjHandleT = orc::ObjectLinkingLayerBase::ObjSetHandleT; class JuliaOJIT { // Custom object emission notification handler for the JuliaOJIT - // TODO: hook up RegisterJITEventListener, instead of hard-coding the GDB and JuliaListener targets class DebugObjectRegistrar { public: DebugObjectRegistrar(JuliaOJIT &JIT); @@ -112,7 +111,6 @@ class JuliaOJIT { private: template void registerObject(RTDyldObjHandleT H, const ObjT &Object, const LoadResult &LO); - void NotifyGDB(object::OwningBinary &DebugObj); std::vector> SavedObjects; std::unique_ptr JuliaListener; JuliaOJIT &JIT; From d15b0912fe092e3256fc03e48e5ecea1bce7b33a Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Mon, 13 Aug 2018 09:16:08 -0400 Subject: [PATCH 002/110] Doc IndexLinear and IndexCartesian (#28476) * Doc IndexLinear and IndexCartesian --- base/cartesian.jl | 2 +- base/indices.jl | 33 +++++++++++++++++++++++++++++---- base/iterators.jl | 6 +++--- doc/src/base/arrays.md | 2 ++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/base/cartesian.jl b/base/cartesian.jl index 526cff67bd706..865b766664708 100644 --- a/base/cartesian.jl +++ b/base/cartesian.jl @@ -32,7 +32,7 @@ would generate: end end -If you want just a post-expression, supply `nothing` for the pre-expression. Using +If you want just a post-expression, supply [`nothing`](@ref) for the pre-expression. Using parentheses and semicolons, you can supply multi-statement expressions. """ macro nloops(N, itersym, rangeexpr, args...) diff --git a/base/indices.jl b/base/indices.jl index adec164f080b5..800280c90f57e 100644 --- a/base/indices.jl +++ b/base/indices.jl @@ -13,7 +13,32 @@ Indices{N} = NTuple{N,AbstractUnitRange} ## Traits for array types ## abstract type IndexStyle end +""" + IndexLinear() + +Subtype of [`IndexStyle`](@ref) used to describe arrays which +are optimally indexed by one linear index. + +A linear indexing style uses one integer to describe the position in the array +(even if it's a multidimensional array) and column-major +ordering is used to access the elements. For example, +if `A` were a `(2, 3)` custom matrix type with linear indexing, +and we referenced `A[5]` (using linear style), this would +be equivalent to referencing `A[1, 3]` (since `2*1 + 3 = 5`). +See also [`IndexCartesian`](@ref). +""" struct IndexLinear <: IndexStyle end +""" + IndexCartesian() + +Subtype of [`IndexStyle`](@ref) used to describe arrays which +are optimally indexed by a Cartesian index. + +A cartesian indexing style uses multiple integers/indices to describe the position in the array. +For example, if `A` were a `(2, 3, 4)` custom matrix type with cartesian indexing, +we could reference `A[2, 1, 3]` and Julia would automatically convert this into the +correct location in the underlying memory. See also [`IndexLinear`](@ref). +""" struct IndexCartesian <: IndexStyle end """ @@ -21,14 +46,14 @@ struct IndexCartesian <: IndexStyle end IndexStyle(typeof(A)) `IndexStyle` specifies the "native indexing style" for array `A`. When -you define a new `AbstractArray` type, you can choose to implement -either linear indexing or cartesian indexing. If you decide to -implement linear indexing, then you must set this trait for your array +you define a new [`AbstractArray`](@ref) type, you can choose to implement +either linear indexing (with [`IndexLinear`](@ref)) or cartesian indexing. +If you decide to implement linear indexing, then you must set this trait for your array type: Base.IndexStyle(::Type{<:MyArray}) = IndexLinear() -The default is `IndexCartesian()`. +The default is [`IndexCartesian()`](@ref). Julia's internal indexing machinery will automatically (and invisibly) convert all indexing operations into the preferred style. This allows users diff --git a/base/iterators.jl b/base/iterators.jl index 396b1744482f7..1564ffa1be9a1 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -181,9 +181,9 @@ Also similar to `enumerate(A)`, except `i` will be a valid index for `A`, while `enumerate` always counts from 1 regardless of the indices of `A`. -Specifying `IndexLinear()` ensures that `i` will be an integer; -specifying `IndexCartesian()` ensures that `i` will be a -`CartesianIndex`; specifying `IndexStyle(A)` chooses whichever has +Specifying [`IndexLinear()`](@ref) ensures that `i` will be an integer; +specifying [`IndexCartesian()`](@ref) ensures that `i` will be a +[`CartesianIndex`](@ref); specifying `IndexStyle(A)` chooses whichever has been defined as the native indexing style for array `A`. Mutation of the bounds of the underlying array will invalidate this iterator. diff --git a/doc/src/base/arrays.md b/doc/src/base/arrays.md index 521cbc2d3dea8..260649a3a36cf 100644 --- a/doc/src/base/arrays.md +++ b/doc/src/base/arrays.md @@ -53,6 +53,8 @@ Base.axes(::AbstractArray, ::Any) Base.length(::AbstractArray) Base.eachindex Base.IndexStyle +Base.IndexLinear +Base.IndexCartesian Base.conj! Base.stride Base.strides From 883c8a38920985e0c02df169ff8c379731d88fc6 Mon Sep 17 00:00:00 2001 From: chromezh <32255369+chromezh@users.noreply.github.com> Date: Mon, 13 Aug 2018 21:59:23 +0800 Subject: [PATCH 003/110] Fix typo (#28594) Add a punctuation --- doc/src/manual/noteworthy-differences.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/manual/noteworthy-differences.md b/doc/src/manual/noteworthy-differences.md index 9aff0df12fe68..c45d7b1ef8e44 100644 --- a/doc/src/manual/noteworthy-differences.md +++ b/doc/src/manual/noteworthy-differences.md @@ -253,7 +253,7 @@ For users coming to Julia from R, these are some noteworthy differences: Floating point literals are closer in behavior to C/C++. Octal (prefixed with `0o`) and binary (prefixed with `0b`) literals are also treated as unsigned. * String literals can be delimited with either `"` or `"""`, `"""` delimited literals can contain - `"` characters without quoting it like `"\""` String literals can have values of other variables + `"` characters without quoting it like `"\""`. String literals can have values of other variables or expressions interpolated into them, indicated by `$variablename` or `$(expression)`, which evaluates the variable name or the expression in the context of the function. * `//` indicates a [`Rational`](@ref) number, and not a single-line comment (which is `#` in Julia) From decee6537e7924d53174768880dadfa1854d0bf1 Mon Sep 17 00:00:00 2001 From: Sebastian Pfitzner Date: Mon, 13 Aug 2018 23:37:00 +0100 Subject: [PATCH 004/110] fix various `printstyled` calls (#28586) --- base/compiler/ssair/show.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/base/compiler/ssair/show.jl b/base/compiler/ssair/show.jl index c1b396f22a6ab..97d74be275702 100644 --- a/base/compiler/ssair/show.jl +++ b/base/compiler/ssair/show.jl @@ -327,7 +327,7 @@ function show_ir(io::IO, code::IRCode, expr_type_printer=default_expr_type_print bb_idx = 1 new_nodes = code.new_nodes if any(i -> !isassigned(code.new_nodes, i), 1:length(code.new_nodes)) - printstyled(io, :red, "ERROR: New node array has unset entry\n") + printstyled(io, "ERROR: New node array has unset entry\n", color=:red) new_nodes = new_nodes[filter(i -> isassigned(code.new_nodes, i), 1:length(code.new_nodes))] end for nn in new_nodes @@ -354,7 +354,7 @@ function show_ir(io::IO, code::IRCode, expr_type_printer=default_expr_type_print if !isassigned(stmts, idx) # This is invalid, but do something useful rather # than erroring, to make debugging easier - printstyled(io, :red, "#UNDEF\n") + printstyled(io, "#UNDEF\n", color=:red) continue end stmt = stmts[idx] @@ -495,7 +495,7 @@ function show_ir(io::IO, code::CodeInfo, expr_type_printer=default_expr_type_pri if !isassigned(stmts, idx) # This is invalid, but do something useful rather # than erroring, to make debugging easier - printstyled(io, :red, "#UNDEF\n") + printstyled(io, "#UNDEF\n", color=:red) continue end stmt = stmts[idx] From 2fcad41676403255c075e3acf8d997892d2fcfc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Tue, 14 Aug 2018 00:37:43 +0200 Subject: [PATCH 005/110] fix print docstring (#28609) --- base/strings/io.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/strings/io.jl b/base/strings/io.jl index bd82fd37494b3..4df79c223ac69 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -11,7 +11,7 @@ of values `xs` if there is one, otherwise call [`show`](@ref). The representation used by `print` includes minimal formatting and tries to avoid Julia-specific details. -Printing `nothing` is deprecated and will throw an error in the future. +Printing `nothing` is not allowed and throws an error. # Examples ```jldoctest @@ -132,7 +132,7 @@ string_with_env(env, xs...) = print_to_string(xs...; env=env) """ string(xs...) -Create a string from any values using the [`print`](@ref) function. +Create a string from any values, except `nothing`, using the [`print`](@ref) function. # Examples ```jldoctest From 3fe2d08c1546c41ade0459122905016527efa03f Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Tue, 14 Aug 2018 12:02:25 +0200 Subject: [PATCH 006/110] implement the REPL replayer on Windows (#28608) --- contrib/generate_precompile.jl | 150 ++++--- contrib/precompile_explicit.jl | 732 --------------------------------- stdlib/Pkg/src/Pkg.jl | 11 +- stdlib/Pkg/src/precompile.jl | 431 ------------------- stdlib/REPL/src/Terminals.jl | 2 + 5 files changed, 87 insertions(+), 1239 deletions(-) delete mode 100644 contrib/precompile_explicit.jl delete mode 100644 stdlib/Pkg/src/precompile.jl diff --git a/contrib/generate_precompile.jl b/contrib/generate_precompile.jl index 67885582754f8..cd1778568851f 100644 --- a/contrib/generate_precompile.jl +++ b/contrib/generate_precompile.jl @@ -8,7 +8,7 @@ if !isdefined(Base, :uv_eventloop) Base.reinit_stdio() end Base.include(@__MODULE__, joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testhelpers", "FakePTYs.jl")) -import .FakePTYs: with_fake_pty +import .FakePTYs: open_fake_pty CTRL_C = '\x03' UP_ARROW = "\e[A" @@ -43,6 +43,12 @@ if Pkg !== nothing precompile_script *= Pkg.precompile_script end +push!(LOAD_PATH, Sys.STDLIB) +using Sockets +Sockets.__init__() +using Libdl +empty!(LOAD_PATH) + function generate_precompile_statements() start_time = time() @@ -62,82 +68,94 @@ function generate_precompile_statements() empty!(DEPOT_PATH) end - # Create a staging area where all the loaded packages are available - PrecompileStagingArea = Module() - for (_pkgid, _mod) in Base.loaded_modules - if !(_pkgid.name in ("Main", "Core", "Base")) - eval(PrecompileStagingArea, :($(Symbol(_mod)) = $_mod)) + print("Generating precompile statements...") + sysimg = isempty(ARGS) ? joinpath(dirname(Sys.BINDIR), "lib", "julia", "sys." * Libdl.dlext) : ARGS[1] + + mktemp() do precompile_file, _ + # Run a repl process and replay our script + repl_output_buffer = IOBuffer() + @static if Sys.iswindows() + # Fake being cygwin + pipename = """\\\\?\\pipe\\cygwin-$("0"^16)-pty10-abcdef""" + server = listen(pipename) + slave = connect(pipename) + @assert ccall(:jl_ispty, Cint, (Ptr{Cvoid},), slave.handle) == 1 + master = accept(server) + else + slave, master = open_fake_pty() end - end - - # TODO: Implement REPL replayer for Windows - @static if !Sys.iswindows() - print("Generating precompile statements...") - sysimg = isempty(ARGS) ? joinpath(dirname(Sys.BINDIR), "lib", "julia", "sys.ji") : ARGS[1] - - mktemp() do precompile_file, _ - # Run a repl process and replay our script - stdout_accumulator, stderr_accumulator = IOBuffer(), IOBuffer() - with_fake_pty() do slave, master - with_fake_pty() do slave_err, master_err - done = false - withenv("JULIA_HISTORY" => tempname(), "JULIA_PROJECT" => nothing, - "TERM" => "") do - p = run(`$(julia_cmd()) -O0 --trace-compile=$precompile_file --sysimage $sysimg - --startup-file=no --color=yes`, - slave, slave, slave_err; wait=false) - readuntil(master, "julia>", keep=true) - for (tty, accumulator) in (master => stdout_accumulator, - master_err => stderr_accumulator) - @async begin - while true - done && break - write(accumulator, readavailable(tty)) - end - end - end - if have_repl - for l in split(precompile_script, '\n'; keepempty=false) - write(master, l, '\n') - end - end - write(master, "exit()\n") - wait(p) - done = true - end + done = false + withenv("JULIA_HISTORY" => tempname(), "JULIA_PROJECT" => nothing, + "TERM" => "") do + p = run(`$(julia_cmd()) -O0 --trace-compile=$precompile_file --sysimage $sysimg + --compile=all --startup-file=no --color=yes + -e 'import REPL; REPL.Terminals.is_precompiling[] = true' + -i`, + slave, slave, slave; wait=false) + readuntil(master, "julia>", keep=true) + @async begin + while true + done && break + write(repl_output_buffer, readavailable(master)) + end + end + if have_repl + for l in split(precompile_script, '\n'; keepempty=false) + write(master, l, '\n') end end + # TODO Figure out why exit() on Windows doesn't exit the process + if Sys.iswindows() + print(master, "ccall(:_exit, Cvoid, (Cint,), 0)\n") + else + write(master, "exit()\n") + end + wait(p) + done = true + end + close(master) - # Check what the REPL displayed - # stdout_output = String(take!(stdout_accumulator)) - # println(stdout_output) + # Check what the REPL displayed + # repl_output = String(take!(repl_output_buffer)) + # println(repl_output) - # Extract the precompile statements from stderr - statements = Set{String}() - for statement in split(read(precompile_file, String), '\n') - occursin("Main.", statement) && continue - push!(statements, statement) - end + # Extract the precompile statements from stderr + statements = Set{String}() + for statement in split(read(precompile_file, String), '\n') + occursin("Main.", statement) && continue + push!(statements, statement) + end - # Load the precompile statements - statements_ordered = join(sort(collect(statements)), '\n') - # println(statements_ordered) - if have_repl - # Seems like a reasonable number right now, adjust as needed - @assert length(statements) > 700 + if have_repl + # Seems like a reasonable number right now, adjust as needed + # comment out if debugging script + @assert length(statements) > 700 + end + + # Create a staging area where all the loaded packages are available + PrecompileStagingArea = Module() + for (_pkgid, _mod) in Base.loaded_modules + if !(_pkgid.name in ("Main", "Core", "Base")) + eval(PrecompileStagingArea, :($(Symbol(_mod)) = $_mod)) end + end - Base.include_string(PrecompileStagingArea, statements_ordered) - print(" $(length(statements)) generated in ") - Base.time_print((time() - start_time) * 10^9) - println() + # Execute the collected precompile statements + include_time = @elapsed for statement in sort(collect(statements)) + # println(statement) + try + Base.include_string(PrecompileStagingArea, statement) + catch ex + @error "Failed to precompile $statement" + rethrow(ex) + end end + print(" $(length(statements)) generated in ") + tot_time = time() - start_time + Base.time_print(tot_time * 10^9) + print(" (overhead "); Base.time_print((tot_time - include_time) * 10^9); println(")") end - # Fall back to explicit list on Windows, might as well include them - # for everyone though - Base.include(PrecompileStagingArea, "precompile_explicit.jl") - return end diff --git a/contrib/precompile_explicit.jl b/contrib/precompile_explicit.jl deleted file mode 100644 index a95b3cb8ddc34..0000000000000 --- a/contrib/precompile_explicit.jl +++ /dev/null @@ -1,732 +0,0 @@ -# This file is a part of Julia. License is MIT: https://julialang.org/license - -# Steps to regenerate this file: -# 1. Remove all `precompile` calls -# 2. Rebuild system image -# 3. Start julia with `--trace-compile=precompiles.txt and do some stuff -# 5. Run `grep -v '#[0-9]' precompiles.txt >> contrib/precompile_explicit.jl` -# (filters out closures, which might have different generated names in different environments) -# This list is only used on Windows, otherwise precompile statements are generated dynamically. - -precompile(Tuple{Type{Array{Base.StackTraces.StackFrame, 1}}, UndefInitializer, Int64}) -precompile(Tuple{Type{Array{Union{Nothing, String}, 1}}, UndefInitializer, Int64}) -precompile(Tuple{Type{Base.CoreLogging.LogState}, Logging.ConsoleLogger}) -precompile(Tuple{Type{Base.Dict{Any, Any}}}) -precompile(Tuple{Type{Base.Dict{Any, Int64}}}) -precompile(Tuple{Type{Base.Dict{Char, Any}}}) -precompile(Tuple{Type{Base.Dict{Symbol, Any}}, Base.Pair{Symbol, REPL.LineEdit.Prompt}, Base.Pair{Symbol, REPL.LineEdit.Prompt}, Base.Pair{Symbol, REPL.LineEdit.Prompt}}) -precompile(Tuple{Type{Base.Dict{Symbol, Any}}, Base.Pair{Symbol, REPL.LineEdit.Prompt}, Vararg{Base.Pair{Symbol, REPL.LineEdit.Prompt}, N} where N}) -precompile(Tuple{Type{Base.Dict{Symbol, Any}}}) -precompile(Tuple{Type{Base.GC_Diff}, Base.GC_Num, Base.GC_Num}) -precompile(Tuple{Type{Base.Generator{I, F} where F where I}, typeof(Base.names), Array{Any, 1}}) -precompile(Tuple{Type{Base.IOContext{IO_t} where IO_t<:IO}, Base.GenericIOBuffer{Array{UInt8, 1}}, Base.IOStream}) -precompile(Tuple{Type{Base.IOContext{IO_t} where IO_t<:IO}, REPL.Terminals.TTYTerminal, Base.Pair{Symbol, Bool}}) -precompile(Tuple{Type{Base.InterpreterIP}, Core.CodeInfo, Ptr{Nothing}}) -precompile(Tuple{Type{Base.IteratorSize}, Array{Any, 1}}) -precompile(Tuple{Type{Base.LinearIndices{N, R} where R<:Tuple{Vararg{Base.AbstractUnitRange{Int64}, N}} where N}, Array{Method, 1}}) -precompile(Tuple{Type{Base.MIME{Symbol("text/plain")}}}) -precompile(Tuple{Type{Base.Multimedia.TextDisplay}, Base.TTY}) -precompile(Tuple{Type{Base.Order.Perm{O, V} where V<:(AbstractArray{T, 1} where T) where O<:Base.Order.Ordering}, Base.Order.ForwardOrdering, Array{Tuple{Float64, Int64}, 1}}) -precompile(Tuple{Type{Base.Pair{A, B} where B where A}, Base.PkgId, UInt64}) -precompile(Tuple{Type{Base.Pair{A, B} where B where A}, Int64, Int64}) -precompile(Tuple{Type{Base.PkgId}, String}) -precompile(Tuple{Type{Base.StackTraces.StackFrame}, Symbol, Symbol, Int64, Core.CodeInfo, Bool, Bool, Int64}) -precompile(Tuple{Type{Base.StackTraces.StackFrame}, Symbol, Symbol, Int64, Core.MethodInstance, Bool, Bool, Ptr{Nothing}}) -precompile(Tuple{Type{Base.StackTraces.StackFrame}, Symbol, Symbol, Int64, Nothing, Bool, Bool, Ptr{Nothing}}) -precompile(Tuple{Type{Base.SubString{T} where T<:AbstractString}, String, Int64}) -precompile(Tuple{Type{Base.Val{2}}}) -precompile(Tuple{Type{Base.Val{3}}}) -precompile(Tuple{Type{Logging.ConsoleLogger}, Base.IOStream}) -precompile(Tuple{Type{Logging.ConsoleLogger}, Base.TTY}) -precompile(Tuple{Type{Markdown.Header{1}}, Array{Any, 1}}) -precompile(Tuple{Type{Markdown.MD}, Markdown.MD, Markdown.MD}) -precompile(Tuple{Type{NamedTuple{(), T} where T<:Tuple}, Tuple{}}) -precompile(Tuple{Type{NamedTuple{(:bold, :color), Tuple{Bool, Symbol}}}, Tuple{Bool, Symbol}}) -precompile(Tuple{Type{NamedTuple{(:bold, :color), T} where T<:Tuple}, Tuple{Bool, Symbol}}) -precompile(Tuple{Type{NamedTuple{(:create,), T} where T<:Tuple}, Tuple{Bool}}) -precompile(Tuple{Type{NamedTuple{(:merge,), T} where T<:Tuple}, Tuple{Bool}}) -precompile(Tuple{Type{NamedTuple{(:prompt_prefix, :prompt_suffix, :complete, :sticky), Tuple{String, String, Pkg.REPLMode.PkgCompletionProvider, Bool}}}, Tuple{String, String, Pkg.REPLMode.PkgCompletionProvider, Bool}}) -precompile(Tuple{Type{NamedTuple{(:prompt_prefix, :prompt_suffix, :complete, :sticky), T} where T<:Tuple}, Tuple{String, String, Pkg.REPLMode.PkgCompletionProvider, Bool}}) -precompile(Tuple{Type{NamedTuple{(:prompt_prefix, :prompt_suffix, :repl, :complete, :on_enter), Tuple{String, typeof(Base.input_color), REPL.LineEditREPL, REPL.REPLCompletionProvider, typeof(REPL.return_callback)}}}, Tuple{String, typeof(Base.input_color), REPL.LineEditREPL, REPL.REPLCompletionProvider, typeof(REPL.return_callback)}}) -precompile(Tuple{Type{NamedTuple{(:prompt_prefix, :prompt_suffix, :repl, :complete, :on_enter), T} where T<:Tuple}, Tuple{String, typeof(Base.input_color), REPL.LineEditREPL, REPL.REPLCompletionProvider, typeof(REPL.return_callback)}}) -precompile(Tuple{Type{NamedTuple{(:stderr,), Tuple{Base.IOStream}}}, Tuple{Base.IOStream}}) -precompile(Tuple{Type{REPL.LineEditREPL}, REPL.Terminals.TTYTerminal, Bool, Bool}) -precompile(Tuple{Type{REPL.LineEditREPL}, REPL.Terminals.TTYTerminal, Bool, String, String, String, String, String, Bool, Bool, Bool, Bool}) -precompile(Tuple{Type{REPL.REPLDisplay{R} where R<:REPL.AbstractREPL}, REPL.LineEditREPL}) -precompile(Tuple{Type{REPL.Terminals.TTYTerminal}, String, Base.PipeEndpoint, Base.TTY, Base.IOStream}) -precompile(Tuple{Type{REPL.Terminals.TTYTerminal}, String, Base.TTY, Base.TTY, Base.IOStream}) -precompile(Tuple{Type{REPL.Terminals.TTYTerminal}, String, Base.TTY, Base.TTY, Base.TTY}) -precompile(Tuple{Type{String}, Array{UInt8, 1}}) -precompile(Tuple{Type{UInt32}, UInt8}) -precompile(Tuple{Type{UnionAll}, TypeVar, Any}) -precompile(Tuple{getfield(Base, Symbol("#@time")), LineNumberNode, Module, Expr}) -precompile(Tuple{getfield(Base, Symbol("#kw##_spawn")), NamedTuple{(:chain,), Tuple{Nothing}}, typeof(Base._spawn), Base.Cmd, Tuple{Base.Pipe, Base.TTY, Base.IOStream}}) -precompile(Tuple{getfield(Base, Symbol("#kw##pipeline")), NamedTuple{(:stderr,), Tuple{Base.IOStream}}, typeof(Base.pipeline), Base.Cmd}) -precompile(Tuple{getfield(Base, Symbol("#kw##printstyled")), NamedTuple{(:bold, :color), Tuple{Bool, Symbol}}, typeof(Base.printstyled), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, String, String}) -precompile(Tuple{getfield(Base, Symbol("#kw##printstyled")), NamedTuple{(:bold, :color), Tuple{Bool, Symbol}}, typeof(Base.printstyled), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, String}) -precompile(Tuple{getfield(Base, Symbol("#kw##printstyled")), NamedTuple{(:bold, :color), Tuple{Bool, Symbol}}, typeof(Base.printstyled), REPL.Terminals.TTYTerminal, String}) -precompile(Tuple{getfield(Base, Symbol("#kw##printstyled")), NamedTuple{(:color,), Tuple{Symbol}}, typeof(Base.printstyled), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, String}) -precompile(Tuple{getfield(Base, Symbol("#kw##show_trace_entry")), NamedTuple{(:prefix,), Tuple{String}}, typeof(Base.show_trace_entry), Base.IOContext{REPL.Terminals.TTYTerminal}, Base.StackTraces.StackFrame, Int64}) -precompile(Tuple{getfield(Base, Symbol("#kw##sort!")), NamedTuple{(:by,), Tuple{typeof(REPL.REPLCompletions.completion_text)}}, typeof(Base.sort!), Array{REPL.REPLCompletions.Completion, 1}}) -precompile(Tuple{getfield(Base, Symbol("#kw##with_output_color")), NamedTuple{(:bold,), Tuple{Bool}}, typeof(Base.with_output_color), typeof(Base.print), Symbol, Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, String, String}) -precompile(Tuple{getfield(Base.Cartesian, Symbol("#@ncall")), LineNumberNode, Module, Int64, Symbol, Symbol, Expr}) -precompile(Tuple{getfield(Base.Cartesian, Symbol("#@nexprs")), LineNumberNode, Module, Int64, Expr}) -precompile(Tuple{getfield(Base.Meta, Symbol("#kw##parse")), NamedTuple{(:raise, :depwarn), Tuple{Bool, Bool}}, typeof(Base.Meta.parse), String, Int64}) -precompile(Tuple{getfield(Core, Symbol("#@doc")), LineNumberNode, Module, Symbol}) -precompile(Tuple{getfield(Core, Symbol("#kw#Type")), NamedTuple{(:prompt_prefix, :prompt_suffix, :complete, :sticky), Tuple{String, String, Pkg.REPLMode.PkgCompletionProvider, Bool}}, Type{REPL.LineEdit.Prompt}, typeof(Pkg.REPLMode.promptf)}) -precompile(Tuple{getfield(Core, Symbol("#kw#Type")), NamedTuple{(:prompt_prefix, :prompt_suffix, :repl, :complete, :on_enter), Tuple{String, typeof(Base.input_color), REPL.LineEditREPL, REPL.REPLCompletionProvider, typeof(REPL.return_callback)}}, Type{REPL.LineEdit.Prompt}, String}) -precompile(Tuple{getfield(REPL, Symbol("#@repl")), LineNumberNode, Module, Base.TTY, Symbol}) -precompile(Tuple{getfield(REPL, Symbol("#kw##printmatches")), NamedTuple{(:cols,), Tuple{Int64}}, typeof(REPL.printmatches), Base.TTY, String, Array{String, 1}}) -precompile(Tuple{getfield(REPL.LineEdit, Symbol("#kw##add_nested_key!")), NamedTuple{(:override,), Tuple{Bool}}, typeof(REPL.LineEdit.add_nested_key!), Base.Dict{Char, Any}, Char, Function}) -precompile(Tuple{getfield(REPL.LineEdit, Symbol("#kw##refresh_multi_line")), NamedTuple{(:beeping,), Tuple{Bool}}, typeof(REPL.LineEdit.refresh_multi_line), REPL.Terminals.TTYTerminal, REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(Base.:(!=)), Char, Char}) -precompile(Tuple{typeof(Base.:(!=)), Int64, Int64}) -precompile(Tuple{typeof(Base.:(!=)), Int8, Int64}) -precompile(Tuple{typeof(Base.:(!=)), Nothing, Nothing}) -precompile(Tuple{typeof(Base.:(!=)), REPL.LineEdit.Prompt, Nothing}) -precompile(Tuple{typeof(Base.:(!=)), String, Nothing}) -precompile(Tuple{typeof(Base.:(!=)), String, String}) -precompile(Tuple{typeof(Base.:(!=)), UInt8, UInt8}) -precompile(Tuple{typeof(Base.:(*)), Base.SubString{String}, String}) -precompile(Tuple{typeof(Base.:(+)), Int64, Bool}) -precompile(Tuple{typeof(Base.:(<<)), UInt32, Int64}) -precompile(Tuple{typeof(Base.:(<=)), Int64, Int64}) -precompile(Tuple{typeof(Base.:(==)), Base.Multimedia.TextDisplay, REPL.REPLDisplay{REPL.LineEditREPL}}) -precompile(Tuple{typeof(Base.:(==)), Int8, Int64}) -precompile(Tuple{typeof(Base.:(==)), Module, Module}) -precompile(Tuple{typeof(Base.:(==)), Nothing, String}) -precompile(Tuple{typeof(Base.:(==)), REPL.REPLDisplay{REPL.LineEditREPL}, REPL.REPLDisplay{REPL.LineEditREPL}}) -precompile(Tuple{typeof(Base.:(>)), UInt64, Int64}) -precompile(Tuple{typeof(Base.:(^)), Char, Int64}) -precompile(Tuple{typeof(Base.:(|>)), Array{Any, 1}, typeof(Base.unique)}) -precompile(Tuple{typeof(Base.:(|>)), Array{Any, 1}, typeof(REPL.filtervalid)}) -precompile(Tuple{typeof(Base.CoreLogging.global_logger), Logging.ConsoleLogger}) -precompile(Tuple{typeof(Base.CoreLogging.global_logger)}) -precompile(Tuple{typeof(Base.CoreLogging.logmsg_shim), Int64, String, Nothing, Symbol, Symbol, Symbol, Int64, Array{Any, 1}}) -precompile(Tuple{typeof(Base.Docs.catdoc), Markdown.MD, Markdown.MD}) -precompile(Tuple{typeof(Base.Docs.doc), Base.Docs.Binding, Type{Union{}}}) -precompile(Tuple{typeof(Base.Docs.doc), Base.Docs.Binding}) -precompile(Tuple{typeof(Base.Docs.docm), LineNumberNode, Module, Symbol}) -precompile(Tuple{typeof(Base.Docs.formatdoc), Base.GenericIOBuffer{Array{UInt8, 1}}, Base.Docs.DocStr, String}) -precompile(Tuple{typeof(Base.Filesystem.basename), String}) -precompile(Tuple{typeof(Base.Filesystem.isdir), String}) -precompile(Tuple{typeof(Base.Filesystem.pwd)}) -precompile(Tuple{typeof(Base.Filesystem.splitdir), String}) -precompile(Tuple{typeof(Base.Filesystem.splitext), String}) -precompile(Tuple{typeof(Base.Meta.isexpr), Symbol, Symbol, Int64}) -precompile(Tuple{typeof(Base.Meta.parse), String}) -precompile(Tuple{typeof(Base.Multimedia.display), Int64}) -precompile(Tuple{typeof(Base.Multimedia.display), Markdown.MD}) -precompile(Tuple{typeof(Base.Multimedia.display), REPL.REPLDisplay{REPL.LineEditREPL}, Array{Float64, 1}}) -precompile(Tuple{typeof(Base.Multimedia.display), REPL.REPLDisplay{REPL.LineEditREPL}, Array{Float64, 2}}) -precompile(Tuple{typeof(Base.Multimedia.display), REPL.REPLDisplay{REPL.LineEditREPL}, Array{Int64, 1}}) -precompile(Tuple{typeof(Base.Multimedia.display), REPL.REPLDisplay{REPL.LineEditREPL}, Float64}) -precompile(Tuple{typeof(Base.Multimedia.display), REPL.REPLDisplay{REPL.LineEditREPL}, Int64}) -precompile(Tuple{typeof(Base.Multimedia.display), REPL.REPLDisplay{REPL.LineEditREPL}, Markdown.MD}) -precompile(Tuple{typeof(Base.Multimedia.display), REPL.REPLDisplay{REPL.LineEditREPL}, String}) -precompile(Tuple{typeof(Base.Multimedia.pushdisplay), REPL.REPLDisplay{REPL.LineEditREPL}}) -precompile(Tuple{typeof(Base.Order.ord), typeof(Base.isless), typeof(Base.identity), Nothing, Base.Order.ForwardOrdering}) -precompile(Tuple{typeof(Base.Printf.decode_dec), Base.TTY, Float64, String, Int64, Int64, Char}) -precompile(Tuple{typeof(Base.StackTraces.lookup), Base.InterpreterIP}) -precompile(Tuple{typeof(Base.Unicode.textwidth), String}) -precompile(Tuple{typeof(Base.__atreplinit), REPL.LineEditREPL}) -precompile(Tuple{typeof(Base.__precompile__)}) -precompile(Tuple{typeof(Base._atexit)}) -precompile(Tuple{typeof(Base._compute_eltype), Type{Tuple{Int64, String}}}) -precompile(Tuple{typeof(Base._iterate), Base.Dict{Symbol, Any}, Int64}) -precompile(Tuple{typeof(Base._promote_typejoin), Type{Int64}, Type{String}}) -precompile(Tuple{typeof(Base._promote_typejoin), Type{Nothing}, Type{String}}) -precompile(Tuple{typeof(Base._promote_typejoin), Type{Union{}}, Type{Int64}}) -precompile(Tuple{typeof(Base._reformat_bt), Array{Ptr{Nothing}, 1}, Array{Any, 1}}) -precompile(Tuple{typeof(Base._similar_for), Array{Any, 1}, Type{String}, Base.Generator{Array{Any, 1}, typeof(Base.string)}, Base.HasShape{1}}) -precompile(Tuple{typeof(Base._similar_for), Array{Base.Docs.DocStr, 1}, Type{Markdown.MD}, Base.Generator{Array{Base.Docs.DocStr, 1}, typeof(Base.Docs.parsedoc)}, Base.HasShape{1}}) -precompile(Tuple{typeof(Base._similar_for), Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}, Type{Array{Base.StackTraces.StackFrame, 1}}, Base.Generator{Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}, typeof(Base.StackTraces.lookup)}, Base.HasShape{1}}) -precompile(Tuple{typeof(Base._spawn), Base.CmdRedirect, Tuple{Base.Pipe, Base.TTY, Base.IOStream}}) -precompile(Tuple{typeof(Base._start)}) -precompile(Tuple{typeof(Base._typed_vcat), Type{Any}, Tuple{Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{String, 1}}}) -precompile(Tuple{typeof(Base._uv_hook_close), Base.PipeEndpoint}) -precompile(Tuple{typeof(Base._uv_hook_close), Base.Process}) -precompile(Tuple{typeof(Base._uv_hook_close), Base.Timer}) -precompile(Tuple{typeof(Base.alignment), Base.IOContext{REPL.Terminals.TTYTerminal}, Array{Float64, 1}, Base.OneTo{Int64}, Base.OneTo{Int64}, Int64, Int64, Int64}) -precompile(Tuple{typeof(Base.alignment), Base.IOContext{REPL.Terminals.TTYTerminal}, Array{Float64, 2}, Base.OneTo{Int64}, Base.OneTo{Int64}, Int64, Int64, Int64}) -precompile(Tuple{typeof(Base.alignment), Base.IOContext{REPL.Terminals.TTYTerminal}, Array{Int64, 1}, Base.OneTo{Int64}, Base.OneTo{Int64}, Int64, Int64, Int64}) -precompile(Tuple{typeof(Base.alloc_buf_hook), Base.PipeEndpoint, UInt64}) -precompile(Tuple{typeof(Base.alloc_buf_hook), Base.TTY, UInt64}) -precompile(Tuple{typeof(Base.append!), Array{String, 1}, Array{String, 1}}) -precompile(Tuple{typeof(Base.arg_gen), Base.Cmd}) -precompile(Tuple{typeof(Base.arg_gen), String}) -precompile(Tuple{typeof(Base.axes), Array{Any, 1}}) -precompile(Tuple{typeof(Base.bytesavailable), Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{typeof(Base.catch_backtrace)}) -precompile(Tuple{typeof(Base.check_open), Base.TTY}) -precompile(Tuple{typeof(Base.close), Base.Pipe}) -precompile(Tuple{typeof(Base.collect_similar), Array{Any, 1}, Base.Generator{Array{Any, 1}, typeof(Base.names)}}) -precompile(Tuple{typeof(Base.collect_to_with_first!), Array{Array{Base.StackTraces.StackFrame, 1}, 1}, Array{Base.StackTraces.StackFrame, 1}, Base.Generator{Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}, typeof(Base.StackTraces.lookup)}, Int64}) -precompile(Tuple{typeof(Base.collect_to_with_first!), Array{Markdown.MD, 1}, Markdown.MD, Base.Generator{Array{Base.Docs.DocStr, 1}, typeof(Base.Docs.parsedoc)}, Int64}) -precompile(Tuple{typeof(Base.collect_to_with_first!), Array{String, 1}, String, Base.Generator{Array{Any, 1}, typeof(Base.string)}, Int64}) -precompile(Tuple{typeof(Base.collect_to_with_first!), Array{String, 1}, String, Base.Generator{Array{REPL.REPLCompletions.Completion, 1}, typeof(REPL.REPLCompletions.completion_text)}, Int64}) -precompile(Tuple{typeof(Base.convert), Type{Array{String, 1}}, Array{Any, 1}}) -precompile(Tuple{typeof(Base.convert), Type{Base.Dict{Char, V} where V}, Base.Dict{Char, Any}}) -precompile(Tuple{typeof(Base.convert), Type{Base.Dict{K, V} where V where K}, Base.Dict{String, Any}}) -precompile(Tuple{typeof(Base.convert), Type{Base.GenericIOBuffer{Array{UInt8, 1}}}, Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{typeof(Base.convert), Type{Bool}, Bool}) -precompile(Tuple{typeof(Base.convert), Type{Int64}, Int64}) -precompile(Tuple{typeof(Base.convert), Type{Ptr{Nothing}}, Ptr{Nothing}}) -precompile(Tuple{typeof(Base.convert), Type{Ptr{Nothing}}, Ptr{UInt8}}) -precompile(Tuple{typeof(Base.convert), Type{REPL.LineEdit.InputAreaState}, REPL.LineEdit.InputAreaState}) -precompile(Tuple{typeof(Base.convert), Type{REPL.LineEdit.MIState}, REPL.LineEdit.MIState}) -precompile(Tuple{typeof(Base.convert), Type{REPL.LineEdit.Prompt}, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(Base.convert), Type{Union{Base.UUID, Bool}}, Bool}) -precompile(Tuple{typeof(Base.convert), Type{Union{Function, String}}, String}) -precompile(Tuple{typeof(Base.convert), Type{Union{Nothing, REPL.LineEdit.Prompt}}, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(Base.convert), Type{Union{Nothing, Type{T} where T}}, Nothing}) -precompile(Tuple{typeof(Base.copy), Array{Any, 1}}) -precompile(Tuple{typeof(Base.copy), Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{typeof(Base.copymutable), Array{String, 1}}) -precompile(Tuple{typeof(Base.copyto!), Array{Union{Nothing, String}, 1}, Int64, Array{Nothing, 1}, Int64, Int64}) -precompile(Tuple{typeof(Base.delete!), Base.Set{Any}, Char}) -precompile(Tuple{typeof(Base.diff_names), Tuple{Symbol, Symbol, Symbol, Symbol, Symbol}, Tuple{Symbol, Symbol, Symbol, Symbol, Symbol, Symbol, Symbol, Symbol, Symbol}}) -precompile(Tuple{typeof(Base.diff_names), Tuple{Symbol, Symbol, Symbol}, Tuple{Symbol, Symbol, Symbol, Symbol, Symbol}}) -precompile(Tuple{typeof(Base.diff_names), Tuple{Symbol}, Tuple{Symbol, Symbol, Symbol, Symbol, Symbol, Symbol, Symbol}}) -precompile(Tuple{typeof(Base.diff_names), Tuple{Symbol}, Tuple{Symbol}}) -precompile(Tuple{typeof(Base.display_error), REPL.Terminals.TTYTerminal, ErrorException, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}) -precompile(Tuple{typeof(Base.display_error), REPL.Terminals.TTYTerminal, MethodError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}) -precompile(Tuple{typeof(Base.display_error), REPL.Terminals.TTYTerminal, UndefVarError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}) -precompile(Tuple{typeof(Base.displaysize), Base.IOStream}) -precompile(Tuple{typeof(Base.displaysize), Base.TTY}) -precompile(Tuple{typeof(Base.displaysize), REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(Base.divrem), Int64, Int64}) -precompile(Tuple{typeof(Base.eachline), String}) -precompile(Tuple{typeof(Base.empty!), Array{Base.Pair{Base.PkgId, UInt64}, 1}}) -precompile(Tuple{typeof(Base.ensure_rescheduled), Task}) -precompile(Tuple{typeof(Base.eof), Base.PipeEndpoint}) -precompile(Tuple{typeof(Base.eof), Base.TTY}) -precompile(Tuple{typeof(Base.error), String}) -precompile(Tuple{typeof(Base.findlast), String, String}) -precompile(Tuple{typeof(Base.findprev), Base.Fix2{typeof(Base.in), Array{Char, 1}}, String, Int64}) -precompile(Tuple{typeof(Base.findprev), String, String, Int64}) -precompile(Tuple{typeof(Base.first), Base.OneTo{Int64}}) -precompile(Tuple{typeof(Base.first), Base.UnitRange{Int64}}) -precompile(Tuple{typeof(Base.firstindex), String}) -precompile(Tuple{typeof(Base.flush), Base.IOStream}) -precompile(Tuple{typeof(Base.gc_alloc_count), Base.GC_Diff}) -precompile(Tuple{typeof(Base.gc_num)}) -precompile(Tuple{typeof(Base.get), Base.Dict{Char, Any}, Char, Nothing}) -precompile(Tuple{typeof(Base.getindex), Array{AbstractString, 1}, Base.UnitRange{Int64}}) -precompile(Tuple{typeof(Base.getindex), Array{AbstractString, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Array{Any, 1}, Int32}) -precompile(Tuple{typeof(Base.getindex), Array{Int32, 1}, UInt64}) -precompile(Tuple{typeof(Base.getindex), Array{String, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Array{UInt8, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Base.Dict{Any, Any}, Char}) -precompile(Tuple{typeof(Base.getindex), Base.Dict{String, Any}, String}) -precompile(Tuple{typeof(Base.getindex), Base.Dict{Symbol, Any}, Symbol}) -precompile(Tuple{typeof(Base.getindex), Core.SimpleVector, Base.UnitRange{Int64}}) -precompile(Tuple{typeof(Base.getindex), String, Base.UnitRange{Int64}}) -precompile(Tuple{typeof(Base.getindex), Tuple{Base.GenericIOBuffer{Array{UInt8, 1}}, Int64}, Int64}) -precompile(Tuple{typeof(Base.getindex), Tuple{Base.StackTraces.StackFrame, Int64}, Int64}) -precompile(Tuple{typeof(Base.getindex), Tuple{Int64, Int64}, Int64}) -precompile(Tuple{typeof(Base.getindex), Tuple{Symbol, Symbol, Symbol}, Base.UnitRange{Int64}}) -precompile(Tuple{typeof(Base.getindex), Tuple{Symbol}, Base.UnitRange{Int64}}) -precompile(Tuple{typeof(Base.getindex), Tuple{Symbol}, Int64}) -precompile(Tuple{typeof(Base.getproperty), Base.CoreLogging.LogState, Symbol}) -precompile(Tuple{typeof(Base.getproperty), Base.GC_Diff, Symbol}) -precompile(Tuple{typeof(Base.getproperty), Base.GenericIOBuffer{Array{UInt8, 1}}, Symbol}) -precompile(Tuple{typeof(Base.getproperty), Base.Process, Symbol}) -precompile(Tuple{typeof(Base.getproperty), Base.StackTraces.StackFrame, Symbol}) -precompile(Tuple{typeof(Base.getproperty), Core.CodeInfo, Symbol}) -precompile(Tuple{typeof(Base.getproperty), Core.LineInfoNode, Symbol}) -precompile(Tuple{typeof(Base.getproperty), Core.MethodTable, Symbol}) -precompile(Tuple{typeof(Base.getproperty), Method, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.HistoryPrompt, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.ModalInterface, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.PrefixHistoryPrompt, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.PrefixSearchState, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.Prompt, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.PromptState, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.SearchState, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.LineEditREPL, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.Options, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.REPLHistoryProvider, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.Terminals.TTYTerminal, Symbol}) -precompile(Tuple{typeof(Base.haskey), Base.Dict{String, Any}, String}) -precompile(Tuple{typeof(Base.haskey), Base.Dict{Symbol, Any}, Symbol}) -precompile(Tuple{typeof(Base.haskey), Base.Dict{Symbol, Function}, Symbol}) -precompile(Tuple{typeof(Base.haskey), Base.IdDict{Any, Any}, Base.Docs.Binding}) -precompile(Tuple{typeof(Base.hvcat), Tuple{Int64, Int64}, Float64, Float64, Float64, Float64}) -precompile(Tuple{typeof(Base.identity), Char}) -precompile(Tuple{typeof(Base.in), Char, Tuple{Char, Char, Char}}) -precompile(Tuple{typeof(Base.in), String, Base.Set{Any}}) -precompile(Tuple{typeof(Base.in), String, Tuple{String, String}}) -precompile(Tuple{typeof(Base.in), Symbol, Base.Set{Any}}) -precompile(Tuple{typeof(Base.incomplete_tag), Symbol}) -precompile(Tuple{typeof(Base.indexed_iterate), Base.Pair{String, String}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Base.Pair{String, String}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{ArgumentError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{ArgumentError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Array{Float64, 1}, Nothing}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Array{Float64, 1}, Nothing}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Array{Float64, 2}, Nothing}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Array{Float64, 2}, Nothing}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Array{Int64, 1}, Nothing}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Array{Int64, 1}, Nothing}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Array{String, 1}, String, Bool}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Array{String, 1}, String, Bool}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Base.GenericIOBuffer{Array{UInt8, 1}}, Bool, Bool}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Base.GenericIOBuffer{Array{UInt8, 1}}, Bool, Bool}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Base.StackTraces.StackFrame, Int64}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Base.StackTraces.StackFrame, Int64}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{ErrorException, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{ErrorException, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Expr, Int64}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Expr, Int64}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Float64, Nothing}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Float64, Nothing}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Int64, Nothing}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Int64, Nothing}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Markdown.MD, Nothing}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Markdown.MD, Nothing}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{MethodError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{MethodError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Nothing, Nothing}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Nothing, Nothing}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{String, Nothing}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{String, Nothing}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Symbol, String, String}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Symbol, String, String}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{UndefVarError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{UndefVarError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}, Int64}) -precompile(Tuple{typeof(Base.init_stdio), Ptr{Nothing}}) -precompile(Tuple{typeof(Base.isempty), Array{Base.Docs.DocStr, 1}}) -precompile(Tuple{typeof(Base.isempty), Array{String, 1}}) -precompile(Tuple{typeof(Base.isempty), Core.SimpleVector}) -precompile(Tuple{typeof(Base.isempty), NamedTuple{(), Tuple{}}}) -precompile(Tuple{typeof(Base.isempty), Nothing}) -precompile(Tuple{typeof(Base.isempty), REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(Base.isempty), String}) -precompile(Tuple{typeof(Base.isequal), REPL.LineEdit.Prompt, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(Base.isequal), String, Symbol}) -precompile(Tuple{typeof(Base.issingletontype), Type{Base.Regex}}) -precompile(Tuple{typeof(Base.iterate), Array{AbstractString, 1}, Int64}) -precompile(Tuple{typeof(Base.iterate), Array{AbstractString, 1}}) -precompile(Tuple{typeof(Base.iterate), Array{Base.StackTraces.StackFrame, 1}, Int64}) -precompile(Tuple{typeof(Base.iterate), Array{Base.StackTraces.StackFrame, 1}}) -precompile(Tuple{typeof(Base.iterate), Array{REPL.LineEdit.TextInterface, 1}, Int64}) -precompile(Tuple{typeof(Base.iterate), Array{REPL.LineEdit.TextInterface, 1}}) -precompile(Tuple{typeof(Base.iterate), Base.Dict{String, String}, Int64}) -precompile(Tuple{typeof(Base.iterate), Base.Dict{String, String}}) -precompile(Tuple{typeof(Base.iterate), Base.OneTo{Int64}, Int64}) -precompile(Tuple{typeof(Base.iterate), Base.OneTo{Int64}}) -precompile(Tuple{typeof(Base.iterate), Nothing}) -precompile(Tuple{typeof(Base.iterate), Tuple{Int64, Int64}, Int64}) -precompile(Tuple{typeof(Base.iterate), Tuple{Int64, Int64}}) -precompile(Tuple{typeof(Base.last), Base.OneTo{Int64}}) -precompile(Tuple{typeof(Base.lastindex), Array{AbstractString, 1}}) -precompile(Tuple{typeof(Base.lastindex), Array{String, 1}}) -precompile(Tuple{typeof(Base.lastindex), Core.SimpleVector}) -precompile(Tuple{typeof(Base.lastindex), String}) -precompile(Tuple{typeof(Base.lastindex), Tuple{Symbol}}) -precompile(Tuple{typeof(Base.leading_ones), UInt8}) -precompile(Tuple{typeof(Base.length), Array{AbstractString, 1}}) -precompile(Tuple{typeof(Base.length), Array{Int32, 1}}) -precompile(Tuple{typeof(Base.length), Array{Symbol, 1}}) -precompile(Tuple{typeof(Base.length), Tuple{DataType, DataType}}) -precompile(Tuple{typeof(Base.map), typeof(Base.names), Array{Any, 1}}) -precompile(Tuple{typeof(Base.merge), Base.Dict{String, Any}, Base.Dict{String, Any}}) -precompile(Tuple{typeof(Base.merge), NamedTuple{(), Tuple{}}, NamedTuple{(), Tuple{}}}) -precompile(Tuple{typeof(Base.min), Int64, Int64}) -precompile(Tuple{typeof(Base.nextind), String, Int64}) -precompile(Tuple{typeof(Base.occursin), Base.Regex, Base.SubString{String}}) -precompile(Tuple{typeof(Base.occursin), String, String}) -precompile(Tuple{typeof(Base.open), Base.CmdRedirect, String, Base.TTY}) -precompile(Tuple{typeof(Base.open), String, String}) -precompile(Tuple{typeof(Base.poptask)}) -precompile(Tuple{typeof(Base.position), Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{typeof(Base.precompilableerror), LoadError, Bool}) -precompile(Tuple{typeof(Base.preserve_handle), Base.Timer}) -precompile(Tuple{typeof(Base.prevind), String, Int64}) -precompile(Tuple{typeof(Base.print), Base.GenericIOBuffer{Array{UInt8, 1}}, Base.UUID}) -precompile(Tuple{typeof(Base.print), Base.GenericIOBuffer{Array{UInt8, 1}}, String, Base.SubString{String}, String}) -precompile(Tuple{typeof(Base.print), Base.GenericIOBuffer{Array{UInt8, 1}}, String, String, String, String, String, String, String}) -precompile(Tuple{typeof(Base.print), Base.GenericIOBuffer{Array{UInt8, 1}}, Type{Int64}}) -precompile(Tuple{typeof(Base.print), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Base.SubString{String}}) -precompile(Tuple{typeof(Base.print), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Char, String, String}) -precompile(Tuple{typeof(Base.print), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Char}) -precompile(Tuple{typeof(Base.print), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Module, String, Symbol}) -precompile(Tuple{typeof(Base.print), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, String, String}) -precompile(Tuple{typeof(Base.print), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, String, Symbol, String, Int32}) -precompile(Tuple{typeof(Base.print), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, String, Symbol}) -precompile(Tuple{typeof(Base.print), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, String}) -precompile(Tuple{typeof(Base.print), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Symbol}) -precompile(Tuple{typeof(Base.print), Base.IOContext{REPL.Terminals.TTYTerminal}, Char, String, String}) -precompile(Tuple{typeof(Base.print), Base.IOContext{REPL.Terminals.TTYTerminal}, Char}) -precompile(Tuple{typeof(Base.print), Base.IOContext{REPL.Terminals.TTYTerminal}, String, String, String, String}) -precompile(Tuple{typeof(Base.print), Base.IOContext{REPL.Terminals.TTYTerminal}, String, Type{Module}}) -precompile(Tuple{typeof(Base.print), Base.IOContext{REPL.Terminals.TTYTerminal}, String}) -precompile(Tuple{typeof(Base.print), Base.IOContext{REPL.Terminals.TTYTerminal}, Type{Module}}) -precompile(Tuple{typeof(Base.print), Base.IOStream, Char}) -precompile(Tuple{typeof(Base.print), Base.IOStream, String}) -precompile(Tuple{typeof(Base.print), Base.TTY, Char}) -precompile(Tuple{typeof(Base.print), Base.TTY, String}) -precompile(Tuple{typeof(Base.print), REPL.Terminals.TTYTerminal, String}) -precompile(Tuple{typeof(Base.print_matrix_row), Base.IOContext{REPL.Terminals.TTYTerminal}, Array{Float64, 1}, Array{Tuple{Int64, Int64}, 1}, Int64, Base.OneTo{Int64}, String}) -precompile(Tuple{typeof(Base.print_matrix_row), Base.IOContext{REPL.Terminals.TTYTerminal}, Array{Float64, 2}, Array{Tuple{Int64, Int64}, 1}, Int64, Base.OneTo{Int64}, String}) -precompile(Tuple{typeof(Base.print_matrix_row), Base.IOContext{REPL.Terminals.TTYTerminal}, Array{Int64, 1}, Array{Tuple{Int64, Int64}, 1}, Int64, Base.OneTo{Int64}, String}) -precompile(Tuple{typeof(Base.print_to_string), Type{Any}}) -precompile(Tuple{typeof(Base.println), Base.TTY}) -precompile(Tuple{typeof(Base.println), REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(Base.println), String}) -precompile(Tuple{typeof(Base.promote_eltype), Array{Symbol, 1}, Array{String, 1}}) -precompile(Tuple{typeof(Base.promote_eltype), Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{String, 1}}) -precompile(Tuple{typeof(Base.push!), Array{Base.Docs.DocStr, 1}, Base.Docs.DocStr}) -precompile(Tuple{typeof(Base.push!), Array{Base.Docs.MultiDoc, 1}, Base.Docs.MultiDoc}) -precompile(Tuple{typeof(Base.push!), Array{Base.Pair{Base.PkgId, UInt64}, 1}, Base.Pair{Base.PkgId, UInt64}}) -precompile(Tuple{typeof(Base.push!), Array{Char, 1}, Char}) -precompile(Tuple{typeof(Base.push!), Array{Symbol, 1}, Symbol}) -precompile(Tuple{typeof(Base.push!), Array{Tuple{String, Int64}, 1}, Tuple{String, Int64}}) -precompile(Tuple{typeof(Base.push!), Base.Set{Any}, Char}) -precompile(Tuple{typeof(Base.push!), Base.Set{Any}, Tuple{Module, String, Float64}}) -precompile(Tuple{typeof(Base.push!), Base.Set{REPL.REPLCompletions.Completion}, REPL.REPLCompletions.PackageCompletion}) -precompile(Tuple{typeof(Base.push!), Base.Set{String}, Base.SubString{String}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{ArgumentError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{Array{Float64, 1}, Nothing}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{Array{Float64, 2}, Nothing}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{Array{Int64, 1}, Nothing}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{ErrorException, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{Float64, Nothing}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{Int64, Nothing}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{Markdown.MD, Nothing}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{MethodError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{Nothing, Nothing}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{String, Nothing}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{UndefVarError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}}) -precompile(Tuple{typeof(Base.rand), Int64, Int64}) -precompile(Tuple{typeof(Base.rand), Int64}) -precompile(Tuple{typeof(Base.rand), Random.RandomDevice, Type{UInt32}, Int64}) -precompile(Tuple{typeof(Base.rand)}) -precompile(Tuple{typeof(Base.read!), Base.GenericIOBuffer{Array{UInt8, 1}}, Array{UInt8, 1}}) -precompile(Tuple{typeof(Base.read), Base.TTY, Type{UInt8}}) -precompile(Tuple{typeof(Base.readuntil), Base.PipeEndpoint, Char}) -precompile(Tuple{typeof(Base.readuntil), Base.TTY, String}) -precompile(Tuple{typeof(Base.readuntil), REPL.Terminals.TTYTerminal, String}) -precompile(Tuple{typeof(Base.reinterpret), Type{Char}, UInt32}) -precompile(Tuple{typeof(Base.replace), Base.SubString{String}, Base.Pair{Base.Regex, String}}) -precompile(Tuple{typeof(Base.resize!), Array{Tuple{String, Int64}, 1}, Int64}) -precompile(Tuple{typeof(Base.rethrow)}) -precompile(Tuple{typeof(Base.seek), Base.GenericIOBuffer{Array{UInt8, 1}}, Int64}) -precompile(Tuple{typeof(Base.setindex!), Array{Any, 1}, Array{String, 1}, Base.UnitRange{Int64}}) -precompile(Tuple{typeof(Base.setindex!), Array{Any, 1}, Array{Symbol, 1}, Base.UnitRange{Int64}}) -precompile(Tuple{typeof(Base.setindex!), Array{Base.StackTraces.StackFrame, 1}, Base.StackTraces.StackFrame, Int64}) -precompile(Tuple{typeof(Base.setindex!), Array{Method, 1}, Method, Int64}) -precompile(Tuple{typeof(Base.setindex!), Array{String, 1}, String, Int64}) -precompile(Tuple{typeof(Base.setindex!), Array{Symbol, 1}, Symbol, Int64}) -precompile(Tuple{typeof(Base.setindex!), Array{Union{Nothing, String}, 1}, String, Int64}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Any, Any}, Char, Char}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Any, Any}, Char, String}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Any, Any}, Module, Symbol}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Any, Any}, Type{Union{}}, Symbol}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Symbol, Any}, REPL.LineEdit.Prompt, Symbol}) -precompile(Tuple{typeof(Base.setindex!), Base.RefValue{Bool}, Bool}) -precompile(Tuple{typeof(Base.setproperty!), Base.Iterators.Stateful{Tuple{String, String}, Any}, Symbol, Tuple{String, Int64}}) -precompile(Tuple{typeof(Base.setproperty!), Base.Process, Symbol, Ptr{Nothing}}) -precompile(Tuple{typeof(Base.setproperty!), Base.Process, Symbol, Symbol}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.MIState, Symbol, Symbol}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixHistoryPrompt, Symbol, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixSearchState, Symbol, Int64}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixSearchState, Symbol, REPL.LineEdit.MIState}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixSearchState, Symbol, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixSearchState, Symbol, String}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.Prompt, Symbol, Base.Dict{Char, Any}}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PromptState, Symbol, Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PromptState, Symbol, REPL.LineEdit.InputAreaState}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.SearchState, Symbol, Bool}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.SearchState, Symbol, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(Base.setproperty!), REPL.LineEditREPL, Symbol, Bool}) -precompile(Tuple{typeof(Base.setproperty!), REPL.REPLHistoryProvider, Symbol, Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{typeof(Base.setproperty!), REPL.REPLHistoryProvider, Symbol, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(Base.show), Base.GenericIOBuffer{Array{UInt8, 1}}, Array{String, 1}}) -precompile(Tuple{typeof(Base.show), Base.GenericIOBuffer{Array{UInt8, 1}}, String}) -precompile(Tuple{typeof(Base.show), Base.GenericIOBuffer{Array{UInt8, 1}}, Type{Any}}) -precompile(Tuple{typeof(Base.show), Base.GenericIOBuffer{Array{UInt8, 1}}, UInt64}) -precompile(Tuple{typeof(Base.show), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Array{Any, 1}}) -precompile(Tuple{typeof(Base.show), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Int64}) -precompile(Tuple{typeof(Base.show), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, String}) -precompile(Tuple{typeof(Base.show), Base.IOContext{REPL.Terminals.TTYTerminal}, Base.MIME{Symbol("text/plain")}, Array{Float64, 1}}) -precompile(Tuple{typeof(Base.show), Base.IOContext{REPL.Terminals.TTYTerminal}, Base.MIME{Symbol("text/plain")}, Array{Float64, 2}}) -precompile(Tuple{typeof(Base.show), Base.IOContext{REPL.Terminals.TTYTerminal}, Base.MIME{Symbol("text/plain")}, Array{Int64, 1}}) -precompile(Tuple{typeof(Base.show), Base.IOContext{REPL.Terminals.TTYTerminal}, Base.MIME{Symbol("text/plain")}, Float64}) -precompile(Tuple{typeof(Base.show), Base.IOContext{REPL.Terminals.TTYTerminal}, Base.MIME{Symbol("text/plain")}, Int64}) -precompile(Tuple{typeof(Base.show), Base.IOContext{REPL.Terminals.TTYTerminal}, Base.MIME{Symbol("text/plain")}, Markdown.MD}) -precompile(Tuple{typeof(Base.show), Base.IOContext{REPL.Terminals.TTYTerminal}, Base.MIME{Symbol("text/plain")}, String}) -precompile(Tuple{typeof(Base.show), Base.IOContext{REPL.Terminals.TTYTerminal}, Int64}) -precompile(Tuple{typeof(Base.show), Base.IOContext{REPL.Terminals.TTYTerminal}, Type{Module}}) -precompile(Tuple{typeof(Base.show_datatype), Base.IOContext{REPL.Terminals.TTYTerminal}, Type{Module}}) -precompile(Tuple{typeof(Base.show_tuple_as_call), Base.IOContext{REPL.Terminals.TTYTerminal}, Symbol, Type{Tuple{typeof(Base.require), Module, Symbol}}}) -precompile(Tuple{typeof(Base.showerror), Base.IOContext{REPL.Terminals.TTYTerminal}, ArgumentError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}) -precompile(Tuple{typeof(Base.showerror), Base.IOContext{REPL.Terminals.TTYTerminal}, ErrorException, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}) -precompile(Tuple{typeof(Base.showerror), Base.IOContext{REPL.Terminals.TTYTerminal}, MethodError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}) -precompile(Tuple{typeof(Base.showerror), Base.IOContext{REPL.Terminals.TTYTerminal}, UndefVarError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}}) -precompile(Tuple{typeof(Base.similar), Array{Any, 1}, Type{Nothing}, Tuple{Base.OneTo{Int64}}}) -precompile(Tuple{typeof(Base.similar), Array{Base.Docs.DocStr, 1}, Type{Markdown.MD}, Tuple{Base.OneTo{Int64}}}) -precompile(Tuple{typeof(Base.similar), Array{REPL.REPLCompletions.Completion, 1}, Type{String}, Tuple{Base.OneTo{Int64}}}) -precompile(Tuple{typeof(Base.similar), Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}, Type{Array{Base.StackTraces.StackFrame, 1}}, Tuple{Base.OneTo{Int64}}}) -precompile(Tuple{typeof(Base.similar), Type{Array{Method, N} where N}, Tuple{Base.OneTo{Int64}}}) -precompile(Tuple{typeof(Base.sizeof), String}) -precompile(Tuple{typeof(Base.skip_deleted_floor!), Base.Dict{Symbol, Any}}) -precompile(Tuple{typeof(Base.sort!), Array{Int64, 1}, Base.Sort.QuickSortAlg, Base.Order.Perm{Base.Order.ForwardOrdering, Array{Tuple{Float64, Int64}, 1}}}) -precompile(Tuple{typeof(Base.startswith), Base.SubString{String}, String}) -precompile(Tuple{typeof(Base.startswith), String, Char}) -precompile(Tuple{typeof(Base.stream_wait), Base.Timer, Base.Condition}) -precompile(Tuple{typeof(Base.string), String, Nothing, String, String, String, Int64}) -precompile(Tuple{typeof(Base.string), String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, Base.VersionNumber, String, String, String, String, String, String, String, String, String, String, String, String, String, String}) -precompile(Tuple{typeof(Base.string), String, Type{Int64}}) -precompile(Tuple{typeof(Base.string), Type{Any}}) -precompile(Tuple{typeof(Base.strip), String}) -precompile(Tuple{typeof(Base.take!), Base.Channel{Any}}) -precompile(Tuple{typeof(Base.take!), Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{typeof(Base.task_done_hook), Task}) -precompile(Tuple{typeof(Base.time_print), UInt64, Int64, Int64, Int64}) -precompile(Tuple{typeof(Base.truncate), Base.GenericIOBuffer{Array{UInt8, 1}}, Int64}) -precompile(Tuple{typeof(Base.try_yieldto), typeof(Base.ensure_rescheduled), Base.RefValue{Task}}) -precompile(Tuple{typeof(Base.tuple_type_head), Type{Tuple{Vararg{Int64, N}} where N}}) -precompile(Tuple{typeof(Base.tuple_type_tail), Type{Tuple{Vararg{Int64, N}} where N}}) -precompile(Tuple{typeof(Base.typed_vcat), Type{Any}, Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{String, 1}}) -precompile(Tuple{typeof(Base.typeinfo_eltype), Type{Any}}) -precompile(Tuple{typeof(Base.typesof), Int64, Int64}) -precompile(Tuple{typeof(Base.unique), Array{Any, 1}}) -precompile(Tuple{typeof(Base.unlock), Base.Threads.RecursiveTatasLock}) -precompile(Tuple{typeof(Base.unpreserve_handle), Base.Timer}) -precompile(Tuple{typeof(Base.unsafe_convert), Type{Ptr{Int64}}, Base.Threads.Atomic{Int64}}) -precompile(Tuple{typeof(Base.unsafe_convert), Type{Ptr{Nothing}}, Ptr{Nothing}}) -precompile(Tuple{typeof(Base.unsafe_convert), Type{Ptr{UInt64}}, Base.Threads.Atomic{UInt64}}) -precompile(Tuple{typeof(Base.unsafe_write), Base.Pipe, Ptr{UInt8}, UInt64}) -precompile(Tuple{typeof(Base.unsafe_write), Base.TTY, Ptr{UInt8}, Int32}) -precompile(Tuple{typeof(Base.unsafe_write), Base.TTY, Ptr{UInt8}, UInt64}) -precompile(Tuple{typeof(Base.uvfinalize), Base.PipeEndpoint}) -precompile(Tuple{typeof(Base.uvfinalize), Base.Process}) -precompile(Tuple{typeof(Base.uvfinalize), Base.TTY}) -precompile(Tuple{typeof(Base.uvfinalize), Base.Timer}) -precompile(Tuple{typeof(Base.vcat), Array{Any, 1}, String, String}) -precompile(Tuple{typeof(Base.vcat), Array{Base.StackTraces.StackFrame, 1}, Array{Base.StackTraces.StackFrame, 1}, Array{Base.StackTraces.StackFrame, 1}, Array{Base.StackTraces.StackFrame, 1}, Array{Base.StackTraces.StackFrame, 1}, Array{Base.StackTraces.StackFrame, 1}, Array{Base.StackTraces.StackFrame, 1}, Array{Base.StackTraces.StackFrame, 1}, Array{Base.StackTraces.StackFrame, 1}, Array{Base.StackTraces.StackFrame, 1}, Array{Base.StackTraces.StackFrame, 1}, Array{Base.StackTraces.StackFrame, 1}}) -precompile(Tuple{typeof(Base.vcat), Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{String, 1}}) -precompile(Tuple{typeof(Base.vcat), Markdown.MD, Markdown.MD}) -precompile(Tuple{typeof(Base.vcat), Markdown.MD}) -precompile(Tuple{typeof(Base.vect), Symbol, Vararg{Symbol, N} where N}) -precompile(Tuple{typeof(Base.wait), Base.Condition}) -precompile(Tuple{typeof(Base.wait), Base.Timer}) -precompile(Tuple{typeof(Base.wait)}) -precompile(Tuple{typeof(Base.write), Base.GenericIOBuffer{Array{UInt8, 1}}, String}) -precompile(Tuple{typeof(Base.write), Base.IOStream, Array{UInt8, 1}}) -precompile(Tuple{typeof(Base.write), Base.Pipe, String}) -precompile(Tuple{typeof(Base.write), Base.Process, String}) -precompile(Tuple{typeof(Base.write), Base.TTY, Char}) -precompile(Tuple{typeof(Base.write), Base.TTY, String}) -precompile(Tuple{typeof(Base.write), Base.TTY, UInt8}) -precompile(Tuple{typeof(Base.write), REPL.Terminals.TTYTerminal, String}) -precompile(Tuple{typeof(Base.write), REPL.Terminals.TerminalBuffer, Base.Missing}) -precompile(Tuple{typeof(Base.write), REPL.Terminals.TerminalBuffer, String}) -precompile(Tuple{typeof(Core.Compiler.:(!=)), Type{Any}, Core.Compiler.Const}) -precompile(Tuple{typeof(Core.Compiler.getindex), Array{DataType, 1}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Array{Bool, 0}}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Array{String, 1}}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Broadcast.DefaultArrayStyle{0}, typeof(Base.identity), Int64}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Colon}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), typeof(Base.Multimedia.display)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), typeof(Base.__atreplinit)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), typeof(Base.display_error)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), typeof(Base.show)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), typeof(REPL.helpmode)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Val{1}, Union}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Char, Char}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Core.Compiler.IndexLinear, Array{Bool, 0}}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Nothing, Nothing}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Nothing, typeof(Base.replace), Nothing}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{QuoteNode, Int64}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{String, Int64}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Symbol, Bool}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Symbol, GlobalRef}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.:(*)), Int64}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.Multimedia.display), Int64}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.convert), Int64}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.convert), typeof(Base.getindex), typeof(Base.setindex!)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.getindex), typeof(Base.setindex!)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.open_flags)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.setindex!)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Type{Any}, Core.SSAValue, Char, Core.SSAValue}) -precompile(Tuple{typeof(Core.Compiler.getindex), Type{Any}, Core.SSAValue, Core.Compiler.Argument, Core.Compiler.Argument, Core.SSAValue, Core.SSAValue}) -precompile(Tuple{typeof(Core.Compiler.getindex), Type{Any}, Core.SSAValue, Core.SSAValue, Int64, Core.SSAValue, Core.SSAValue}) -precompile(Tuple{typeof(Core.Compiler.getindex), Type{Any}, Core.SSAValue, Core.SSAValue, String, Core.SSAValue}) -precompile(Tuple{typeof(Core.Compiler.getindex), Type{Any}, Core.SSAValue, Int64, Core.SSAValue}) -precompile(Tuple{typeof(Core.Compiler.getindex), Type{Any}, Core.SSAValue, UInt8, Core.SSAValue}) -precompile(Tuple{typeof(Core.Compiler.getindex), Type{Any}, Tuple{Symbol}, Tuple{Symbol, Symbol, Symbol, Symbol, Symbol, Symbol, Symbol}}) -precompile(Tuple{typeof(Core.Compiler.getindex), Type{Any}, getfield(Markdown, Symbol("#kw##print_wrapped")), Core.SSAValue, Core.SSAValue, Core.SSAValue, Core.Compiler.Argument, Core.SSAValue}) -precompile(Tuple{typeof(Core.Compiler.instanceof_tfunc), Any}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Array{Bool, 0}}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Array{String, 1}}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Base.Broadcast.DefaultArrayStyle{0}, typeof(Base.identity), Int64}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Base.Colon}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), typeof(Base.Multimedia.display)}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), typeof(Base.__atreplinit)}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), typeof(Base.display_error)}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), typeof(Base.show)}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), typeof(REPL.helpmode)}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Base.Val{1}, Union}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Char, Char}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Core.Compiler.IndexLinear, Array{Bool, 0}}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Nothing, Nothing}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Nothing, typeof(Base.replace), Nothing}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Symbol, Bool}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{Symbol, GlobalRef}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{typeof(Base.:(*)), Int64}}) -precompile(Tuple{typeof(Core.Compiler.length), Tuple{typeof(Base.open_flags)}}) -precompile(Tuple{typeof(Core.Compiler.rewrap_unionall), Any, Any}) -precompile(Tuple{typeof(Core.Compiler.vect), Type{typeof(typeassert)}}) -precompile(Tuple{typeof(Distributed.flush_gc_msgs), Distributed.Worker}) -precompile(Tuple{typeof(Distributed.flush_gc_msgs)}) -precompile(Tuple{typeof(Distributed.terminate_all_workers)}) -precompile(Tuple{typeof(LibGit2.ensure_initialized)}) -precompile(Tuple{typeof(LibGit2.initialize)}) -precompile(Tuple{typeof(Logging.__init__)}) -precompile(Tuple{typeof(Logging.default_metafmt), Base.CoreLogging.LogLevel, Module, Symbol, Symbol, String, Int64}) -precompile(Tuple{typeof(Logging.default_metafmt), Base.CoreLogging.LogLevel, Nothing, Symbol, Symbol, String, Int64}) -precompile(Tuple{typeof(Markdown.ansi_length), Base.SubString{String}}) -precompile(Tuple{typeof(Markdown.ansi_length), String}) -precompile(Tuple{typeof(Markdown.footnote_link), Base.GenericIOBuffer{Array{UInt8, 1}}, Markdown.MD}) -precompile(Tuple{typeof(Markdown.link), Base.GenericIOBuffer{Array{UInt8, 1}}, Markdown.MD}) -precompile(Tuple{typeof(Markdown.term), Base.IOContext{REPL.Terminals.TTYTerminal}, Markdown.Code, Int64}) -precompile(Tuple{typeof(Markdown.term), Base.IOContext{REPL.Terminals.TTYTerminal}, Markdown.Header{1}, Int64}) -precompile(Tuple{typeof(Markdown.term), Base.IOContext{REPL.Terminals.TTYTerminal}, Markdown.HorizontalRule, Int64}) -precompile(Tuple{typeof(Markdown.term), Base.IOContext{REPL.Terminals.TTYTerminal}, Markdown.MD, Int64}) -precompile(Tuple{typeof(Markdown.term), Base.IOContext{REPL.Terminals.TTYTerminal}, Markdown.Paragraph, Int64}) -precompile(Tuple{typeof(Markdown.terminline), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Array{Any, 1}}) -precompile(Tuple{typeof(Markdown.terminline), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Markdown.Code}) -precompile(Tuple{typeof(Markdown.terminline), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Markdown.Link}) -precompile(Tuple{typeof(Markdown.terminline), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, String}) -precompile(Tuple{typeof(Markdown.terminline_string), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Array{Any, 1}}) -precompile(Tuple{typeof(Markdown.terminline_string), Base.IOContext{REPL.Terminals.TTYTerminal}, Array{Any, 1}}) -precompile(Tuple{typeof(Pkg.REPLMode.create_mode), REPL.LineEditREPL, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(Pkg.REPLMode.repl_init), REPL.LineEditREPL}) -precompile(Tuple{typeof(REPL.LineEdit.accept_result), REPL.LineEdit.MIState, REPL.LineEdit.PrefixHistoryPrompt}) -precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.HistoryPrompt, REPL.LineEdit.SearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.PrefixHistoryPrompt, REPL.LineEdit.PrefixSearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.Prompt, REPL.LineEdit.MIState, REPL.Terminals.TTYTerminal, REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.Prompt, REPL.LineEdit.PromptState, REPL.Terminals.TTYTerminal, REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.Prompt, REPL.LineEdit.PromptState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(REPL.LineEdit.activate_region), REPL.LineEdit.MIState, Symbol}) -precompile(Tuple{typeof(REPL.LineEdit.buffer), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.buffer), REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.cancel_beep), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.cancel_beep), REPL.LineEdit.PrefixSearchState}) -precompile(Tuple{typeof(REPL.LineEdit.cancel_beep), REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.cancel_beep), REPL.LineEdit.SearchState}) -precompile(Tuple{typeof(REPL.LineEdit.commit_changes), REPL.Terminals.TTYTerminal, REPL.Terminals.TerminalBuffer}) -precompile(Tuple{typeof(REPL.LineEdit.common_prefix), Array{String, 1}}) -precompile(Tuple{typeof(REPL.LineEdit.complete_line), REPL.LineEdit.PromptState, Int64}) -precompile(Tuple{typeof(REPL.LineEdit.complete_line), REPL.REPLCompletionProvider, REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.HistoryPrompt, REPL.LineEdit.SearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.PrefixHistoryPrompt, REPL.LineEdit.PrefixSearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.Prompt, REPL.LineEdit.PromptState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(REPL.LineEdit.deactivate_region), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.deactivate_region), REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.default_enter_cb), REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.edit_abort), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.edit_backspace), REPL.LineEdit.PromptState, Bool, Bool}) -precompile(Tuple{typeof(REPL.LineEdit.edit_delete), Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{typeof(REPL.LineEdit.edit_delete), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.edit_insert), Base.GenericIOBuffer{Array{UInt8, 1}}, Base.SubString{String}}) -precompile(Tuple{typeof(REPL.LineEdit.edit_splice!), REPL.LineEdit.PromptState, Base.Pair{Int64, Int64}, String}) -precompile(Tuple{typeof(REPL.LineEdit.eval), Module, Expr}) -precompile(Tuple{typeof(REPL.LineEdit.history_next_prefix), REPL.LineEdit.PrefixSearchState, REPL.REPLHistoryProvider, String}) -precompile(Tuple{typeof(REPL.LineEdit.history_prev_prefix), REPL.LineEdit.PrefixSearchState, REPL.REPLHistoryProvider, String}) -precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.HistoryPrompt}) -precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.ModalInterface}) -precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.PrefixHistoryPrompt}) -precompile(Tuple{typeof(REPL.LineEdit.is_region_active), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.keymap), REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PrefixHistoryPrompt}) -precompile(Tuple{typeof(REPL.LineEdit.keymap), REPL.LineEdit.SearchState, REPL.LineEdit.HistoryPrompt}) -precompile(Tuple{typeof(REPL.LineEdit.keymap_data), REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PrefixHistoryPrompt}) -precompile(Tuple{typeof(REPL.LineEdit.keymap_data), REPL.LineEdit.SearchState, REPL.LineEdit.HistoryPrompt}) -precompile(Tuple{typeof(REPL.LineEdit.match_input), Base.Dict{Char, Any}, REPL.LineEdit.MIState, Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{typeof(REPL.LineEdit.match_input), Base.Dict{Char, Any}, REPL.LineEdit.MIState, REPL.Terminals.TTYTerminal, Array{Char, 1}, Base.Dict{Char, Any}}) -precompile(Tuple{typeof(REPL.LineEdit.match_input), Base.Dict{Char, Any}, REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.match_input), Function, REPL.LineEdit.MIState, REPL.Terminals.TTYTerminal, Array{Char, 1}, Base.Dict{Char, Any}}) -precompile(Tuple{typeof(REPL.LineEdit.mode), REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.options), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.options), REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.pop_undo), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.prompt_string), typeof(Base.input_color)}) -precompile(Tuple{typeof(REPL.LineEdit.push_undo), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.refresh_multi_line), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.refresh_multi_line), REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.refresh_multi_line), REPL.Terminals.TTYTerminal, REPL.LineEdit.PrefixSearchState}) -precompile(Tuple{typeof(REPL.LineEdit.refresh_multi_line), REPL.Terminals.TTYTerminal, REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.refresh_multi_line), REPL.Terminals.TTYTerminal, REPL.LineEdit.SearchState}) -precompile(Tuple{typeof(REPL.LineEdit.refresh_multi_line), REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal, Base.GenericIOBuffer{Array{UInt8, 1}}, REPL.LineEdit.InputAreaState, String}) -precompile(Tuple{typeof(REPL.LineEdit.refresh_multi_line), REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal, REPL.LineEdit.PrefixSearchState}) -precompile(Tuple{typeof(REPL.LineEdit.refresh_multi_line), REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal, REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.region_active), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.replace_line), REPL.LineEdit.MIState, String}) -precompile(Tuple{typeof(REPL.LineEdit.replace_line), REPL.LineEdit.PromptState, Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{typeof(REPL.LineEdit.reset_state), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.reset_state), REPL.LineEdit.PrefixSearchState}) -precompile(Tuple{typeof(REPL.LineEdit.reset_state), REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.reset_state), REPL.LineEdit.SearchState}) -precompile(Tuple{typeof(REPL.LineEdit.reset_state), REPL.REPLHistoryProvider}) -precompile(Tuple{typeof(REPL.LineEdit.run_interface), REPL.Terminals.TTYTerminal, REPL.LineEdit.ModalInterface, REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.set_action!), REPL.LineEdit.MIState, Symbol}) -precompile(Tuple{typeof(REPL.LineEdit.setmark), REPL.LineEdit.MIState, Bool}) -precompile(Tuple{typeof(REPL.LineEdit.setup_prefix_keymap), REPL.REPLHistoryProvider, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(REPL.LineEdit.setup_search_keymap), REPL.REPLHistoryProvider}) -precompile(Tuple{typeof(REPL.LineEdit.show_completions), REPL.LineEdit.PromptState, Array{String, 1}}) -precompile(Tuple{typeof(REPL.LineEdit.terminal), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.terminal), REPL.LineEdit.PrefixSearchState}) -precompile(Tuple{typeof(REPL.LineEdit.terminal), REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.terminal), REPL.LineEdit.SearchState}) -precompile(Tuple{typeof(REPL.REPLCompletions.completion_text), REPL.REPLCompletions.PackageCompletion}) -precompile(Tuple{typeof(REPL.REPLCompletions.completions), String, Int64, Module}) -precompile(Tuple{typeof(REPL.REPLCompletions.get_type), Symbol, Module}) -precompile(Tuple{typeof(REPL.REPLCompletions.get_value), Symbol, Module}) -precompile(Tuple{typeof(REPL.Terminals.beep), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.Terminals.beep), REPL.LineEdit.PromptState, Float64, Float64, Float64}) -precompile(Tuple{typeof(REPL.Terminals.beep), REPL.LineEdit.SearchState}) -precompile(Tuple{typeof(REPL.Terminals.cmove_col), REPL.Terminals.TTYTerminal, Int64}) -precompile(Tuple{typeof(REPL.Terminals.cmove_down), REPL.Terminals.TTYTerminal, Int64}) -precompile(Tuple{typeof(REPL.Terminals.hascolor), REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(REPL.Terminals.width), REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(Base.banner), REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(REPL.ends_with_semicolon), String}) -precompile(Tuple{typeof(REPL.eval), Module, Expr}) -precompile(Tuple{typeof(REPL.eval), Module, String}) -precompile(Tuple{typeof(REPL.eval_user_input), Any, REPL.REPLBackend}) -precompile(Tuple{typeof(REPL.eval_user_input), Expr, REPL.REPLBackend}) -precompile(Tuple{typeof(REPL.filtervalid), Array{Any, 1}}) -precompile(Tuple{typeof(REPL.fuzzysort), String, Array{String, 1}}) -precompile(Tuple{typeof(REPL.helpmode), Base.TTY, String}) -precompile(Tuple{typeof(REPL.helpmode), String}) -precompile(Tuple{typeof(REPL.hist_from_file), REPL.REPLHistoryProvider, Base.IOStream, String}) -precompile(Tuple{typeof(REPL.insert_hlines), Base.TTY, Markdown.MD}) -precompile(Tuple{typeof(REPL.lookup_doc), Symbol}) -precompile(Tuple{typeof(REPL.mode_idx), REPL.REPLHistoryProvider, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(REPL.prepare_next), REPL.LineEditREPL}) -precompile(Tuple{typeof(REPL.print_response), REPL.LineEditREPL, ArgumentError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}, Bool, Bool}) -precompile(Tuple{typeof(REPL.print_response), REPL.LineEditREPL, Markdown.MD, Nothing, Bool, Bool}) -precompile(Tuple{typeof(REPL.print_response), REPL.Terminals.TTYTerminal, ArgumentError, Array{Union{Ptr{Nothing}, Base.InterpreterIP}, 1}, Bool, Bool, Nothing}) -precompile(Tuple{typeof(REPL.print_response), REPL.Terminals.TTYTerminal, Markdown.MD, Nothing, Bool, Bool, Nothing}) -precompile(Tuple{typeof(REPL.repl), Base.TTY, Symbol}) -precompile(Tuple{typeof(REPL.repl_latex), Base.TTY, String}) -precompile(Tuple{typeof(REPL.repl_search), Base.TTY, String}) -precompile(Tuple{typeof(REPL.reset), REPL.LineEditREPL}) -precompile(Tuple{typeof(REPL.return_callback), REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.run_repl), REPL.LineEditREPL, typeof(x->nothing)}) -precompile(Tuple{typeof(REPL.send_to_backend), Expr, Base.Channel{Any}, Base.Channel{Any}}) -precompile(Tuple{typeof(REPL.send_to_backend), Expr, REPL.REPLBackendRef}) -precompile(Tuple{typeof(REPL.send_to_backend), String, Base.Channel{Any}, Base.Channel{Any}}) -precompile(Tuple{typeof(REPL.send_to_backend), String, REPL.REPLBackendRef}) -precompile(Tuple{typeof(REPL.send_to_backend), Symbol, Base.Channel{Any}, Base.Channel{Any}}) -precompile(Tuple{typeof(REPL.send_to_backend), Symbol, REPL.REPLBackendRef}) -precompile(Tuple{typeof(REPL.setup_interface), REPL.LineEditREPL, Bool, Array{Base.Dict{Any, Any}, 1}}) -precompile(Tuple{typeof(REPL.setup_interface), REPL.LineEditREPL, Bool, Base.Dict{Any, Any}}) -precompile(Tuple{typeof(REPL.setup_interface), REPL.LineEditREPL}) -precompile(Tuple{typeof(REPL.start_repl_backend), Base.Channel{Any}, Base.Channel{Any}}) -precompile(Tuple{typeof(Random.__init__)}) -precompile(Tuple{typeof(eval), Module, Expr}) diff --git a/stdlib/Pkg/src/Pkg.jl b/stdlib/Pkg/src/Pkg.jl index f5e34961758e0..940375c94af54 100644 --- a/stdlib/Pkg/src/Pkg.jl +++ b/stdlib/Pkg/src/Pkg.jl @@ -368,18 +368,9 @@ const precompile_script = """ ] activate . $CTRL_C Pkg.add("Test") # adding an stdlib doesn't require internet access + ] add Te\t\t$CTRL_C ] st $CTRL_C rm(tmp; recursive=true)""" -module PrecompileArea - import ..Pkg - using ..Types - using UUIDs - import LibGit2 - import REPL - import SHA - include("precompile.jl") -end - end # module diff --git a/stdlib/Pkg/src/precompile.jl b/stdlib/Pkg/src/precompile.jl deleted file mode 100644 index adfebb709a63f..0000000000000 --- a/stdlib/Pkg/src/precompile.jl +++ /dev/null @@ -1,431 +0,0 @@ -# This file is a part of Julia. License is MIT: https://julialang.org/license - -precompile(Tuple{Type{Base.Dict{K, V} where V where K}, Array{Base.Pair{A, B} where B where A, 1}}) -precompile(Tuple{Type{Base.Dict{Pkg.Types.VersionRange, Base.Dict{String, Base.UUID}}}}) -precompile(Tuple{Type{Base.Dict{Pkg.Types.VersionRange, Base.Dict{String, Pkg.Types.VersionSpec}}}}) -precompile(Tuple{Type{Base.Dict{String, Any}}, Base.Pair{String, String}}) -precompile(Tuple{Type{Base.Dict{String, Base.UUID}}}) -precompile(Tuple{Type{Base.Dict{String, Pkg.Types.VersionSpec}}}) -precompile(Tuple{Type{Base.Generator{I, F} where F where I}, Type{Base.UUID}, Base.ValueIterator{Base.Dict{String, Any}}}) -precompile(Tuple{Type{Base.Generator{I, F} where F where I}, Type{Base.UUID}, Base.ValueIterator{Base.Dict{String, String}}}) -precompile(Tuple{Type{Base.Generator{I, F} where F where I}, typeof(Base.close), Array{LibGit2.GitAnnotated, 1}}) -precompile(Tuple{Type{Base.Generator{I, F} where F where I}, typeof(Pkg.TOML.is_tabular), Base.ValueIterator{Base.Dict{String, Any}}}) -precompile(Tuple{Type{Base.Generator{I, F} where F where I}, typeof(Pkg.TOML.table2dict), Array{Any, 1}}) -precompile(Tuple{Type{Base.IOContext{IO_t} where IO_t<:IO}, Base.GenericIOBuffer{Array{UInt8, 1}}, Base.TTY}) -precompile(Tuple{Type{Base.Pair{A, B} where B where A}, Base.UUID, Int64}) -precompile(Tuple{Type{Base.Pair{A, B} where B where A}, Base.UUID, Pkg.Types.VersionSpec}) -precompile(Tuple{Type{Base.Pair{A, B} where B where A}, Base.VersionNumber, Base.SHA1}) -precompile(Tuple{Type{Base.Pair{A, B} where B where A}, String, Base.UUID}) -precompile(Tuple{Type{Base.SHA1}, Base.SubString{String}}) -precompile(Tuple{Type{Base.SHA1}, String}) -precompile(Tuple{Type{Char}, Int32}) -precompile(Tuple{Type{NamedTuple{(:by,), T} where T<:Tuple}, Tuple{typeof(Base.identity)}}) -precompile(Tuple{Type{NamedTuple{(:header, :color), T} where T<:Tuple}, Tuple{String, Symbol}}) -precompile(Tuple{Type{NamedTuple{(:indent, :region_active), T} where T<:Tuple}, Tuple{Int64, Bool}}) -precompile(Tuple{Type{NamedTuple{(:indent, :sorted, :by), T} where T<:Tuple}, Tuple{Int64, Bool, typeof(Base.identity)}}) -precompile(Tuple{Type{NamedTuple{(:init,), T} where T<:Tuple}, Tuple{Int64}}) -precompile(Tuple{Type{NamedTuple{(:mode,), T} where T<:Tuple}, Tuple{Symbol}}) -precompile(Tuple{Type{NamedTuple{(:transfer_progress, :credentials), T} where T<:Tuple}, Tuple{Ptr{Nothing}, Ptr{Nothing}}}) -precompile(Tuple{Type{Pkg.Display.DiffEntry}, Base.UUID, String, Pkg.Display.VerInfo, Pkg.Display.VerInfo}) -precompile(Tuple{Type{Pkg.Display.VerInfo}, Base.SHA1, Nothing, Base.VersionNumber, Bool, Nothing}) -precompile(Tuple{Type{Pkg.Display.VerInfo}, Base.SHA1, Nothing, Base.VersionNumber, Bool, Pkg.Types.GitRepo}) -precompile(Tuple{Type{Pkg.Display.VerInfo}, Nothing, Nothing, Nothing, Bool, Nothing}) -precompile(Tuple{Type{Pkg.Display.VerInfo}, Nothing, String, Base.VersionNumber, Bool, Nothing}) -precompile(Tuple{Type{Pkg.Types.EnvCache}, Nothing, Nothing, String, String, Nothing, Base.Dict{String, Any}, Base.Dict{String, Any}, Base.Dict{String, Array{Base.UUID, 1}}, Base.Dict{Base.UUID, Array{String, 1}}, Base.Dict{Base.UUID, Array{String, 1}}}) -precompile(Tuple{Type{Pkg.Types.GitRepo}, String, String, Base.SHA1}) -precompile(Tuple{Type{Pkg.Types.GitRepo}, String, String}) -precompile(Tuple{Type{Pkg.Types.PackageSpec}, Base.SubString{String}, Pkg.Types.VersionSpec}) -precompile(Tuple{Type{Pkg.Types.PackageSpec}, Base.SubString{String}}) -precompile(Tuple{Type{Pkg.Types.PackageSpec}, String, Base.UUID, Pkg.Types.VersionSpec}) -precompile(Tuple{Type{Pkg.Types.PackageSpec}, String}) -precompile(Tuple{Type{Pkg.Types.VersionBound}, Base.SubString{String}}) -precompile(Tuple{Type{Pkg.Types.VersionBound}, Int64, Int64}) -precompile(Tuple{Type{Pkg.Types.VersionBound}, Tuple{Int64, Int64, Int64}}) -precompile(Tuple{Type{Pkg.Types.VersionBound}, Tuple{Int64, Int64}}) -precompile(Tuple{Type{Pkg.Types.VersionBound}, Tuple{UInt32, UInt32}}) -precompile(Tuple{Type{Pkg.Types.VersionBound}, UInt32, UInt32}) -precompile(Tuple{Type{Pkg.Types.VersionRange}, Base.VersionNumber}) -precompile(Tuple{Type{Pkg.Types.VersionSpec}, String}) -precompile(Tuple{Type{REPL.LineEdit.PrefixSearchState}, REPL.Terminals.TTYTerminal, REPL.LineEdit.PrefixHistoryPrompt, String, Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{Type{REPL.LineEdit.PromptState}, REPL.Terminals.TTYTerminal, REPL.LineEdit.Prompt, Base.GenericIOBuffer{Array{UInt8, 1}}, Symbol, Array{Base.GenericIOBuffer{Array{UInt8, 1}}, 1}, Int64, REPL.LineEdit.InputAreaState, Int64, Base.Threads.TatasLock, Float64}) -precompile(Tuple{Type{REPL.LineEdit.SearchState}, REPL.Terminals.TTYTerminal, REPL.LineEdit.HistoryPrompt, Bool, Base.GenericIOBuffer{Array{UInt8, 1}}, Base.GenericIOBuffer{Array{UInt8, 1}}}) -precompile(Tuple{Type{REPL.REPLHistoryProvider}, Array{String, 1}, Nothing, Int64, Int64, Int64, Base.GenericIOBuffer{Array{UInt8, 1}}, Nothing, Base.Dict{Symbol, Any}, Array{UInt8, 1}}) -precompile(Tuple{Type{REPL.REPLHistoryProvider}, Base.Dict{Symbol, Any}}) -precompile(Tuple{getfield(Base, Symbol("#kw##printstyled")), NamedTuple{(:bold, :color), Tuple{Bool, Symbol}}, typeof(Base.printstyled), Base.TTY, String}) -precompile(Tuple{getfield(Base, Symbol("#kw##sort!")), NamedTuple{(:by,), Tuple{typeof(Base.Unicode.lowercase)}}, typeof(Base.sort!), Array{String, 1}}) -precompile(Tuple{getfield(Base, Symbol("#kw##sort!")), NamedTuple{(:by,), Tuple{typeof(Base.identity)}}, typeof(Base.sort!), Array{String, 1}}) -precompile(Tuple{getfield(Base.Cartesian, Symbol("#@nloops")), LineNumberNode, Module, Int64, Symbol, Expr, Expr, Expr}) -precompile(Tuple{getfield(Core, Symbol("#kw#Type")), NamedTuple{(:header, :color), Tuple{String, Symbol}}, Type{Pkg.GitTools.MiniProgressBar}}) -precompile(Tuple{getfield(Core, Symbol("#kw#Type")), NamedTuple{(:payload, :transfer_progress, :credentials), Tuple{Base.Dict{Symbol, Any}, Ptr{Nothing}, Ptr{Nothing}}}, Type{LibGit2.RemoteCallbacks}}) -precompile(Tuple{getfield(Pkg.API, Symbol("#kw##add_or_develop")), NamedTuple{(:mode,), Tuple{Symbol}}, typeof(Pkg.API.add_or_develop), Pkg.Types.Context, Array{Pkg.Types.PackageSpec, 1}}) -precompile(Tuple{getfield(Pkg.TOML, Symbol("#kw##_print")), NamedTuple{(:indent, :sorted, :by), Tuple{Int64, Bool, typeof(Base.identity)}}, typeof(Pkg.TOML._print), Base.IOStream, Base.Dict{String, Any}, Array{String, 1}}) -precompile(Tuple{getfield(Pkg.TOML, Symbol("#kw##print")), NamedTuple{(:sorted,), Tuple{Bool}}, typeof(Pkg.TOML.print), Base.IOStream, Base.Dict{String, Any}}) -precompile(Tuple{getfield(Pkg.TOML, Symbol("#kw##printvalue")), NamedTuple{(:sorted,), Tuple{Bool}}, typeof(Pkg.TOML.printvalue), Base.IOStream, Array{String, 1}}) -precompile(Tuple{getfield(Pkg.TOML, Symbol("#kw##printvalue")), NamedTuple{(:sorted,), Tuple{Bool}}, typeof(Pkg.TOML.printvalue), Base.IOStream, String}) -precompile(Tuple{getfield(REPL.LineEdit, Symbol("#kw##add_nested_key!")), NamedTuple{(:override,), Tuple{Bool}}, typeof(REPL.LineEdit.add_nested_key!), Base.Dict{Char, Any}, String, Nothing}) -precompile(Tuple{getfield(REPL.LineEdit, Symbol("#kw##refresh_multi_line")), NamedTuple{(:indent, :region_active), Tuple{Int64, Bool}}, typeof(REPL.LineEdit.refresh_multi_line), REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal, Base.GenericIOBuffer{Array{UInt8, 1}}, REPL.LineEdit.InputAreaState, REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(Base.:(!=)), Base.SubString{String}, Nothing}) -precompile(Tuple{typeof(Base.:(!=)), Base.UUID, Base.UUID}) -precompile(Tuple{typeof(Base.:(==)), Base.Dict{String, Any}, Nothing}) -precompile(Tuple{typeof(Base.:(==)), Base.SHA1, Nothing}) -precompile(Tuple{typeof(Base.:(==)), Base.UUID, Base.UUID}) -precompile(Tuple{typeof(Base.:(==)), Expr, Int64}) -precompile(Tuple{typeof(Base.:(==)), Nothing, Base.UUID}) -precompile(Tuple{typeof(Base.:(==)), Nothing, Nothing}) -precompile(Tuple{typeof(Base.:(==)), String, Nothing}) -precompile(Tuple{typeof(Base.:(==)), Symbol, Int64}) -precompile(Tuple{typeof(Base.Cartesian._nloops), Int64, Symbol, Expr, Expr, Expr}) -precompile(Tuple{typeof(Base.Cartesian.exprresolve), LineNumberNode}) -precompile(Tuple{typeof(Base.Cartesian.lreplace!), Int64, Base.Cartesian.LReplace{String}}) -precompile(Tuple{typeof(Base.Filesystem.ispath), String}) -precompile(Tuple{typeof(Base.Filesystem.mtime), String}) -precompile(Tuple{typeof(Base.Iterators.enumerate), Array{Base.VersionNumber, 1}}) -precompile(Tuple{typeof(Base._array_for), Type{Array{Base.BitArray{2}, 1}}, Base.UnitRange{Int64}, Base.HasShape{1}}) -precompile(Tuple{typeof(Base._array_for), Type{Array{Base.VersionNumber, 1}}, Base.UnitRange{Int64}, Base.HasShape{1}}) -precompile(Tuple{typeof(Base._array_for), Type{Base.BitArray{1}}, Base.UnitRange{Int64}, Base.HasShape{1}}) -precompile(Tuple{typeof(Base._array_for), Type{Base.BitArray{2}}, Base.UnitRange{Int64}, Base.HasShape{1}}) -precompile(Tuple{typeof(Base._array_for), Type{Base.Dict{Base.VersionNumber, Int64}}, Base.UnitRange{Int64}, Base.HasShape{1}}) -precompile(Tuple{typeof(Base._array_for), Type{Base.UUID}, Base.ValueIterator{Base.Dict{String, Any}}, Base.HasLength}) -precompile(Tuple{typeof(Base._collect), Array{Pkg.REPLMode.Statement, 1}, Base.Generator{Array{Pkg.REPLMode.Statement, 1}, Type{Pkg.REPLMode.PkgCommand}}, Base.EltypeUnknown, Base.HasShape{1}}) -precompile(Tuple{typeof(Base._compute_eltype), Type{Tuple{Array{String, 1}, LibGit2.CachedCredentials}}}) -precompile(Tuple{typeof(Base._compute_eltype), Type{Tuple{Bool, LibGit2.CachedCredentials}}}) -precompile(Tuple{typeof(Base._compute_eltype), Type{Tuple{Int32, Base.Cstring, Ptr{Nothing}}}}) -precompile(Tuple{typeof(Base._deepcopy_array_t), Array{Base.Dict{String, Any}, 1}, Type{Base.Dict{String, Any}}, Base.IdDict{Any, Any}}) -precompile(Tuple{typeof(Base._getindex), Base.IndexLinear, Base.BitArray{2}, Base.LogicalIndex{Int64, Base.BitArray{1}}, Int64}) -precompile(Tuple{typeof(Base._iterate), Base.Dict{String, Any}, Int64}) -precompile(Tuple{typeof(Base._promote_typejoin), Type{Any}, Type{Ptr{Nothing}}}) -precompile(Tuple{typeof(Base._promote_typejoin), Type{Array{String, 1}}, Type{LibGit2.CachedCredentials}}) -precompile(Tuple{typeof(Base._promote_typejoin), Type{Bool}, Type{LibGit2.CachedCredentials}}) -precompile(Tuple{typeof(Base._promote_typejoin), Type{Int32}, Type{Base.Cstring}}) -precompile(Tuple{typeof(Base._promote_typejoin), Type{Union{}}, Type{Array{String, 1}}}) -precompile(Tuple{typeof(Base._promote_typejoin), Type{Union{}}, Type{Bool}}) -precompile(Tuple{typeof(Base._promote_typejoin), Type{Union{}}, Type{Int32}}) -precompile(Tuple{typeof(Base._shrink), typeof(Base.setdiff!), Array{Base.UUID, 1}, Tuple{Array{Base.UUID, 1}}}) -precompile(Tuple{typeof(Base.add_sum), Int64, Int64}) -precompile(Tuple{typeof(Base.afoldl), typeof(Base.:(+)), Int64, Int64, Int64}) -precompile(Tuple{typeof(Base.all), Base.Generator{Base.ValueIterator{Base.Dict{String, Any}}, typeof(Pkg.TOML.is_tabular)}}) -precompile(Tuple{typeof(Base.close), Base.Channel{Any}}) -precompile(Tuple{typeof(Base.close), LibGit2.GitAnnotated}) -precompile(Tuple{typeof(Base.close), LibGit2.GitConfig}) -precompile(Tuple{typeof(Base.close), LibGit2.GitDiff}) -precompile(Tuple{typeof(Base.close), LibGit2.GitReference}) -precompile(Tuple{typeof(Base.close), LibGit2.GitRemote}) -precompile(Tuple{typeof(Base.close), LibGit2.GitRepo}) -precompile(Tuple{typeof(Base.close), LibGit2.GitTree}) -precompile(Tuple{typeof(Base.cmd_gen), Tuple{Tuple{Base.Cmd}}}) -precompile(Tuple{typeof(Base.collect), Base.Generator{Array{Any, 1}, typeof(Pkg.TOML.table2dict)}}) -precompile(Tuple{typeof(Base.collect), Base.Generator{Base.ValueIterator{Base.Dict{String, Any}}, Type{Base.UUID}}}) -precompile(Tuple{typeof(Base.collect), Base.Generator{Base.ValueIterator{Base.Dict{String, String}}, Type{Base.UUID}}}) -precompile(Tuple{typeof(Base.collect), Base.KeySet{String, Base.Dict{String, Any}}}) -precompile(Tuple{typeof(Base.collect_similar), Array{LibGit2.GitAnnotated, 1}, Base.Generator{Array{LibGit2.GitAnnotated, 1}, typeof(Base.close)}}) -precompile(Tuple{typeof(Base.collect_to_with_first!), Array{Base.UUID, 1}, Base.UUID, Base.Generator{Base.ValueIterator{Base.Dict{String, Any}}, Type{Base.UUID}}, Int64}) -precompile(Tuple{typeof(Base.collect_to_with_first!), Array{String, 1}, String, Base.Generator{Array{String, 1}, typeof(Pkg.REPLMode.word2token)}, Int64}) -precompile(Tuple{typeof(Base.convert), Type{Array{Array{Base.BitArray{2}, 1}, 1}}, Array{Array{Base.BitArray{2}, 1}, 1}}) -precompile(Tuple{typeof(Base.convert), Type{Array{Array{Base.VersionNumber, 1}, 1}}, Array{Array{Base.VersionNumber, 1}, 1}}) -precompile(Tuple{typeof(Base.convert), Type{Array{Array{Int64, 1}, 1}}, Array{Array{Int64, 1}, 1}}) -precompile(Tuple{typeof(Base.convert), Type{Array{Base.BitArray{1}, 1}}, Array{Base.BitArray{1}, 1}}) -precompile(Tuple{typeof(Base.convert), Type{Array{Base.Dict{Base.VersionNumber, Int64}, 1}}, Array{Base.Dict{Base.VersionNumber, Int64}, 1}}) -precompile(Tuple{typeof(Base.convert), Type{Array{Base.UUID, 1}}, Array{Base.UUID, 1}}) -precompile(Tuple{typeof(Base.convert), Type{Array{Char, 1}}, Array{Char, 1}}) -precompile(Tuple{typeof(Base.convert), Type{Array{Int64, 1}}, Array{Int64, 1}}) -precompile(Tuple{typeof(Base.convert), Type{Array{Symbol, 1}}, Array{UInt8, 1}}) -precompile(Tuple{typeof(Base.convert), Type{Array{Union{Pkg.Types.VersionRange, String, Pkg.REPLMode.Rev}, 1}}, Array{String, 1}}) -precompile(Tuple{typeof(Base.convert), Type{Base.Dict{Base.UUID, Int64}}, Base.Dict{Base.UUID, Int64}}) -precompile(Tuple{typeof(Base.convert), Type{Base.Dict{Base.UUID, Pkg.GraphType.ResolveLogEntry}}, Base.Dict{Base.UUID, Pkg.GraphType.ResolveLogEntry}}) -precompile(Tuple{typeof(Base.convert), Type{Base.Dict{K, V} where V where K}, Base.Dict{Symbol, Any}}) -precompile(Tuple{typeof(Base.convert), Type{Base.Dict{Symbol, Any}}, Base.Dict{Any, Any}}) -precompile(Tuple{typeof(Base.convert), Type{Base.UUID}, Base.UUID}) -precompile(Tuple{typeof(Base.convert), Type{REPL.LineEdit.TextInterface}, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(Base.convert), Type{REPL.Terminals.AbstractTerminal}, REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(Base.convert), Type{REPL.Terminals.TextTerminal}, REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(Base.convert), Type{Union{Nothing, IO}}, Base.IOStream}) -precompile(Tuple{typeof(Base.convert), Type{Union{Nothing, IO}}, Nothing}) -precompile(Tuple{typeof(Base.convert), Type{Union{Nothing, REPL.LineEdit.Prompt}}, Nothing}) -precompile(Tuple{typeof(Base.convert), Type{Union{Pkg.Types.UpgradeLevel, Base.VersionNumber, Pkg.Types.VersionSpec}}, Base.VersionNumber}) -precompile(Tuple{typeof(Base.copy_chunks!), Array{UInt64, 1}, Int64, Array{UInt64, 1}, Int64, Int64}) -precompile(Tuple{typeof(Base.count), Base.BitArray{1}}) -precompile(Tuple{typeof(Base.deepcopy), Base.Dict{String, Any}}) -precompile(Tuple{typeof(Base.deepcopy_internal), Array{Base.Dict{String, Any}, 1}, Base.IdDict{Any, Any}}) -precompile(Tuple{typeof(Base.deepcopy_internal), Base.Dict{Any, Any}, Base.IdDict{Any, Any}}) -precompile(Tuple{typeof(Base.deepcopy_internal), Base.Dict{String, Any}, Base.IdDict{Any, Any}}) -precompile(Tuple{typeof(Base.deepcopy_internal), Base.Dict{String, String}, Base.IdDict{Any, Any}}) -precompile(Tuple{typeof(Base.deepcopy_internal), String, Base.IdDict{Any, Any}}) -precompile(Tuple{typeof(Base.delete!), Base.Dict{String, Any}, String}) -precompile(Tuple{typeof(Base.delete!), Base.IdDict{Any, Any}, Symbol}) -precompile(Tuple{typeof(Base.empty), Base.Dict{Any, Any}, Type{Base.UUID}, Type{Int64}}) -precompile(Tuple{typeof(Base.empty), Base.Dict{Any, Any}, Type{String}, Type{Base.UUID}}) -precompile(Tuple{typeof(Base.empty), Base.Dict{Any, Any}, Type{String}, Type{String}}) -precompile(Tuple{typeof(Base.eof), Base.IOStream}) -precompile(Tuple{typeof(Base.get!), Base.Dict{Base.UUID, Array{String, 1}}, Base.UUID, Array{String, 1}}) -precompile(Tuple{typeof(Base.get!), Base.Dict{Pkg.Types.VersionRange, Base.Dict{String, Base.UUID}}, Pkg.Types.VersionRange, Base.Dict{String, Base.UUID}}) -precompile(Tuple{typeof(Base.get!), Base.Dict{Pkg.Types.VersionRange, Base.Dict{String, Pkg.Types.VersionSpec}}, Pkg.Types.VersionRange, Base.Dict{String, Pkg.Types.VersionSpec}}) -precompile(Tuple{typeof(Base.get!), Base.Dict{String, Any}, String, Array{Base.Dict{String, Any}, 1}}) -precompile(Tuple{typeof(Base.get!), Base.Dict{String, Array{Base.UUID, 1}}, String, Array{Base.UUID, 1}}) -precompile(Tuple{typeof(Base.get), Base.Dict{String, Any}, String, Base.Dict{Any, Any}}) -precompile(Tuple{typeof(Base.get), Base.Dict{String, Pkg.REPLMode.CommandSpec}, String, Nothing}) -precompile(Tuple{typeof(Base.getindex), Array{Array{Base.VersionNumber, 1}, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Array{Array{Int64, 1}, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Array{Array{UInt64, 1}, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Array{Base.BitArray{1}, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Array{Base.BitArray{2}, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Array{Base.Dict{Int64, Int64}, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Array{Base.Dict{String, Any}, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Array{Base.UUID, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Array{Base.VersionNumber, 1}, Base.BitArray{1}}) -precompile(Tuple{typeof(Base.getindex), Array{Int64, 1}, Int64}) -precompile(Tuple{typeof(Base.getindex), Base.BitArray{1}, Base.UnitRange{Int64}}) -precompile(Tuple{typeof(Base.getindex), Base.BitArray{2}, Base.BitArray{1}, Base.BitArray{1}}) -precompile(Tuple{typeof(Base.getindex), Base.Dict{Int64, Int64}, Int64}) -precompile(Tuple{typeof(Base.getindex), Base.Dict{String, Base.UUID}, String}) -precompile(Tuple{typeof(Base.getindex), Base.Dict{Symbol, Function}, Symbol}) -precompile(Tuple{typeof(Base.getindex), NamedTuple{(:indent, :region_active), Tuple{Int64, Bool}}, Symbol}) -precompile(Tuple{typeof(Base.getindex), NamedTuple{(:prompt_prefix, :prompt_suffix, :complete, :sticky), Tuple{String, String, Pkg.REPLMode.PkgCompletionProvider, Bool}}, Symbol}) -precompile(Tuple{typeof(Base.getindex), NamedTuple{(:prompt_prefix, :prompt_suffix, :repl, :complete, :on_enter), Tuple{String, typeof(Base.input_color), REPL.LineEditREPL, REPL.REPLCompletionProvider, typeof(REPL.return_callback)}}, Symbol}) -precompile(Tuple{typeof(Base.getindex), Pkg.TOML.Table, String}) -precompile(Tuple{typeof(Base.getindex), Type{Pkg.Types.VersionRange}, Pkg.Pkg2.Pkg2Types.VersionInterval}) -precompile(Tuple{typeof(Base.getproperty), Pkg.TOML.Table, Symbol}) -precompile(Tuple{typeof(Base.getproperty), Pkg.Types.PackageSpec, Symbol}) -precompile(Tuple{typeof(Base.getproperty), REPL.Terminals.TerminalBuffer, Symbol}) -precompile(Tuple{typeof(Base.hash), Tuple{String, UInt64}, UInt64}) -precompile(Tuple{typeof(Base.hash), Tuple{String}, UInt64}) -precompile(Tuple{typeof(Base.haskey), Base.Dict{Base.UUID, Base.Dict{K, V} where V where K}, Base.UUID}) -precompile(Tuple{typeof(Base.haskey), Base.Dict{String, Base.UUID}, String}) -precompile(Tuple{typeof(Base.haskey), Base.Dict{String, Pkg.Types.VersionSpec}, String}) -precompile(Tuple{typeof(Base.haskey), NamedTuple{(:indent, :region_active), Tuple{Int64, Bool}}, Symbol}) -precompile(Tuple{typeof(Base.haskey), NamedTuple{(:prompt_prefix, :prompt_suffix, :complete, :sticky), Tuple{String, String, Pkg.REPLMode.PkgCompletionProvider, Bool}}, Symbol}) -precompile(Tuple{typeof(Base.haskey), NamedTuple{(:prompt_prefix, :prompt_suffix, :repl, :complete, :on_enter), Tuple{String, typeof(Base.input_color), REPL.LineEditREPL, REPL.REPLCompletionProvider, typeof(REPL.return_callback)}}, Symbol}) -precompile(Tuple{typeof(Base.haskey), Pkg.TOML.Table, String}) -precompile(Tuple{typeof(Base.ident_cmp), Tuple{String, UInt64}, Tuple{String, UInt64}}) -precompile(Tuple{typeof(Base.ident_cmp), Tuple{String}, Tuple{String}}) -precompile(Tuple{typeof(Base.ident_cmp), Tuple{}, Tuple{}}) -precompile(Tuple{typeof(Base.identity), Int64}) -precompile(Tuple{typeof(Base.in), Base.UUID, Array{Base.UUID, 1}}) -precompile(Tuple{typeof(Base.in), Base.VersionNumber, Pkg.Types.VersionSpec}) -precompile(Tuple{typeof(Base.in), String, Array{String, 1}}) -precompile(Tuple{typeof(Base.in), String, Base.KeySet{String, Base.Dict{String, Any}}}) -precompile(Tuple{typeof(Base.in), String, Base.KeySet{String, Base.Dict{String, Base.Dict{String, Pkg.REPLMode.CommandSpec}}}}) -precompile(Tuple{typeof(Base.indexed_iterate), Base.Pair{Any, Any}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Base.Pair{Any, Any}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Base.Pair{String, Any}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Base.Pair{String, Any}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Char, Bool}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Char, Bool}, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{String, Array{String, 1}, Array{String, 1}}, Int64, Int64}) -precompile(Tuple{typeof(Base.indexed_iterate), Tuple{String, Array{String, 1}, Array{String, 1}}, Int64}) -precompile(Tuple{typeof(Base.input_color)}) -precompile(Tuple{typeof(Base.invokelatest), typeof(Pkg.REPLMode.do_status!), Base.Dict{Symbol, Any}, Array{String, 1}, Base.Dict{Symbol, Any}}) -precompile(Tuple{typeof(Base.isempty), Array{Base.Dict{String, Any}, 1}}) -precompile(Tuple{typeof(Base.isempty), Array{Base.UUID, 1}}) -precompile(Tuple{typeof(Base.isempty), Base.Dict{String, Any}}) -precompile(Tuple{typeof(Base.isempty), Base.Dict{String, String}}) -precompile(Tuple{typeof(Base.isempty), NamedTuple{(:mode,), Tuple{Symbol}}}) -precompile(Tuple{typeof(Base.isopen), Base.Channel{Any}}) -precompile(Tuple{typeof(Base.iterate), Array{Base.Dict{String, Any}, 1}, Int64}) -precompile(Tuple{typeof(Base.iterate), Array{Base.Dict{String, Any}, 1}}) -precompile(Tuple{typeof(Base.iterate), Array{Base.UUID, 1}, Int64}) -precompile(Tuple{typeof(Base.iterate), Array{Base.UUID, 1}}) -precompile(Tuple{typeof(Base.iterate), Base.Channel{Any}}) -precompile(Tuple{typeof(Base.iterate), Base.Dict{Any, Any}, Int64}) -precompile(Tuple{typeof(Base.iterate), Base.Dict{Any, Any}}) -precompile(Tuple{typeof(Base.iterate), Base.Dict{String, Any}, Int64}) -precompile(Tuple{typeof(Base.iterate), Base.Dict{String, Any}}) -precompile(Tuple{typeof(Base.iterate), Tuple{Base.BitArray{1}}, Int64}) -precompile(Tuple{typeof(Base.iterate), Tuple{Base.BitArray{1}}}) -precompile(Tuple{typeof(Base.join), Base.GenericIOBuffer{Array{UInt8, 1}}, Tuple{String}, Char}) -precompile(Tuple{typeof(Base.join), Base.GenericIOBuffer{Array{UInt8, 1}}, Tuple{Symbol, Symbol}, String}) -precompile(Tuple{typeof(Base.join), Base.GenericIOBuffer{Array{UInt8, 1}}, Tuple{UInt32, UInt32, UInt32}, Char}) -precompile(Tuple{typeof(Base.join), Base.GenericIOBuffer{Array{UInt8, 1}}, Tuple{UInt32, UInt32}, Char}) -precompile(Tuple{typeof(Base.join), Tuple{Symbol, Symbol}, String}) -precompile(Tuple{typeof(Base.keys), Base.Dict{String, Any}}) -precompile(Tuple{typeof(Base.keys), Base.Dict{String, Base.Dict{String, Pkg.REPLMode.CommandSpec}}}) -precompile(Tuple{typeof(Base.lastindex), Base.BitArray{1}}) -precompile(Tuple{typeof(Base.length), Array{Array{Base.BitArray{2}, 1}, 1}}) -precompile(Tuple{typeof(Base.length), Array{Array{Base.VersionNumber, 1}, 1}}) -precompile(Tuple{typeof(Base.length), Array{Array{Int64, 1}, 1}}) -precompile(Tuple{typeof(Base.length), Array{Base.BitArray{1}, 1}}) -precompile(Tuple{typeof(Base.length), Array{Base.Dict{Base.VersionNumber, Int64}, 1}}) -precompile(Tuple{typeof(Base.length), Array{Base.Dict{Int64, Int64}, 1}}) -precompile(Tuple{typeof(Base.length), Array{Base.Dict{String, Any}, 1}}) -precompile(Tuple{typeof(Base.length), Array{Base.UUID, 1}}) -precompile(Tuple{typeof(Base.length), Array{Int64, 1}}) -precompile(Tuple{typeof(Base.length), Base.BitArray{1}}) -precompile(Tuple{typeof(Base.length), Base.Dict{Base.UUID, Int64}}) -precompile(Tuple{typeof(Base.length), Base.Dict{Base.UUID, Pkg.GraphType.ResolveLogEntry}}) -precompile(Tuple{typeof(Base.length), Base.Dict{String, Any}}) -precompile(Tuple{typeof(Base.map), Type{Base.UUID}, Base.ValueIterator{Base.Dict{String, Any}}}) -precompile(Tuple{typeof(Base.map), Type{Base.UUID}, Base.ValueIterator{Base.Dict{String, String}}}) -precompile(Tuple{typeof(Base.map), typeof(Base.close), Array{LibGit2.GitAnnotated, 1}}) -precompile(Tuple{typeof(Base.mapreduce_first), typeof(Base.identity), typeof(Base.add_sum), Int64}) -precompile(Tuple{typeof(Base.match), Base.Regex, String}) -precompile(Tuple{typeof(Base.merge!), Base.Dict{String, Any}, Base.Dict{String, Any}}) -precompile(Tuple{typeof(Base.merge), Base.Dict{String, Any}, Base.Dict{String, String}}) -precompile(Tuple{typeof(Base.merge), NamedTuple{(), Tuple{}}, Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}) -precompile(Tuple{typeof(Base.merge), NamedTuple{(), Tuple{}}, NamedTuple{(:mode,), Tuple{Symbol}}}) -precompile(Tuple{typeof(Base.merge), NamedTuple{(:payload,), Tuple{Base.Dict{Symbol, Any}}}, NamedTuple{(:transfer_progress, :credentials), Tuple{Ptr{Nothing}, Ptr{Nothing}}}}) -precompile(Tuple{typeof(Base.merge_names), Tuple{Symbol, Symbol, Symbol}, Tuple{Symbol}}) -precompile(Tuple{typeof(Base.merge_names), Tuple{Symbol, Symbol}, Tuple{Symbol, Symbol}}) -precompile(Tuple{typeof(Base.merge_names), Tuple{Symbol, Symbol}, Tuple{Symbol}}) -precompile(Tuple{typeof(Base.merge_names), Tuple{Symbol}, Tuple{Symbol, Symbol}}) -precompile(Tuple{typeof(Base.merge_names), Tuple{Symbol}, Tuple{Symbol}}) -precompile(Tuple{typeof(Base.merge_names), Tuple{Symbol}, Tuple{}}) -precompile(Tuple{typeof(Base.notify_error), Base.Channel{Any}, Base.InvalidStateException}) -precompile(Tuple{typeof(Base.peek), Base.IOStream}) -precompile(Tuple{typeof(Base.prepend!), Array{Base.Dict{Any, Any}, 1}, Array{Base.Dict{Any, Any}, 1}}) -precompile(Tuple{typeof(Base.print), Base.GenericIOBuffer{Array{UInt8, 1}}, Base.SubString{String}}) -precompile(Tuple{typeof(Base.print), Base.GenericIOBuffer{Array{UInt8, 1}}, Pkg.Types.VersionSpec}) -precompile(Tuple{typeof(Base.print), Base.IOStream, String, String, String, Char}) -precompile(Tuple{typeof(Base.print), Base.TTY, String, String, Char}) -precompile(Tuple{typeof(Base.promote_eltype), Base.KeySet{Base.UUID, Base.Dict{Base.UUID, Pkg.Types.VersionSpec}}}) -precompile(Tuple{typeof(Base.push!), Array{Base.UUID, 1}, Base.UUID}) -precompile(Tuple{typeof(Base.push!), Array{Int64, 1}, Int64}) -precompile(Tuple{typeof(Base.push!), Array{Pkg.Types.VersionRange, 1}, Pkg.Types.VersionRange}) -precompile(Tuple{typeof(Base.push!), Array{Tuple{Base.UUID, String}, 1}, Tuple{Base.UUID, String}}) -precompile(Tuple{typeof(Base.push!), Base.Set{Base.VersionNumber}, Base.VersionNumber}) -precompile(Tuple{typeof(Base.push!), Base.Set{Symbol}, Symbol}) -precompile(Tuple{typeof(Base.push!), Pkg.GraphType.ResolveLogEntry, Tuple{Nothing, String}}) -precompile(Tuple{typeof(Base.push!), Pkg.GraphType.ResolveLogEntry, Tuple{Pkg.GraphType.ResolveLogEntry, String}}) -precompile(Tuple{typeof(Base.put!), Base.Channel{Any}, Tuple{String, Array{String, 1}, Array{String, 1}}}) -precompile(Tuple{typeof(Base.rethrow), Base.InvalidStateException}) -precompile(Tuple{typeof(Base.rstrip), String}) -precompile(Tuple{typeof(Base.seek), Base.IOStream, Int64}) -precompile(Tuple{typeof(Base.setdiff!), Base.Set{Base.UUID}, Array{Base.UUID, 1}}) -precompile(Tuple{typeof(Base.setindex!), Array{Base.BitArray{1}, 1}, Base.BitArray{1}, Int64}) -precompile(Tuple{typeof(Base.setindex!), Base.BitArray{1}, Bool, Int64}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Base.UUID, Base.Dict{K, V} where V where K}, Base.Dict{String, Any}, Base.UUID}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Base.UUID, Int64}, Int64, Base.UUID}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Base.UUID, Pkg.Types.VersionSpec}, Pkg.Types.VersionSpec, Base.UUID}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Base.UUID, String}, String, Base.UUID}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Base.VersionNumber, Base.SHA1}, Base.SHA1, Base.VersionNumber}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Int64, Int64}, Int64, Int64}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{String, Any}, Array{Any, 1}, String}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{String, Any}, Array{Base.Dict{String, Any}, 1}, String}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{String, Any}, Array{String, 1}, String}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{String, Any}, Base.Dict{Any, Any}, String}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{String, Any}, Base.Dict{String, String}, String}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{String, Any}, Base.UUID, String}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{String, Base.UUID}, Base.UUID, String}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{String, Pkg.Types.VersionSpec}, Pkg.Types.VersionSpec, String}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Symbol, Any}, LibGit2.CredentialPayload, Symbol}) -precompile(Tuple{typeof(Base.setindex!), Base.Dict{Symbol, Any}, Pkg.GitTools.MiniProgressBar, Symbol}) -precompile(Tuple{typeof(Base.setindex!), Base.EnvDict, String, String}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.GraphType.Graph, Symbol, Array{Array{Base.BitArray{2}, 1}, 1}}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.GraphType.Graph, Symbol, Array{Array{Int64, 1}, 1}}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.GraphType.Graph, Symbol, Array{Base.BitArray{1}, 1}}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.GraphType.Graph, Symbol, Array{Int64, 1}}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.GraphType.GraphData, Symbol, Array{Array{Base.VersionNumber, 1}, 1}}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.GraphType.GraphData, Symbol, Array{Base.Dict{Base.VersionNumber, Int64}, 1}}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.GraphType.GraphData, Symbol, Array{Base.UUID, 1}}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.GraphType.GraphData, Symbol, Array{Int64, 1}}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.GraphType.GraphData, Symbol, Base.Dict{Base.UUID, Int64}}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.GraphType.ResolveLog, Symbol, Base.Dict{Base.UUID, Pkg.GraphType.ResolveLogEntry}}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.REPLMode.Statement, Symbol, Pkg.REPLMode.CommandSpec}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.Types.PackageSpec, Symbol, Base.UUID}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.Types.PackageSpec, Symbol, Base.VersionNumber}) -precompile(Tuple{typeof(Base.setproperty!), Pkg.Types.PackageSpec, Symbol, String}) -precompile(Tuple{typeof(Base.similar), Array{Base.Dict{String, Any}, 1}}) -precompile(Tuple{typeof(Base.skip_deleted_floor!), Base.Dict{String, Any}}) -precompile(Tuple{typeof(Base.string), String, Base.SubString{String}, String, String}) -precompile(Tuple{typeof(Base.string), Symbol, Int64}) -precompile(Tuple{typeof(Base.strip), Base.SubString{String}}) -precompile(Tuple{typeof(Base.structdiff), NamedTuple{(:indent, :region_active), Tuple{Int64, Bool}}, Type{NamedTuple{(:indent, :region_active), T} where T<:Tuple}}) -precompile(Tuple{typeof(Base.structdiff), NamedTuple{(:prompt_prefix, :prompt_suffix, :complete, :sticky), Tuple{String, String, Pkg.REPLMode.PkgCompletionProvider, Bool}}, Type{NamedTuple{(:prompt_prefix, :prompt_suffix, :keymap_dict, :repl, :complete, :on_enter, :on_done, :hist, :sticky), T} where T<:Tuple}}) -precompile(Tuple{typeof(Base.structdiff), NamedTuple{(:prompt_prefix, :prompt_suffix, :repl, :complete, :on_enter), Tuple{String, typeof(Base.input_color), REPL.LineEditREPL, REPL.REPLCompletionProvider, typeof(REPL.return_callback)}}, Type{NamedTuple{(:prompt_prefix, :prompt_suffix, :keymap_dict, :repl, :complete, :on_enter, :on_done, :hist, :sticky), T} where T<:Tuple}}) -precompile(Tuple{typeof(Base.sum), Array{Int64, 1}}) -precompile(Tuple{typeof(Base.sym_in), Symbol, Tuple{Symbol, Symbol}}) -precompile(Tuple{typeof(Base.sym_in), Symbol, Tuple{Symbol}}) -precompile(Tuple{typeof(Base.sym_in), Symbol, Tuple{}}) -precompile(Tuple{typeof(Base.to_indices), Base.BitArray{2}, Tuple{Base.OneTo{Int64}}, Tuple{Int64}}) -precompile(Tuple{typeof(Base.trues), Int64}) -precompile(Tuple{typeof(Base.union!), Base.Set{Base.UUID}, Base.KeySet{Base.UUID, Base.Dict{Base.UUID, Pkg.Types.Fixed}}}) -precompile(Tuple{typeof(Base.union!), Base.Set{Base.UUID}, Base.KeySet{Base.UUID, Base.Dict{Base.UUID, Pkg.Types.VersionSpec}}}) -precompile(Tuple{typeof(Base.unique!), Array{Base.UUID, 1}}) -precompile(Tuple{typeof(Base.unique!), Array{String, 1}}) -precompile(Tuple{typeof(Base.values), Base.Dict{String, Any}}) -precompile(Tuple{typeof(Base.values), Base.Dict{String, String}}) -precompile(Tuple{typeof(Base.vcat), Base.BitArray{1}, Base.BitArray{1}}) -precompile(Tuple{typeof(Base.vcat), Base.BitArray{1}}) -precompile(Tuple{typeof(Base.vcat), Base.BitArray{2}, Base.BitArray{2}, Base.BitArray{2}, Base.BitArray{2}}) -precompile(Tuple{typeof(Base.vcat), Base.BitArray{2}, Base.BitArray{2}}) -precompile(Tuple{typeof(Base.vect), Base.Cmd, Base.Cmd}) -precompile(Tuple{typeof(Base.vect), Base.VersionNumber}) -precompile(Tuple{typeof(Base.vect), Nothing}) -precompile(Tuple{typeof(Base.write), Base.TTY, Array{UInt8, 1}}) -precompile(Tuple{typeof(Base.write), REPL.Terminals.TTYTerminal, Array{UInt8, 1}}) -precompile(Tuple{typeof(Core.Compiler.eltype), Type{Array{Base.BitArray{2}, 1}}}) -precompile(Tuple{typeof(Core.Compiler.eltype), Type{Array{Base.KeySet{Base.UUID, Base.Dict{Base.UUID, Pkg.Types.VersionSpec}}, 1}}}) -precompile(Tuple{typeof(Core.Compiler.eltype), Type{Array{Pkg.Pkg2.Pkg2Types.VersionInterval, 1}}}) -precompile(Tuple{typeof(Core.Compiler.eltype), Type{Array{UInt32, 1}}}) -precompile(Tuple{typeof(Core.Compiler.eltype), Type{Array{UInt8, 1}}}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), Nothing}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.invokelatest), typeof(Pkg.REPLMode.do_help!)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.open), typeof(Pkg.Pkg2.Reqs.read)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Base.open), typeof(Pkg.TOML.parse)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.IteratorsMD.CartesianIndex{0}}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Missing, Int64}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Missing}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Base.Val{1}, typeof(Base.cat_t), Union}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Bool, typeof(Pkg.Types.parse_toml)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Int64, Tuple{Int64, Tuple{Int64, Tuple{Int64, Tuple{}}}}}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{NamedTuple{(:dims,), Tuple{Base.Val{1}}}, typeof(Base.cat_t), Union}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Nothing, Int64, typeof(Base.sprint), typeof(Base.showerror)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Nothing, Int64, typeof(Base.sprint), typeof(Pkg.GraphType.showlog)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{Pkg.REPLMode.CommandKind, Int64}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.:(!))}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.:(&))}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.:(+))}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.:(-))}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.:(==))}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.:(>))}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.:(~))}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.Unicode.lowercase)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.abs)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.first)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.identity)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Base.maximum)}, Int64}) -precompile(Tuple{typeof(Core.Compiler.getindex), Tuple{typeof(Pkg.BinaryProvider.parse_tar_list)}, Int64}) -precompile(Tuple{typeof(Pkg.Display.filter_manifest), Pkg.Display.InProject{Base.Dict{String, Any}}, Base.Dict{String, Any}}) -precompile(Tuple{typeof(Pkg.Display.in_project), Base.Dict{String, Any}}) -precompile(Tuple{typeof(Pkg.Display.manifest_diff), Pkg.Types.Context, Base.Dict{String, Any}, Base.Dict{String, Any}}) -precompile(Tuple{typeof(Pkg.Display.name_ver_info), Base.Dict{String, Any}}) -precompile(Tuple{typeof(Pkg.Display.not_in_project), Base.Dict{String, Any}}) -precompile(Tuple{typeof(Pkg.Display.print_diff), Base.TTY, Pkg.Types.Context, Array{Pkg.Display.DiffEntry, 1}, Bool}) -precompile(Tuple{typeof(Pkg.Operations.load_package_data_raw), Type{Base.UUID}, String}) -precompile(Tuple{typeof(Pkg.REPLMode.do_add!), Base.Dict{Symbol, Any}, Array{Pkg.Types.PackageSpec, 1}, Base.Dict{Symbol, Any}}) -precompile(Tuple{typeof(Pkg.REPLMode.do_status!), Base.Dict{Symbol, Any}, Array{String, 1}, Base.Dict{Symbol, Any}}) -precompile(Tuple{typeof(Pkg.REPLMode.promptf)}) -precompile(Tuple{typeof(Pkg.TOML.SOME), Array{String, 1}}) -precompile(Tuple{typeof(Pkg.TOML.SOME), Pkg.TOML.Table}) -precompile(Tuple{typeof(Pkg.TOML.insertpair), Pkg.TOML.Parser{Base.IOStream}, Pkg.TOML.Table, String, Array{String, 1}, Int64}) -precompile(Tuple{typeof(Pkg.TOML.insertpair), Pkg.TOML.Parser{Base.IOStream}, Pkg.TOML.Table, String, Pkg.TOML.Table, Int64}) -precompile(Tuple{typeof(Pkg.TOML.is_array_of_tables), Array{Base.Dict{String, Any}, 1}}) -precompile(Tuple{typeof(Pkg.TOML.is_array_of_tables), Array{String, 1}}) -precompile(Tuple{typeof(Pkg.TOML.is_array_of_tables), String}) -precompile(Tuple{typeof(Pkg.TOML.is_tabular), Array{Base.Dict{String, Any}, 1}}) -precompile(Tuple{typeof(Pkg.TOML.is_tabular), Array{String, 1}}) -precompile(Tuple{typeof(Pkg.TOML.is_tabular), Base.Dict{String, Any}}) -precompile(Tuple{typeof(Pkg.TOML.is_tabular), String}) -precompile(Tuple{typeof(Pkg.TOML.parsefile), String}) -precompile(Tuple{typeof(Pkg.Types.printpkgstyle), Base.TTY, Symbol, String}) -precompile(Tuple{typeof(Pkg.Types.semver_interval), Base.RegexMatch}) -precompile(Tuple{typeof(Pkg.Types.write_env_usage), String}) -precompile(Tuple{typeof(REPL.LineEdit._clear_input_area), REPL.Terminals.TerminalBuffer, REPL.LineEdit.InputAreaState}) -precompile(Tuple{typeof(REPL.LineEdit.add_history), REPL.REPLHistoryProvider, REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.clear_input_area), REPL.Terminals.TerminalBuffer, REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.edit_abort), REPL.LineEdit.MIState, Bool}) -precompile(Tuple{typeof(REPL.LineEdit.edit_insert), REPL.LineEdit.MIState, String}) -precompile(Tuple{typeof(REPL.LineEdit.edit_insert), REPL.LineEdit.PromptState, String}) -precompile(Tuple{typeof(REPL.LineEdit.fixup_keymaps!), Base.Dict{Char, Any}, Int64, Char, Nothing}) -precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(REPL.LineEdit.move_input_end), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.normalize_key), Int64}) -precompile(Tuple{typeof(REPL.LineEdit.normalize_key), String}) -precompile(Tuple{typeof(REPL.LineEdit.on_enter), REPL.LineEdit.MIState}) -precompile(Tuple{typeof(REPL.LineEdit.postprocess!), Base.Dict{Char, Any}}) -precompile(Tuple{typeof(REPL.LineEdit.prompt_string), String}) -precompile(Tuple{typeof(REPL.LineEdit.push_undo), REPL.LineEdit.PromptState, Bool}) -precompile(Tuple{typeof(REPL.LineEdit.refresh_line), REPL.LineEdit.PromptState, REPL.Terminals.TTYTerminal}) -precompile(Tuple{typeof(REPL.LineEdit.refresh_multi_line), REPL.Terminals.TerminalBuffer, REPL.LineEdit.PromptState}) -precompile(Tuple{typeof(REPL.LineEdit.state), REPL.LineEdit.MIState, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(REPL.LineEdit.update_key_repeats), REPL.LineEdit.MIState, Array{Char, 1}}) -precompile(Tuple{typeof(REPL.LineEdit.write_prompt), REPL.Terminals.TerminalBuffer, REPL.LineEdit.Prompt}) -precompile(Tuple{typeof(REPL.LineEdit.write_prompt), REPL.Terminals.TerminalBuffer, String}) diff --git a/stdlib/REPL/src/Terminals.jl b/stdlib/REPL/src/Terminals.jl index bf8189c4205f4..f0e03c0a23e40 100644 --- a/stdlib/REPL/src/Terminals.jl +++ b/stdlib/REPL/src/Terminals.jl @@ -120,8 +120,10 @@ cmove_line_up(t::UnixTerminal, n) = (cmove_up(t, n); cmove_col(t, 1)) cmove_line_down(t::UnixTerminal, n) = (cmove_down(t, n); cmove_col(t, 1)) cmove_col(t::UnixTerminal, n) = (write(t.out_stream, '\r'); n > 1 && cmove_right(t, n-1)) +const is_precompiling = Ref(false) if Sys.iswindows() function raw!(t::TTYTerminal,raw::Bool) + is_precompiling[] && return true check_open(t.in_stream) if Base.ispty(t.in_stream) run((raw ? `stty raw -echo onlcr -ocrnl opost` : `stty sane`), From 3d8091fb1ed9482a5a44e79f5d589197ce61929c Mon Sep 17 00:00:00 2001 From: Affan Date: Tue, 14 Aug 2018 13:21:05 -0400 Subject: [PATCH 007/110] fixes issue 28553, improves error message for missing packages (#28555) --- base/loading.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/loading.jl b/base/loading.jl index 7feb1cdd26d85..f55f75498d90e 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -816,7 +816,7 @@ function require(into::Module, mod::Symbol) if where.uuid === nothing throw(ArgumentError(""" Package $mod not found in current path: - - Run `Pkg.add($(repr(String(mod))))` to install the $mod package. + - Run `import Pkg; Pkg.add($(repr(String(mod))))` to install the $mod package. """)) else s = """ From 686ffdb98bab3e9a3db7c5654bcbf85ecf56cee7 Mon Sep 17 00:00:00 2001 From: Patrick Kofod Mogensen Date: Tue, 14 Aug 2018 20:30:39 +0200 Subject: [PATCH 008/110] Keep parametric information when constructing a SparseMatrixCSC from a SparseMatrixCSC. (#28642) --- stdlib/SparseArrays/src/sparsematrix.jl | 1 + stdlib/SparseArrays/test/sparse.jl | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/stdlib/SparseArrays/src/sparsematrix.jl b/stdlib/SparseArrays/src/sparsematrix.jl index a88f27edd90d1..f954d33393d61 100644 --- a/stdlib/SparseArrays/src/sparsematrix.jl +++ b/stdlib/SparseArrays/src/sparsematrix.jl @@ -356,6 +356,7 @@ similar(S::SparseMatrixCSC, ::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer # converting between SparseMatrixCSC types +SparseMatrixCSC(S::SparseMatrixCSC) = copy(S) AbstractMatrix{Tv}(A::SparseMatrixCSC) where {Tv} = SparseMatrixCSC{Tv}(A) SparseMatrixCSC{Tv}(S::SparseMatrixCSC{Tv}) where {Tv} = copy(S) SparseMatrixCSC{Tv}(S::SparseMatrixCSC) where {Tv} = SparseMatrixCSC{Tv,eltype(S.colptr)}(S) diff --git a/stdlib/SparseArrays/test/sparse.jl b/stdlib/SparseArrays/test/sparse.jl index f88c6dde06493..0c17946d7a5d8 100644 --- a/stdlib/SparseArrays/test/sparse.jl +++ b/stdlib/SparseArrays/test/sparse.jl @@ -2289,4 +2289,10 @@ end @test adjoint(MC) == copy(adjoint(SC)) end +@testset "Issue #28634" begin + a = SparseMatrixCSC{Int8, Int16}([1 2; 3 4]) + na = SparseMatrixCSC(a) + @test typeof(a) === typeof(na) +end + end # module From eabb601ec8cccb4ff40f18eb4f046ab4608f1840 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Wed, 15 Aug 2018 01:44:49 +0200 Subject: [PATCH 009/110] stop specializing on argument types of `display` (#28616) there is no real advantage in specializing on the argument types for display since it goes through a quite complicated machinery of trying to find applicable displays. Before: julia> let @time precompile(Tuple{typeof(Base.Multimedia.display), Int32}) @time precompile(Tuple{typeof(Base.Multimedia.display), Vector{Int}}) @time precompile(Tuple{typeof(Base.Multimedia.display), Float64}) @time precompile(Tuple{typeof(Base.Multimedia.display), Symbol}) end 0.034542 seconds (37.08 k allocations: 1.916 MiB) 0.042272 seconds (92.57 k allocations: 4.810 MiB) 0.039003 seconds (90.20 k allocations: 4.758 MiB) 0.030826 seconds (61.08 k allocations: 3.066 MiB) After: julia> let @time precompile(Tuple{typeof(Base.Multimedia.display), Int32}) @time precompile(Tuple{typeof(Base.Multimedia.display), Vector{Int}}) @time precompile(Tuple{typeof(Base.Multimedia.display), Float64}) @time precompile(Tuple{typeof(Base.Multimedia.display), Symbol}) end 0.000041 seconds (12 allocations: 640 bytes) 0.000029 seconds (10 allocations: 544 bytes) 0.000024 seconds (9 allocations: 496 bytes) 0.000021 seconds (9 allocations: 496 bytes) --- base/multimedia.jl | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/base/multimedia.jl b/base/multimedia.jl index 3ec70cc12b663..9e17f05d7312b 100644 --- a/base/multimedia.jl +++ b/base/multimedia.jl @@ -43,8 +43,8 @@ julia> showable("img/png", rand(5)) false ``` """ -showable(::MIME{mime}, x) where {mime} = hasmethod(show, Tuple{IO, MIME{mime}, typeof(x)}) -showable(m::AbstractString, x) = showable(MIME(m), x) +showable(::MIME{mime}, @nospecialize x) where {mime} = hasmethod(show, Tuple{IO, MIME{mime}, typeof(x)}) +showable(m::AbstractString, @nospecialize x) = showable(MIME(m), x) """ show(io, mime, x) @@ -175,8 +175,8 @@ end abstract type AbstractDisplay end # it is convenient to accept strings instead of ::MIME -display(d::AbstractDisplay, mime::AbstractString, x) = display(d, MIME(mime), x) -display(mime::AbstractString, x) = display(MIME(mime), x) +display(d::AbstractDisplay, mime::AbstractString, @nospecialize x) = display(d, MIME(mime), x) +display(mime::AbstractString, @nospecialize x) = display(MIME(mime), x) """ displayable(mime) -> Bool @@ -201,12 +201,12 @@ objects are printed in the Julia REPL.) struct TextDisplay <: AbstractDisplay io::IO end -display(d::TextDisplay, M::MIME"text/plain", x) = show(d.io, M, x) -display(d::TextDisplay, x) = display(d, MIME"text/plain"(), x) +display(d::TextDisplay, M::MIME"text/plain", @nospecialize x) = show(d.io, M, x) +display(d::TextDisplay, @nospecialize x) = display(d, MIME"text/plain"(), x) # if you explicitly call display("text/foo", x), it should work on a TextDisplay: displayable(d::TextDisplay, M::MIME) = istextmime(M) -function display(d::TextDisplay, M::MIME, x) +function display(d::TextDisplay, M::MIME, @nospecialize x) displayable(d, M) || throw(MethodError(display, (d, M, x))) show(d.io, M, x) end @@ -254,7 +254,7 @@ function reinit_displays() pushdisplay(TextDisplay(stdout)) end -xdisplayable(D::AbstractDisplay, args...) = applicable(display, D, args...) +xdisplayable(D::AbstractDisplay, @nospecialize args...) = applicable(display, D, args...) """ display(x) @@ -280,7 +280,7 @@ variants, one can also supply the "raw" data in the requested MIME type by passi `x::AbstractString` (for MIME types with text-based storage, such as text/html or application/postscript) or `x::Vector{UInt8}` (for binary MIME types). """ -function display(x) +function display(@nospecialize x) for i = length(displays):-1:1 if xdisplayable(displays[i], x) try @@ -294,7 +294,7 @@ function display(x) throw(MethodError(display, (x,))) end -function display(m::MIME, x) +function display(m::MIME, @nospecialize x) for i = length(displays):-1:1 if xdisplayable(displays[i], m, x) try @@ -339,7 +339,7 @@ Using `redisplay` is also a hint to the backend that `x` may be redisplayed several times, and the backend may choose to defer the display until (for example) the next interactive prompt. """ -function redisplay(x) +function redisplay(@nospecialize x) for i = length(displays):-1:1 if xdisplayable(displays[i], x) try @@ -353,7 +353,7 @@ function redisplay(x) throw(MethodError(redisplay, (x,))) end -function redisplay(m::Union{MIME,AbstractString}, x) +function redisplay(m::Union{MIME,AbstractString}, @nospecialize x) for i = length(displays):-1:1 if xdisplayable(displays[i], m, x) try @@ -368,8 +368,8 @@ function redisplay(m::Union{MIME,AbstractString}, x) end # default redisplay is simply to call display -redisplay(d::AbstractDisplay, x) = display(d, x) -redisplay(d::AbstractDisplay, m::Union{MIME,AbstractString}, x) = display(d, m, x) +redisplay(d::AbstractDisplay, @nospecialize x) = display(d, x) +redisplay(d::AbstractDisplay, m::Union{MIME,AbstractString}, @nospecialize x) = display(d, m, x) ########################################################################### From 548d83fe60831b425869a27b219b7d25e4a4bb1d Mon Sep 17 00:00:00 2001 From: anderson15 <4404456+anderson15@users.noreply.github.com> Date: Wed, 15 Aug 2018 03:12:52 -0400 Subject: [PATCH 010/110] Change quit() to exit() (#28660) To get out of REPL. --- stdlib/REPL/docs/src/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/REPL/docs/src/index.md b/stdlib/REPL/docs/src/index.md index 0920ab36549c3..2afa93dfb32ea 100644 --- a/stdlib/REPL/docs/src/index.md +++ b/stdlib/REPL/docs/src/index.md @@ -15,7 +15,7 @@ Markdown.parse("```\n\$ julia\n\n$(banner)\njulia>\n```") ``` To exit the interactive session, type `^D` -- the control key together with the `d` key on a blank -line -- or type `quit()` followed by the return or enter key. The REPL greets you with a banner +line -- or type `exit()` followed by the return or enter key. The REPL greets you with a banner and a `julia>` prompt. ## The different prompt modes From bcce68d79862e99403166c0bbbf7f1565beb658d Mon Sep 17 00:00:00 2001 From: Patrick Kofod Mogensen Date: Wed, 15 Aug 2018 09:13:34 +0200 Subject: [PATCH 011/110] Fix input args in rem_pio2_kernel doc string (#28657) It was once an argument, but it's calculated on the first line, so... --- base/special/rem_pio2.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/special/rem_pio2.jl b/base/special/rem_pio2.jl index 67cb067955f7a..c8d1018cd7881 100644 --- a/base/special/rem_pio2.jl +++ b/base/special/rem_pio2.jl @@ -208,7 +208,7 @@ function paynehanek(x::Float64) end """ - rem_pio2_kernel(x, xhp) + rem_pio2_kernel(x) Return the remainder of `x` modulo π/2 as a double-double pair, along with a `k` such that ``k \\mod 3 == K \\mod 3`` where ``K*π/2 = x - rem``. Note, that it is From 4e098f1717169cfc1340dbeaf99f25fcb8ea0227 Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Wed, 15 Aug 2018 17:04:58 +0900 Subject: [PATCH 012/110] remove redundant text in a docstring (#28663) --- base/strings/io.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/strings/io.jl b/base/strings/io.jl index 4df79c223ac69..1584b529beada 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -223,7 +223,7 @@ IOBuffer(s::SubString{String}) = IOBuffer(view(unsafe_wrap(Vector{UInt8}, s.stri Join an array of `strings` into a single string, inserting the given delimiter between adjacent strings. If `last` is given, it will be used instead of `delim` between the last two strings. If `io` is given, the result is written to `io` rather than returned as -as a `String`. For example, +as a `String`. # Examples ```jldoctest From 7ffe704320543edd943f19a9ffd9c84df2a1df4a Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Wed, 15 Aug 2018 17:12:33 +0900 Subject: [PATCH 013/110] fix typo in a docstring (#28664) --- base/strings/io.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/strings/io.jl b/base/strings/io.jl index 1584b529beada..64b9a613c084e 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -81,7 +81,7 @@ of the buffer (in bytes). The optional keyword argument `context` can be set to `:key=>value` pair or an `IO` or [`IOContext`](@ref) object whose attributes are used for the I/O -stream passed to `f`. The optional `sizehint` is a suggersted (in bytes) +stream passed to `f`. The optional `sizehint` is a suggested size (in bytes) to allocate for the buffer used to write the string. # Examples From b2139cb31a653e593dfb3d1a0cfdbcfb69d54d4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1ll=20Haraldsson?= Date: Wed, 15 Aug 2018 12:52:46 +0000 Subject: [PATCH 014/110] Add note to NEWS about using julia 0.7 when upgrading from 0.6 (#28650) * Something more, at least this should be in NEWS?! * Revised sentence, thanks --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index ac7b3ae5f2605..1a877096ae3ea 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,7 @@ Language changes Breaking changes ---------------- +If you encounter errors in your code that were not there in Julia version 0.6, it is recommended to run the code on version 0.7 where deprecation warnings for things removed in 1.0 are shown. Library improvements -------------------- From 61f6dab775714e0732cf1a6f8e2cf8d97901df06 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Wed, 15 Aug 2018 09:01:33 -0400 Subject: [PATCH 015/110] Some cleanup of the NEWS.md [ci skip] --- NEWS.md | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/NEWS.md b/NEWS.md index 1a877096ae3ea..d59b573f673e4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,21 +1,15 @@ Julia v1.0.0 Release Notes ========================== -New language features ---------------------- - -Language changes ----------------- - -Breaking changes ----------------- -If you encounter errors in your code that were not there in Julia version 0.6, it is recommended to run the code on version 0.7 where deprecation warnings for things removed in 1.0 are shown. - -Library improvements --------------------- - -Compiler/Runtime improvements ------------------------------ +Julia v1.0 is identical to the v0.7 release, with the exception that +it removes all deprecations and deprecation related warnings. When +upgrading a codebase from v0.6, the process is to first get the code +to work on v0.7, and fix all the deprecation warnings. Once the code +runs on v0.7 without warnings, it should be good to run on v1.0. + +Refer to the [Release Notes for +v0.7](https://github.com/JuliaLang/julia/blob/master/HISTORY.md) for a +detailed list of changes from Julia v0.6. Deprecated or removed --------------------- From 72af6204a7fa448dd1bdc38305e78533b4a83040 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Wed, 15 Aug 2018 09:03:19 -0400 Subject: [PATCH 016/110] Remove unused sections in the NEWS.md file. [ci skip] --- NEWS.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index d59b573f673e4..fcbf0ef996f5f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -17,8 +17,5 @@ Deprecated or removed The old package manager (now called `OldPkg`) has been moved to a separate repository at https://github.com/JuliaArchive/OldPkg.jl ([#27930]) -Command-line option changes ---------------------------- - [#27930]: https://github.com/JuliaLang/julia/issues/27930 From 48a9ec40836d32f26751099d4e69a7fa21290f65 Mon Sep 17 00:00:00 2001 From: "M. Zhou" <5723047+cdluminate@users.noreply.github.com> Date: Wed, 15 Aug 2018 18:05:29 +0000 Subject: [PATCH 017/110] Update julia.appdata.xml to a new AppStream specification. (#28020) --- contrib/julia.appdata.xml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/contrib/julia.appdata.xml b/contrib/julia.appdata.xml index 576d88358ee7c..3d451197098b2 100644 --- a/contrib/julia.appdata.xml +++ b/contrib/julia.appdata.xml @@ -1,9 +1,15 @@ - - julia.desktop + + org.julialang.julia + Julia + julia.desktop CC-BY-SA-3.0 MIT and LGPL-2.1+ and GPL-2.0+ + High-performance programming language for technical computing + + julia +

Julia is a high-level, high-performance dynamic programming language for @@ -21,8 +27,9 @@

- https://julialang.org/images/julia-gnome.png + + https://julialang.org/images/julia-gnome.png + https://julialang.org/ - julia-dev@googlegroups.com -
+ From 472fe5fdbec40fad8ae61bb6f250294726b19f94 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Wed, 15 Aug 2018 21:04:00 +0200 Subject: [PATCH 018/110] improve performance for number to string conversion functions (#28661) * improve performance for number to string conversion functions --- base/intfuncs.jl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/base/intfuncs.jl b/base/intfuncs.jl index c3ec78eeb31e9..2b75f09ac62e7 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -543,11 +543,11 @@ function bin(x::Unsigned, pad::Int, neg::Bool) i = neg + max(pad,sizeof(x)<<3-leading_zeros(x)) a = StringVector(i) while i > neg - a[i] = '0'+(x&0x1) + @inbounds a[i] = 48+(x&0x1) x >>= 1 i -= 1 end - if neg; a[1]='-'; end + if neg; @inbounds a[1]=0x2d; end String(a) end @@ -555,11 +555,11 @@ function oct(x::Unsigned, pad::Int, neg::Bool) i = neg + max(pad,div((sizeof(x)<<3)-leading_zeros(x)+2,3)) a = StringVector(i) while i > neg - a[i] = '0'+(x&0x7) + @inbounds a[i] = 48+(x&0x7) x >>= 3 i -= 1 end - if neg; a[1]='-'; end + if neg; @inbounds a[1]=0x2d; end String(a) end @@ -567,11 +567,11 @@ function dec(x::Unsigned, pad::Int, neg::Bool) i = neg + ndigits(x, base=10, pad=pad) a = StringVector(i) while i > neg - a[i] = '0'+rem(x,10) + @inbounds a[i] = 48+rem(x,10) x = oftype(x,div(x,10)) i -= 1 end - if neg; a[1]='-'; end + if neg; @inbounds a[1]=0x2d; end String(a) end @@ -580,11 +580,11 @@ function hex(x::Unsigned, pad::Int, neg::Bool) a = StringVector(i) while i > neg d = x & 0xf - a[i] = '0'+d+39*(d>9) + @inbounds a[i] = 48+d+39*(d>9) x >>= 4 i -= 1 end - if neg; a[1]='-'; end + if neg; @inbounds a[1]=0x2d; end String(a) end From a3a2b7a058e1b5ff1a1d86c78318391b7f49eb0e Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Wed, 15 Aug 2018 18:02:44 -0400 Subject: [PATCH 019/110] Fix throw_complex_domainerror error message for log[1p] (#28621) * Fix throw_complex_domainerror error message for log[1p] This seems pretty clearly unintentional. Relevant history is in d4229beb7e8d2c665fe6bd3fc9624ec2ffa4d096 and d555a9a3874f4c47e16d1fdcbae4866cc0d3917f. * Require `Symbol` as first argument to `throw_complex_domainerror` --- base/math.jl | 20 ++++++++++---------- base/special/log.jl | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/base/math.jl b/base/math.jl index 6e758cf7b83e2..2d58744d61b0d 100644 --- a/base/math.jl +++ b/base/math.jl @@ -27,7 +27,7 @@ using Core.Intrinsics: sqrt_llvm using .Base: IEEEFloat -@noinline function throw_complex_domainerror(f, x) +@noinline function throw_complex_domainerror(f::Symbol, x) throw(DomainError(x, string("$f will only return a complex result if called with a ", "complex argument. Try $f(Complex(x))."))) end @@ -198,17 +198,17 @@ julia> log(4,2) 0.5 julia> log(-2, 3) -ERROR: DomainError with log: --2.0 will only return a complex result if called with a complex argument. Try -2.0(Complex(x)). +ERROR: DomainError with -2.0: +log will only return a complex result if called with a complex argument. Try log(Complex(x)). Stacktrace: - [1] throw_complex_domainerror(::Float64, ::Symbol) at ./math.jl:31 + [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31 [...] julia> log(2, -3) -ERROR: DomainError with log: --3.0 will only return a complex result if called with a complex argument. Try -3.0(Complex(x)). +ERROR: DomainError with -3.0: +log will only return a complex result if called with a complex argument. Try log(Complex(x)). Stacktrace: - [1] throw_complex_domainerror(::Float64, ::Symbol) at ./math.jl:31 + [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31 [...] ``` @@ -459,10 +459,10 @@ julia> log1p(0) 0.0 julia> log1p(-2) -ERROR: DomainError with log1p: --2.0 will only return a complex result if called with a complex argument. Try -2.0(Complex(x)). +ERROR: DomainError with -2.0: +log1p will only return a complex result if called with a complex argument. Try log1p(Complex(x)). Stacktrace: - [1] throw_complex_domainerror(::Float64, ::Symbol) at ./math.jl:31 + [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31 [...] ``` """ diff --git a/base/special/log.jl b/base/special/log.jl index 7e52c39c2a5d9..4b6429adf7c2d 100644 --- a/base/special/log.jl +++ b/base/special/log.jl @@ -282,7 +282,7 @@ function log(x::Float64) elseif isnan(x) NaN else - throw_complex_domainerror(x, :log) + throw_complex_domainerror(:log, x) end end @@ -318,7 +318,7 @@ function log(x::Float32) elseif isnan(x) NaN32 else - throw_complex_domainerror(x, :log) + throw_complex_domainerror(:log, x) end end @@ -353,7 +353,7 @@ function log1p(x::Float64) elseif isnan(x) NaN else - throw_complex_domainerror(x, :log1p) + throw_complex_domainerror(:log1p, x) end end @@ -386,7 +386,7 @@ function log1p(x::Float32) elseif isnan(x) NaN32 else - throw_complex_domainerror(x, :log1p) + throw_complex_domainerror(:log1p, x) end end From 290684d3180bb3b38259343d74479f90dccd9b04 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 15 Aug 2018 18:04:07 -0400 Subject: [PATCH 020/110] fix #28641, passing typevars to `<:` in typejoin and tuplemerge (#28655) --- base/compiler/typelimits.jl | 3 +++ base/promotion.jl | 10 +++++----- test/compiler/compiler.jl | 13 +++++++++++++ test/core.jl | 2 ++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/base/compiler/typelimits.jl b/base/compiler/typelimits.jl index 83ca2a386b119..f8220375e4518 100644 --- a/base/compiler/typelimits.jl +++ b/base/compiler/typelimits.jl @@ -412,6 +412,9 @@ function tuplemerge(a::DataType, b::DataType) for loop_b = (false, true) for i = (lt + 1):(loop_b ? lbr : lar) ti = unwrapva(loop_b ? bp[i] : ap[i]) + while ti isa TypeVar + ti = ti.ub + end # compare (ti <-> tail), (wrapper ti <-> tail), (ti <-> wrapper tail), then (wrapper ti <-> wrapper tail) # until we find the first element that contains the other in the pair # TODO: this result would be more stable (and more associative and more commutative) diff --git a/base/promotion.jl b/base/promotion.jl index 78a1954da55eb..319284beaaaf9 100644 --- a/base/promotion.jl +++ b/base/promotion.jl @@ -14,7 +14,11 @@ typejoin(@nospecialize(t)) = (@_pure_meta; t) typejoin(@nospecialize(t), ts...) = (@_pure_meta; typejoin(t, typejoin(ts...))) function typejoin(@nospecialize(a), @nospecialize(b)) @_pure_meta - if a <: b + if isa(a, TypeVar) + return typejoin(a.ub, b) + elseif isa(b, TypeVar) + return typejoin(a, b.ub) + elseif a <: b return b elseif b <: a return a @@ -22,10 +26,6 @@ function typejoin(@nospecialize(a), @nospecialize(b)) return UnionAll(a.var, typejoin(a.body, b)) elseif isa(b, UnionAll) return UnionAll(b.var, typejoin(a, b.body)) - elseif isa(a, TypeVar) - return typejoin(a.ub, b) - elseif isa(b, TypeVar) - return typejoin(a, b.ub) elseif isa(a, Union) return typejoin(typejoin(a.a, a.b), b) elseif isa(b, Union) diff --git a/test/compiler/compiler.jl b/test/compiler/compiler.jl index 904695982e030..7ddca137ed2c4 100644 --- a/test/compiler/compiler.jl +++ b/test/compiler/compiler.jl @@ -1977,3 +1977,16 @@ function bar28444() e[1] end @test bar28444() == 1 + +# issue #28641 +struct VoxelIndices{T <: Integer} + voxCrnrPos::NTuple{8,NTuple{3,T}} + voxEdgeCrnrs::NTuple{19, NTuple{2,T}} + voxEdgeDir::NTuple{19,T} + voxEdgeIx::NTuple{8,NTuple{8,T}} + subTets::NTuple{6,NTuple{4,T}} + tetEdgeCrnrs::NTuple{6,NTuple{2,T}} + tetTri::NTuple{16,NTuple{6,T}} +end +f28641(x::VoxelIndices, f) = getfield(x, f) +@test Base.return_types(f28641, (Any,Symbol)) == Any[Tuple] diff --git a/test/core.jl b/test/core.jl index 7dd27fefe03fc..d8981f352ffb1 100644 --- a/test/core.jl +++ b/test/core.jl @@ -141,6 +141,8 @@ end @test typejoin(Tuple{Vararg{Int,2}}, Tuple{Int,Int,Int}) === Tuple{Int,Int,Vararg{Int}} @test typejoin(Tuple{Vararg{Int,2}}, Tuple{Vararg{Int}}) === Tuple{Vararg{Int}} +@test typejoin(NTuple{3,Tuple}, NTuple{2,T} where T) == Tuple{Any,Any,Vararg{Tuple}} + # issue #26321 struct T26321{N,S<:NTuple{N}} t::S From 630f53acdd37df3a23d96080deec9a25a1355494 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 15 Aug 2018 18:04:25 -0400 Subject: [PATCH 021/110] fix #28499, calling `cluster_cookie` before cluster starts (#28656) --- stdlib/Distributed/src/cluster.jl | 3 ++- stdlib/Distributed/test/distributed_exec.jl | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/stdlib/Distributed/src/cluster.jl b/stdlib/Distributed/src/cluster.jl index 0d1614b7e972a..49df11b6eef0d 100644 --- a/stdlib/Distributed/src/cluster.jl +++ b/stdlib/Distributed/src/cluster.jl @@ -644,7 +644,7 @@ end Return the cluster cookie. """ -cluster_cookie() = LPROC.cookie +cluster_cookie() = (init_multi(); LPROC.cookie) """ cluster_cookie(cookie) -> cookie @@ -652,6 +652,7 @@ cluster_cookie() = LPROC.cookie Set the passed cookie as the cluster cookie, then returns it. """ function cluster_cookie(cookie) + init_multi() # The cookie must be an ASCII string with length <= HDR_COOKIE_LEN @assert isascii(cookie) @assert length(cookie) <= HDR_COOKIE_LEN diff --git a/stdlib/Distributed/test/distributed_exec.jl b/stdlib/Distributed/test/distributed_exec.jl index 04ef09d495a2d..f17d97697c27e 100644 --- a/stdlib/Distributed/test/distributed_exec.jl +++ b/stdlib/Distributed/test/distributed_exec.jl @@ -3,6 +3,8 @@ using Test, Distributed, Random, Serialization, Sockets import Distributed: launch, manage +@test cluster_cookie() isa String + include(joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testenv.jl")) @test Distributed.extract_imports(:(begin; import Foo, Bar; let; using Baz; end; end)) == From 5c1f6b061c2a486f69f959173039117382c9b95a Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 15 Aug 2018 18:04:49 -0400 Subject: [PATCH 022/110] fix #28597, error for empty arrays with some negative dim sizes (#28659) --- src/array.c | 5 +++-- test/core.jl | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/array.c b/src/array.c index 746d474b97b18..6a893f96cf43e 100644 --- a/src/array.c +++ b/src/array.c @@ -61,8 +61,9 @@ static jl_array_t *_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims, jl_array_t *a; for(i=0; i < ndims; i++) { - wideint_t prod = (wideint_t)nel * (wideint_t)dims[i]; - if (prod > (wideint_t) MAXINTVAL) + size_t di = dims[i]; + wideint_t prod = (wideint_t)nel * (wideint_t)di; + if (prod > (wideint_t) MAXINTVAL || di > MAXINTVAL) jl_error("invalid Array dimensions"); nel = prod; } diff --git a/test/core.jl b/test/core.jl index d8981f352ffb1..822fa6fca76c7 100644 --- a/test/core.jl +++ b/test/core.jl @@ -6697,3 +6697,8 @@ function repackage28445() true end @test repackage28445() + +# issue #28597 +@test_throws ErrorException Array{Int, 2}(undef, 0, -10) +@test_throws ErrorException Array{Int, 2}(undef, -10, 0) +@test_throws ErrorException Array{Int, 2}(undef, -1, -1) From 4629a212afc5055a4cb8cb752be8eb666f7def43 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Thu, 16 Aug 2018 10:25:49 +0200 Subject: [PATCH 023/110] fix performance in printf (#28670) --- base/printf.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/base/printf.jl b/base/printf.jl index 5010503949819..85a066be43bca 100644 --- a/base/printf.jl +++ b/base/printf.jl @@ -863,7 +863,7 @@ function decode_oct(d::Integer) @handle_zero x digits pt = i = div((sizeof(x)<<3)-leading_zeros(x)+2,3) while i > 0 - digits[i] = '0'+(x&0x7) + digits[i] = 48+(x&0x7) x >>= 3 i -= 1 end @@ -876,7 +876,7 @@ function decode_0ct(d::Integer) pt = i = div((sizeof(x)<<3)-leading_zeros(x)+5,3) digits = DIGITSs[Threads.threadid()] while i > 0 - digits[i] = '0'+(x&0x7) + digits[i] = 48+(x&0x7) x >>= 3 i -= 1 end @@ -889,7 +889,7 @@ function decode_dec(d::Integer) @handle_zero x digits pt = i = Base.ndigits0z(x) while i > 0 - digits[i] = '0'+rem(x,10) + digits[i] = 48+rem(x,10) x = div(x,10) i -= 1 end From e23515d97c3d371973d30f33e82a0d4e1faa7ecc Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Thu, 16 Aug 2018 13:17:33 +0200 Subject: [PATCH 024/110] LinearAlgebra remove unused export (#28684) --- stdlib/LinearAlgebra/src/LinearAlgebra.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/stdlib/LinearAlgebra/src/LinearAlgebra.jl b/stdlib/LinearAlgebra/src/LinearAlgebra.jl index 48f5b34ca81f7..0da7dadb67434 100644 --- a/stdlib/LinearAlgebra/src/LinearAlgebra.jl +++ b/stdlib/LinearAlgebra/src/LinearAlgebra.jl @@ -60,7 +60,6 @@ export axpby!, bunchkaufman, bunchkaufman!, - chol, cholesky, cholesky!, cond, From c62555ba7b16810497471d831cfca4328f449798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20Besan=C3=A7on?= Date: Thu, 16 Aug 2018 19:20:44 +0200 Subject: [PATCH 025/110] Complete uuids (#28649) * documented UUID type * fixed typo * improved sentence structure from doc --- base/uuid.jl | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/base/uuid.jl b/base/uuid.jl index cf422724eb928..75bf21d4697cb 100644 --- a/base/uuid.jl +++ b/base/uuid.jl @@ -1,5 +1,10 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +""" + Represents a Universally Unique Identifier (UUID). + Can be built from one `UInt128` (all byte values), two `UInt64`, or four `UInt32`. + Conversion from a string will check the UUID validity. +""" struct UUID value::UInt128 end @@ -8,18 +13,18 @@ UUID(u::NTuple{4, UInt32}) = UUID((UInt128(u[1]) << 96) | (UInt128(u[2]) << 64) (UInt128(u[3]) << 32) | UInt128(u[4])) function convert(::Type{NTuple{2, UInt64}}, uuid::UUID) - uuid = uuid.value - hi = UInt64((uuid >> 64) & 0xffffffffffffffff) - lo = UInt64(uuid & 0xffffffffffffffff) + bytes = uuid.value + hi = UInt64((bytes >> 64) & 0xffffffffffffffff) + lo = UInt64(bytes & 0xffffffffffffffff) return (hi, lo) end function convert(::Type{NTuple{4, UInt32}}, uuid::UUID) - uuid = uuid.value - hh = UInt32((uuid >> 96) & 0xffffffff) - hl = UInt32((uuid >> 64) & 0xffffffff) - lh = UInt32((uuid >> 32) & 0xffffffff) - ll = UInt32(uuid & 0xffffffff) + bytes = uuid.value + hh = UInt32((bytes >> 96) & 0xffffffff) + hl = UInt32((bytes >> 64) & 0xffffffff) + lh = UInt32((bytes >> 32) & 0xffffffff) + ll = UInt32(bytes & 0xffffffff) return (hh, hl, lh, ll) end From 2715fb2904f233e1e1b5f23c52612b9955ee6461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20A=2E=20V=2E=20de=20Bragan=C3=A7a=20Alves?= Date: Thu, 16 Aug 2018 13:22:00 -0400 Subject: [PATCH 026/110] Fix issue #28624 (#28635) --- base/client.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/client.jl b/base/client.jl index 7f568d39d143d..5c5894fc7c8a3 100644 --- a/base/client.jl +++ b/base/client.jl @@ -56,7 +56,7 @@ function repl_cmd(cmd, out) # If it's intended to simulate `cd`, it should instead be doing # more nearly `cd $dir && printf %s \$PWD` (with appropriate quoting), # since shell `cd` does more than just `echo` the result. - dir = read(`$shell -c "printf %s $(shell_escape_posixly(dir))"`, String) + dir = read(`$shell -c "printf '%s' $(shell_escape_posixly(dir))"`, String) end cd(dir) end From 08bf3e11dc4cbe0e654d3d7f534196b22f662420 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Thu, 16 Aug 2018 21:04:48 +0200 Subject: [PATCH 027/110] add a code quote to a word (#28699) --- base/essentials.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/essentials.jl b/base/essentials.jl index 3bf9ecfad81d3..edd7e75d2f949 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -795,7 +795,7 @@ isdone(itr, state...) = missing iterate(iter [, state]) -> Union{Nothing, Tuple{Any, Any}} Advance the iterator to obtain the next element. If no elements -remain, nothing should be returned. Otherwise, a 2-tuple of the +remain, `nothing` should be returned. Otherwise, a 2-tuple of the next element and the new iteration state should be returned. """ function iterate end From af3c452fa3c379d58678538e7a8d9c164e380f4f Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 16 Aug 2018 17:13:23 -0400 Subject: [PATCH 028/110] smarter order of checks in jl_types_equal (#28677) this works around the test issue in RDatasets --- src/subtype.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/subtype.c b/src/subtype.c index 33baf50bac0ee..6b566415ee273 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -1188,6 +1188,13 @@ JL_DLLEXPORT int jl_types_equal(jl_value_t *a, jl_value_t *b) { if (obviously_egal(a, b)) return 1; if (obviously_unequal(a, b)) return 0; + if (jl_is_datatype(a) && !jl_is_concrete_type(b)) { + // if one type looks more likely to be abstract, check it on the left + // first in order to reject more quickly. + jl_value_t *temp = a; + a = b; + b = temp; + } return jl_subtype(a, b) && jl_subtype(b, a); } From 82941f33e532085cbe8a9bc5b905a2d709687997 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Thu, 16 Aug 2018 11:41:34 -0400 Subject: [PATCH 029/110] drop support for LLVM <6.0.0 throughout Julia --- base/atomics.jl | 9 +- base/checked.jl | 4 - deps/llvm.mk | 105 +- .../compiler_rt-3.9-glibc_2.25.90.patch | 118 - deps/patches/lldb-3.7.1.patch | 41 - deps/patches/llvm-3.9-c_api_nullptr.patch | 39 - deps/patches/llvm-3.9-osx-10.12.patch | 33 - .../llvm-3.9.0-D37576-NVPTX-sm_70.patch | 62 - deps/patches/llvm-3.9.0_D27296-libssp.patch | 47 - deps/patches/llvm-3.9.0_threads.patch | 5545 ----------------- .../llvm-3.9.0_win64-reloc-dwarf.patch | 183 - .../llvm-4.0.0-D37576-NVPTX-sm_70.patch | 62 - deps/patches/llvm-4.0.0_threads.patch | 2032 ------ deps/patches/llvm-5.0-NVPTX-addrspaces.patch | 30 - deps/patches/llvm-5.0.0_threads.patch | 2072 ------ deps/patches/llvm-D23597_sdag_names.patch | 796 --- deps/patches/llvm-D24300_ptx_intrinsics.patch | 506 -- deps/patches/llvm-D25865-cmakeshlib.patch | 83 - deps/patches/llvm-D27389.patch | 66 - deps/patches/llvm-D27397.patch | 101 - .../patches/llvm-D27609-AArch64-UABS_G3.patch | 311 - .../llvm-D27629-AArch64-large_model.patch | 100 - deps/patches/llvm-D28009.patch | 68 - deps/patches/llvm-D28215_FreeBSD_shlib.patch | 13 - deps/patches/llvm-D28221-avx512.patch | 22 - ...vm-D28476-musl-targetlibraryinfo_3.9.patch | 3955 ------------ ...vm-D28476-musl-targetlibraryinfo_4.0.patch | 4480 ------------- deps/patches/llvm-D28759-loopclearance.patch | 480 -- deps/patches/llvm-D28786-callclearance.patch | 344 - .../llvm-D28786-callclearance_4.0.patch | 344 - deps/patches/llvm-D30114.patch | 92 - deps/patches/llvm-D30478-VNCoercion.patch | 1139 ---- deps/patches/llvm-D31524-sovers_4.0.patch | 82 - .../llvm-D32196-LIR-non-integral.patch | 95 - .../llvm-D32203-SORA-non-integral.patch | 99 - .../llvm-D32208-coerce-non-integral.patch | 137 - deps/patches/llvm-D32593.patch | 83 - .../llvm-D32623-GVN-non-integral.patch | 94 - ...llvm-D33110-codegen-prepare-inttoptr.patch | 119 - ...lvm-D33129-scevexpander-non-integral.patch | 153 - deps/patches/llvm-D33179.patch | 64 - ...vm-D37939-Mem2Reg-Also-handle-memcpy.patch | 365 -- deps/patches/llvm-D38765-gvn_5.0.patch | 51 - ...llvm-D39297-musl-dynamiclibrary-pre5.patch | 40 - .../llvm-D39297-musl-dynamiclibrary.patch | 40 - .../llvm-D9168_argument_alignment.patch | 98 - deps/patches/llvm-NVPTX-addrspaces.patch | 30 - deps/patches/llvm-PR22923.patch | 151 - deps/patches/llvm-PR276266.patch | 51 - deps/patches/llvm-PR277939.patch | 169 - deps/patches/llvm-PR278088.patch | 224 - deps/patches/llvm-PR278321.patch | 1409 ----- deps/patches/llvm-PR278923.patch | 69 - deps/patches/llvm-PR29010-i386-xmm.patch | 80 - deps/patches/llvm-PR36292-5.0.patch | 97 - deps/patches/llvm-PR36292.patch | 96 - deps/patches/llvm-VNCoercion-signatures.patch | 60 - deps/patches/llvm-VNCoercion-template.patch | 410 -- deps/patches/llvm-Yet-another-fix.patch | 40 - deps/patches/llvm-arm-fix-prel31.patch | 60 - deps/patches/llvm-loadcse-addrspace_4.0.patch | 61 - deps/patches/llvm-loadcse-addrspace_5.0.patch | 104 - deps/patches/llvm-rL293230-icc17-cmake.patch | 35 - doc/src/devdocs/llvm.md | 2 +- src/APInt-C.cpp | 6 - src/APInt-C.h | 4 - src/ccall.cpp | 58 - src/cgutils.cpp | 29 +- src/codegen.cpp | 65 +- src/codegen_shared.h | 24 - src/debuginfo.cpp | 14 - src/disasm.cpp | 17 - src/intrinsics.cpp | 23 - src/jitlayers.cpp | 121 +- src/jitlayers.h | 21 +- src/llvm-alloc-opt.cpp | 27 - src/llvm-lower-handlers.cpp | 7 - src/llvm-muladd.cpp | 34 - src/llvm-ptls.cpp | 5 - src/llvm-simdloop.cpp | 4 - src/llvm-version.h | 4 +- src/processor_arm.cpp | 2 +- src/processor_x86.cpp | 11 - test/llvmcall.jl | 22 +- 84 files changed, 23 insertions(+), 28425 deletions(-) delete mode 100644 deps/patches/compiler_rt-3.9-glibc_2.25.90.patch delete mode 100644 deps/patches/lldb-3.7.1.patch delete mode 100644 deps/patches/llvm-3.9-c_api_nullptr.patch delete mode 100644 deps/patches/llvm-3.9-osx-10.12.patch delete mode 100644 deps/patches/llvm-3.9.0-D37576-NVPTX-sm_70.patch delete mode 100644 deps/patches/llvm-3.9.0_D27296-libssp.patch delete mode 100644 deps/patches/llvm-3.9.0_threads.patch delete mode 100644 deps/patches/llvm-3.9.0_win64-reloc-dwarf.patch delete mode 100644 deps/patches/llvm-4.0.0-D37576-NVPTX-sm_70.patch delete mode 100644 deps/patches/llvm-4.0.0_threads.patch delete mode 100644 deps/patches/llvm-5.0-NVPTX-addrspaces.patch delete mode 100644 deps/patches/llvm-5.0.0_threads.patch delete mode 100644 deps/patches/llvm-D23597_sdag_names.patch delete mode 100644 deps/patches/llvm-D24300_ptx_intrinsics.patch delete mode 100644 deps/patches/llvm-D25865-cmakeshlib.patch delete mode 100644 deps/patches/llvm-D27389.patch delete mode 100644 deps/patches/llvm-D27397.patch delete mode 100644 deps/patches/llvm-D27609-AArch64-UABS_G3.patch delete mode 100644 deps/patches/llvm-D27629-AArch64-large_model.patch delete mode 100644 deps/patches/llvm-D28009.patch delete mode 100644 deps/patches/llvm-D28215_FreeBSD_shlib.patch delete mode 100644 deps/patches/llvm-D28221-avx512.patch delete mode 100644 deps/patches/llvm-D28476-musl-targetlibraryinfo_3.9.patch delete mode 100644 deps/patches/llvm-D28476-musl-targetlibraryinfo_4.0.patch delete mode 100644 deps/patches/llvm-D28759-loopclearance.patch delete mode 100644 deps/patches/llvm-D28786-callclearance.patch delete mode 100644 deps/patches/llvm-D28786-callclearance_4.0.patch delete mode 100644 deps/patches/llvm-D30114.patch delete mode 100644 deps/patches/llvm-D30478-VNCoercion.patch delete mode 100644 deps/patches/llvm-D31524-sovers_4.0.patch delete mode 100644 deps/patches/llvm-D32196-LIR-non-integral.patch delete mode 100644 deps/patches/llvm-D32203-SORA-non-integral.patch delete mode 100644 deps/patches/llvm-D32208-coerce-non-integral.patch delete mode 100644 deps/patches/llvm-D32593.patch delete mode 100644 deps/patches/llvm-D32623-GVN-non-integral.patch delete mode 100644 deps/patches/llvm-D33110-codegen-prepare-inttoptr.patch delete mode 100644 deps/patches/llvm-D33129-scevexpander-non-integral.patch delete mode 100644 deps/patches/llvm-D33179.patch delete mode 100644 deps/patches/llvm-D37939-Mem2Reg-Also-handle-memcpy.patch delete mode 100644 deps/patches/llvm-D38765-gvn_5.0.patch delete mode 100644 deps/patches/llvm-D39297-musl-dynamiclibrary-pre5.patch delete mode 100644 deps/patches/llvm-D39297-musl-dynamiclibrary.patch delete mode 100644 deps/patches/llvm-D9168_argument_alignment.patch delete mode 100644 deps/patches/llvm-NVPTX-addrspaces.patch delete mode 100644 deps/patches/llvm-PR22923.patch delete mode 100644 deps/patches/llvm-PR276266.patch delete mode 100644 deps/patches/llvm-PR277939.patch delete mode 100644 deps/patches/llvm-PR278088.patch delete mode 100644 deps/patches/llvm-PR278321.patch delete mode 100644 deps/patches/llvm-PR278923.patch delete mode 100644 deps/patches/llvm-PR29010-i386-xmm.patch delete mode 100644 deps/patches/llvm-PR36292-5.0.patch delete mode 100644 deps/patches/llvm-PR36292.patch delete mode 100644 deps/patches/llvm-VNCoercion-signatures.patch delete mode 100644 deps/patches/llvm-VNCoercion-template.patch delete mode 100644 deps/patches/llvm-Yet-another-fix.patch delete mode 100644 deps/patches/llvm-arm-fix-prel31.patch delete mode 100644 deps/patches/llvm-loadcse-addrspace_4.0.patch delete mode 100644 deps/patches/llvm-loadcse-addrspace_5.0.patch delete mode 100644 deps/patches/llvm-rL293230-icc17-cmake.patch diff --git a/base/atomics.jl b/base/atomics.jl index d98bed0742639..1d93f48a1def4 100644 --- a/base/atomics.jl +++ b/base/atomics.jl @@ -14,11 +14,8 @@ export atomic_max!, atomic_min!, atomic_fence -# Disable 128-bit types on 32-bit Intel systems due to LLVM problems; -# see (fixed on LLVM 3.9) # 128-bit atomics do not exist on AArch32. -if (Base.libllvm_version < v"3.9-" && ARCH === :i686) || - startswith(string(ARCH), "arm") +if startswith(string(ARCH), "arm") const inttypes = (Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64) else @@ -345,8 +342,8 @@ gc_alignment(::Type{T}) where {T} = ccall(:jl_alignment, Cint, (Csize_t,), sizeo for typ in atomictypes lt = llvmtypes[typ] ilt = llvmtypes[inttype(typ)] - rt = Base.libllvm_version >= v"3.6" ? "$lt, $lt*" : "$lt*" - irt = Base.libllvm_version >= v"3.6" ? "$ilt, $ilt*" : "$ilt*" + rt = "$lt, $lt*" + irt = "$ilt, $ilt*" @eval getindex(x::Atomic{$typ}) = llvmcall($""" %ptr = inttoptr i$WORD_SIZE %0 to $lt* diff --git a/base/checked.jl b/base/checked.jl index 794ce295e0c60..9b11e13caf796 100644 --- a/base/checked.jl +++ b/base/checked.jl @@ -64,10 +64,6 @@ if Core.sizeof(Ptr{Cvoid}) == 4 brokenSignedIntMul = Union{brokenSignedIntMul, Int64} brokenUnsignedIntMul = Union{brokenUnsignedIntMul, UInt64} end -if llvm_version < 30500 - brokenSignedIntMul = Union{brokenSignedIntMul, Int8} - brokenUnsignedIntMul = Union{brokenUnsignedIntMul, UInt8} -end const BrokenSignedInt = brokenSignedInt const BrokenUnsignedInt = brokenUnsignedInt const BrokenSignedIntMul = brokenSignedIntMul diff --git a/deps/llvm.mk b/deps/llvm.mk index 4f350aa443b25..9cc2aa2090530 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -384,102 +384,7 @@ $$(LLVM_BUILDDIR_withtype)/build-compiled: $$(LLVM_SRC_DIR)/$1.patch-applied LLVM_PATCH_PREV := $$(LLVM_SRC_DIR)/$1.patch-applied endef -ifeq ($(LLVM_VER_SHORT),3.9) -$(eval $(call LLVM_PATCH,llvm-PR22923)) # Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-arm-fix-prel31)) # Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-D25865-cmakeshlib)) # Remove for 4.0 -# Cygwin and openSUSE still use win32-threads mingw, https://llvm.org/bugs/show_bug.cgi?id=26365 -$(eval $(call LLVM_PATCH,llvm-3.9.0_threads)) -$(eval $(call LLVM_PATCH,llvm-3.9.0_win64-reloc-dwarf)) # modified version applied as R290809, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-3.9.0_D27296-libssp)) -$(eval $(call LLVM_PATCH,llvm-D27609-AArch64-UABS_G3)) # Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-D27629-AArch64-large_model)) -$(eval $(call LLVM_PATCH,llvm-NVPTX-addrspaces)) # NVPTX -$(eval $(call LLVM_PATCH,llvm-D9168_argument_alignment)) # NVPTX, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-D23597_sdag_names)) # NVPTX, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-D24300_ptx_intrinsics)) # NVPTX, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-D27389)) # Julia issue #19792, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-D27397)) # Julia issue #19792, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-D28009)) # Julia issue #19792, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-D28215_FreeBSD_shlib)) -$(eval $(call LLVM_PATCH,llvm-D28221-avx512)) # mentioned in issue #19797 -$(eval $(call LLVM_PATCH,llvm-PR276266)) # Issue #19976, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-PR278088)) # Issue #19976, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-PR277939)) # Issue #19976, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-PR278321)) # Issue #19976, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-PR278923)) # Issue #19976, Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-D28759-loopclearance)) -$(eval $(call LLVM_PATCH,llvm-D28786-callclearance)) -$(eval $(call LLVM_PATCH,llvm-rL293230-icc17-cmake)) # Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-D32593)) -$(eval $(call LLVM_PATCH,llvm-D33179)) -$(eval $(call LLVM_PATCH,llvm-PR29010-i386-xmm)) # Remove for 4.0 -$(eval $(call LLVM_PATCH,llvm-3.9.0-D37576-NVPTX-sm_70)) # NVPTX, Remove for 6.0 -$(eval $(call LLVM_PATCH,llvm-D37939-Mem2Reg-Also-handle-memcpy)) -$(eval $(call LLVM_PATCH,llvm-D31524-sovers_4.0)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D42262-jumpthreading-not-i1)) -$(eval $(call LLVM_PATCH,llvm-3.9-c_api_nullptr)) -$(eval $(call LLVM_PATCH,llvm-PPC-addrspaces)) # PPC -$(eval $(call LLVM_PATCH,llvm-D30114)) # PPC remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-PR36292)) # PPC fixes #26249, remove for 6.0 -$(eval $(call LLVM_PATCH,llvm-D39297-musl-dynamiclibrary-pre5)) # Remove for 6.0 -$(eval $(call LLVM_PATCH,llvm-D28476-musl-targetlibraryinfo_3.9)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D46460)) -ifeq ($(BUILD_LLVM_CLANG),1) -$(eval $(call LLVM_PATCH,compiler_rt-3.9-glibc_2.25.90)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,clang-D28477)) # Remove for 5.0 -endif -else ifeq ($(LLVM_VER_SHORT),4.0) -# Cygwin and openSUSE still use win32-threads mingw, https://llvm.org/bugs/show_bug.cgi?id=26365 -$(eval $(call LLVM_PATCH,llvm-4.0.0_threads)) -$(eval $(call LLVM_PATCH,llvm-3.9.0_D27296-libssp)) -$(eval $(call LLVM_PATCH,llvm-D27629-AArch64-large_model_4.0)) -$(eval $(call LLVM_PATCH,llvm-D28215_FreeBSD_shlib)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D28759-loopclearance)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D28786-callclearance_4.0)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D32593)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D33179)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D32203-SORA-non-integral)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D33110-codegen-prepare-inttoptr)) -$(eval $(call LLVM_PATCH,llvm-D30478-VNCoercion)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-VNCoercion-signatures)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-VNCoercion-template)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D32196-LIR-non-integral)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D32208-coerce-non-integral)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D32623-GVN-non-integral)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D33129-scevexpander-non-integral)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-Yet-another-fix)) -$(eval $(call LLVM_PATCH,llvm-NVPTX-addrspaces)) # NVPTX -$(eval $(call LLVM_PATCH,llvm-4.0.0-D37576-NVPTX-sm_70)) # NVPTX, Remove for 6.0 -$(eval $(call LLVM_PATCH,llvm-loadcse-addrspace_4.0)) -$(eval $(call LLVM_PATCH,llvm-D31524-sovers_4.0)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D42262-jumpthreading-not-i1)) -$(eval $(call LLVM_PATCH,llvm-PPC-addrspaces)) # PPC -$(eval $(call LLVM_PATCH,llvm-D30114)) # PPC remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-PR36292)) # PPC fixes #26249, remove for 6.0 -$(eval $(call LLVM_PATCH,llvm-D39297-musl-dynamiclibrary-pre5)) # Remove for 6.0 -$(eval $(call LLVM_PATCH,llvm-D28476-musl-targetlibraryinfo_4.0)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,llvm-D46460)) -ifeq ($(BUILD_LLVM_CLANG),1) -$(eval $(call LLVM_PATCH,compiler_rt-3.9-glibc_2.25.90)) # Remove for 5.0 -$(eval $(call LLVM_PATCH,clang-D28477)) # Remove for 5.0 -endif -else ifeq ($(LLVM_VER_SHORT),5.0) -# Cygwin and openSUSE still use win32-threads mingw, https://llvm.org/bugs/show_bug.cgi?id=26365 -$(eval $(call LLVM_PATCH,llvm-5.0.0_threads)) -$(eval $(call LLVM_PATCH,llvm-3.9.0_D27296-libssp)) -$(eval $(call LLVM_PATCH,llvm-D27629-AArch64-large_model_4.0)) -$(eval $(call LLVM_PATCH,llvm-loadcse-addrspace_5.0)) -$(eval $(call LLVM_PATCH,llvm-D34078-vectorize-fdiv)) -$(eval $(call LLVM_PATCH,llvm-5.0-NVPTX-addrspaces)) # NVPTX -$(eval $(call LLVM_PATCH,llvm-4.0.0-D37576-NVPTX-sm_70)) # NVPTX, Remove for 6.0 -$(eval $(call LLVM_PATCH,llvm-D38765-gvn_5.0)) # Remove for 6.0 -$(eval $(call LLVM_PATCH,llvm-D42262-jumpthreading-not-i1)) # remove for 7.0 -$(eval $(call LLVM_PATCH,llvm-PPC-addrspaces)) # PPC -$(eval $(call LLVM_PATCH,llvm-PR36292-5.0)) # PPC fixes #26249, remove for 6.0 -$(eval $(call LLVM_PATCH,llvm-D39297-musl-dynamiclibrary)) # Remove for 6.0 -$(eval $(call LLVM_PATCH,llvm-D46460)) -else ifeq ($(LLVM_VER_SHORT),6.0) +ifeq ($(LLVM_VER_SHORT),6.0) $(eval $(call LLVM_PATCH,llvm-D27629-AArch64-large_model_4.0)) $(eval $(call LLVM_PATCH,llvm-D34078-vectorize-fdiv)) $(eval $(call LLVM_PATCH,llvm-6.0-NVPTX-addrspaces)) # NVPTX @@ -509,15 +414,7 @@ $(eval $(call LLVM_PATCH,llvm-D50167-scev-umin)) $(eval $(call LLVM_PATCH,llvm-windows-race)) endif # LLVM_VER -# Remove hardcoded OS X requirements in compilter-rt cmake build -ifeq ($(LLVM_VER_SHORT),3.9) -ifeq ($(BUILD_LLVM_CLANG),1) -$(eval $(call LLVM_PATCH,llvm-3.9-osx-10.12)) -endif -endif - # Independent to the llvm version add a JL prefix to the version map -# Depends on `llvm-D31524-sovers_4.0` for LLVM_VER==3.9 $(eval $(call LLVM_PATCH,llvm-symver-jlprefix)) # DO NOT REMOVE diff --git a/deps/patches/compiler_rt-3.9-glibc_2.25.90.patch b/deps/patches/compiler_rt-3.9-glibc_2.25.90.patch deleted file mode 100644 index 8fe993a637512..0000000000000 --- a/deps/patches/compiler_rt-3.9-glibc_2.25.90.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 8a5e425a68de4d2c80ff00a97bbcb3722a4716da Mon Sep 17 00:00:00 2001 -From: Kostya Serebryany -Date: Thu, 13 Jul 2017 21:59:01 +0000 -Subject: [PATCH] Fix sanitizer build against latest glibc - -Summary: -libsanitizer doesn't build against latest glibc anymore, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81066 for details. -One of the changes is that stack_t changed from typedef struct sigaltstack { ... } stack_t; to typedef struct { ... } stack_t; for conformance reasons. -And the other change is that the glibc internal __need_res_state macro is now ignored, so when doing -``` -#define __need_res_state -#include -``` -the effect is now the same as just -``` -#include -``` -and thus one doesn't get just the -``` -struct __res_state { ... }; -``` -definition, but newly also the -``` -extern struct __res_state *__res_state(void) __attribute__ ((__const__)); -``` -prototype. So __res_state is no longer a type, but a function. - -Reviewers: kcc, ygribov - -Reviewed By: kcc - -Subscribers: kubamracek - -Differential Revision: https://reviews.llvm.org/D35246 - -git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@307969 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/sanitizer_common/sanitizer_linux.cc | 3 +-- - lib/sanitizer_common/sanitizer_linux.h | 4 +--- - lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc | 2 +- - lib/tsan/rtl/tsan_platform_linux.cc | 2 +- - 4 files changed, 4 insertions(+), 7 deletions(-) - -diff --git a/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc b/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc -index a79a2a155..8c3c1e5d6 100644 ---- a/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc -+++ b/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc -@@ -629,8 +629,7 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) { - } - #endif - --uptr internal_sigaltstack(const struct sigaltstack *ss, -- struct sigaltstack *oss) { -+uptr internal_sigaltstack(const void *ss, void *oss) { - return internal_syscall(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss); - } - -diff --git a/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.h -index ee336f7dd..11cad6b80 100644 ---- a/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.h -+++ b/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.h -@@ -21,7 +21,6 @@ - #include "sanitizer_platform_limits_posix.h" - - struct link_map; // Opaque type returned by dlopen(). --struct sigaltstack; - - namespace __sanitizer { - // Dirent structure for getdents(). Note that this structure is different from -@@ -30,8 +29,7 @@ struct linux_dirent; - - // Syscall wrappers. - uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count); --uptr internal_sigaltstack(const struct sigaltstack* ss, -- struct sigaltstack* oss); -+uptr internal_sigaltstack(const void* ss, void* oss); - uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, - __sanitizer_sigset_t *oldset); - -diff --git a/projects/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/projects/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc -index 03f73ae88..d7fa5f645 100644 ---- a/projects/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc -+++ b/projects/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc -@@ -287,7 +287,7 @@ static int TracerThread(void* argument) { - - // Alternate stack for signal handling. - InternalScopedBuffer handler_stack_memory(kHandlerStackSize); -- struct sigaltstack handler_stack; -+ stack_t handler_stack; - internal_memset(&handler_stack, 0, sizeof(handler_stack)); - handler_stack.ss_sp = handler_stack_memory.data(); - handler_stack.ss_size = kHandlerStackSize; -diff --git a/projects/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc b/projects/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc -index 0ba01babe..ead1e5704 100644 ---- a/projects/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc -+++ b/projects/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc -@@ -286,7 +286,7 @@ void InitializePlatform() { - int ExtractResolvFDs(void *state, int *fds, int nfd) { - #if SANITIZER_LINUX && !SANITIZER_ANDROID - int cnt = 0; -- __res_state *statp = (__res_state*)state; -+ struct __res_state *statp = (struct __res_state*)state; - for (int i = 0; i < MAXNS && cnt < nfd; i++) { - if (statp->_u._ext.nsaddrs[i] && statp->_u._ext.nssocks[i] != -1) - fds[cnt++] = statp->_u._ext.nssocks[i]; -diff --git a/projects/compiler-rt/lib/esan/esan_sideline_linux.cpp b/projects/compiler-rt/lib/esan/esan_sideline_linux.cpp -index d04f5909d6a2..bc272dfe49f8 100644 ---- a/projects/compiler-rt/lib/esan/esan_sideline_linux.cpp -+++ b/projects/compiler-rt/lib/esan/esan_sideline_linux.cpp -@@ -70,7 +70,7 @@ int SidelineThread::runSideline(void *Arg) { - - // Set up a signal handler on an alternate stack for safety. - InternalScopedBuffer StackMap(SigAltStackSize); -- struct sigaltstack SigAltStack; -+ stack_t SigAltStack; - SigAltStack.ss_sp = StackMap.data(); - SigAltStack.ss_size = SigAltStackSize; - SigAltStack.ss_flags = 0; diff --git a/deps/patches/lldb-3.7.1.patch b/deps/patches/lldb-3.7.1.patch deleted file mode 100644 index 15ace008c4991..0000000000000 --- a/deps/patches/lldb-3.7.1.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff --git a/tools/lldb/source/Host/Makefile b/tools/lldb/source/Host/Makefile -index a8e4260..da90c8c 100644 ---- a/tools/lldb/source/Host/Makefile -+++ b/tools/lldb/source/Host/Makefile -@@ -14,7 +14,7 @@ include $(LEVEL)/Makefile.config - - define DIR_SOURCES - SOURCES += $$(addprefix $(1)/,$$(notdir $$(wildcard $$(PROJ_SRC_DIR)/$(1)/*.cpp \ -- $$(PROJ_SRC_DIR)/*.cc $$(PROJ_SRC_DIR)/$(1)/*.c))) -+ $$(PROJ_SRC_DIR)/*.cc $$(PROJ_SRC_DIR)/$(1)/*.c $$(PROJ_SRC_DIR)/$(1)/*.mm))) - endef - - $(eval $(call DIR_SOURCES,common)) -@@ -22,6 +22,15 @@ $(eval $(call DIR_SOURCES,common)) - ifeq ($(HOST_OS),Darwin) - $(eval $(call DIR_SOURCES,posix)) - $(eval $(call DIR_SOURCES,macosx)) -+CFCPP_SOURCES = \ -+ $(addprefix macosx/cfcpp/,$(notdir $(wildcard $(PROJ_SRC_DIR)/macosx/cfcpp/*.cpp))) -+SOURCES += $(CFCPP_SOURCES) -+ -+CFCPP_BaseNameSources := $(sort $(basename $(CFCPP_SOURCES))) -+CFCPP_OBJECTS := $(CFCPP_BaseNameSources:%=$(ObjDir)/%.o) -+ -+# Make sure the cfcpp output directory exists -+$(CFCPP_OBJECTS): $(ObjDir)/cfcpp/.dir - endif - - ifeq ($(HOST_OS),Linux) -@@ -34,6 +43,11 @@ $(eval $(call DIR_SOURCES,posix)) - $(eval $(call DIR_SOURCES,freebsd)) - endif - -+ifeq ($(HOST_OS),NetBSD) -+$(eval $(call DIR_SOURCES,posix)) -+$(eval $(call DIR_SOURCES,netbsd)) -+endif -+ - ifeq ($(HOST_OS),MingW) - $(eval $(call DIR_SOURCES,windows)) - endif diff --git a/deps/patches/llvm-3.9-c_api_nullptr.patch b/deps/patches/llvm-3.9-c_api_nullptr.patch deleted file mode 100644 index 606d2944deddd..0000000000000 --- a/deps/patches/llvm-3.9-c_api_nullptr.patch +++ /dev/null @@ -1,39 +0,0 @@ -diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp -index 1cf17b1f311..a969e08cabc 100644 ---- a/lib/IR/Core.cpp -+++ b/lib/IR/Core.cpp -@@ -1842,12 +1842,16 @@ void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, - - unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx) { - auto *ASN = AttributeSetNode::get(unwrap(F)->getAttributes(), Idx); -+ if (!ASN) -+ return 0; - return ASN->getNumAttributes(); - } - - void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, - LLVMAttributeRef *Attrs) { - auto *ASN = AttributeSetNode::get(unwrap(F)->getAttributes(), Idx); -+ if (!ASN) -+ return; - for (auto A: make_range(ASN->begin(), ASN->end())) - *Attrs++ = wrap(A); - } -@@ -2173,6 +2177,8 @@ unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C, - LLVMAttributeIndex Idx) { - auto CS = CallSite(unwrap(C)); - auto *ASN = AttributeSetNode::get(CS.getAttributes(), Idx); -+ if (!ASN) -+ return 0; - return ASN->getNumAttributes(); - } - -@@ -2180,6 +2186,8 @@ void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx, - LLVMAttributeRef *Attrs) { - auto CS = CallSite(unwrap(C)); - auto *ASN = AttributeSetNode::get(CS.getAttributes(), Idx); -+ if (!ASN) -+ return; - for (auto A: make_range(ASN->begin(), ASN->end())) - *Attrs++ = wrap(A); - } diff --git a/deps/patches/llvm-3.9-osx-10.12.patch b/deps/patches/llvm-3.9-osx-10.12.patch deleted file mode 100644 index a9148e5e947e7..0000000000000 --- a/deps/patches/llvm-3.9-osx-10.12.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/projects/compiler-rt/cmake/builtin-config-ix.cmake -+++ b/projects/compiler-rt/cmake/builtin-config-ix.cmake -@@ -57,9 +57,6 @@ - find_darwin_sdk_dir(DARWIN_tvos_SYSROOT appletvos) - - set(DARWIN_EMBEDDED_PLATFORMS) -- set(DARWIN_osx_BUILTIN_MIN_VER 10.5) -- set(DARWIN_osx_BUILTIN_MIN_VER_FLAG -- -mmacosx-version-min=${DARWIN_osx_BUILTIN_MIN_VER}) - - if(COMPILER_RT_ENABLE_IOS) - list(APPEND DARWIN_EMBEDDED_PLATFORMS ios) -@@ -101,20 +98,6 @@ - set(CAN_TARGET_${arch} 1) - endforeach() - -- # Need to build a 10.4 compatible libclang_rt -- set(DARWIN_10.4_SYSROOT ${DARWIN_osx_SYSROOT}) -- set(DARWIN_10.4_BUILTIN_MIN_VER 10.4) -- set(DARWIN_10.4_BUILTIN_MIN_VER_FLAG -- -mmacosx-version-min=${DARWIN_10.4_BUILTIN_MIN_VER}) -- set(DARWIN_10.4_SKIP_CC_KEXT On) -- darwin_test_archs(10.4 DARWIN_10.4_ARCHS i386 x86_64) -- message(STATUS "OSX 10.4 supported builtin arches: ${DARWIN_10.4_ARCHS}") -- if(DARWIN_10.4_ARCHS) -- # don't include the Haswell slice in the 10.4 compatibility library -- list(REMOVE_ITEM DARWIN_10.4_ARCHS x86_64h) -- list(APPEND BUILTIN_SUPPORTED_OS 10.4) -- endif() -- - foreach(platform ${DARWIN_EMBEDDED_PLATFORMS}) - if(DARWIN_${platform}sim_SYSROOT) - set(DARWIN_${platform}sim_BUILTIN_MIN_VER diff --git a/deps/patches/llvm-3.9.0-D37576-NVPTX-sm_70.patch b/deps/patches/llvm-3.9.0-D37576-NVPTX-sm_70.patch deleted file mode 100644 index 0ac8e44cc5c64..0000000000000 --- a/deps/patches/llvm-3.9.0-D37576-NVPTX-sm_70.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 4059d374ce981827223ab6b1dae7af4ec5f8e74a Mon Sep 17 00:00:00 2001 -From: Artem Belevich -Date: Thu, 7 Sep 2017 18:14:32 +0000 -Subject: [PATCH] [CUDA] Added rudimentary support for CUDA-9 and sm_70. - -For now CUDA-9 is not included in the list of CUDA versions clang -searches for, so the path to CUDA-9 must be explicitly passed -via --cuda-path=. - -On LLVM side NVPTX added sm_70 GPU type which bumps required -PTX version to 6.0, but otherwise is equivalent to sm_62 at the moment. - -Differential Revision: https://reviews.llvm.org/D37576 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312734 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Target/NVPTX/NVPTX.td | 5 +++++ - test/CodeGen/NVPTX/sm-version-70.ll | 5 +++++ - 2 files changed, 10 insertions(+) - create mode 100644 test/CodeGen/NVPTX/sm-version-70.ll - -diff --git a/lib/Target/NVPTX/NVPTX.td b/lib/Target/NVPTX/NVPTX.td -index c77ddbc9978..aba37d36359 100644 ---- a/lib/Target/NVPTX/NVPTX.td -+++ b/lib/Target/NVPTX/NVPTX.td -@@ -50,6 +50,8 @@ def SM61 : SubtargetFeature<"sm_61", "SmVersion", "61", - "Target SM 6.1">; - def SM62 : SubtargetFeature<"sm_62", "SmVersion", "62", - "Target SM 6.2">; -+def SM70 : SubtargetFeature<"sm_70", "SmVersion", "70", -+ "Target SM 7.0">; - - def SATOM : SubtargetFeature<"satom", "HasAtomScope", "true", - "Atomic operations with scope">; -@@ -67,6 +69,8 @@ def PTX43 : SubtargetFeature<"ptx43", "PTXVersion", "43", - "Use PTX version 4.3">; - def PTX50 : SubtargetFeature<"ptx50", "PTXVersion", "50", - "Use PTX version 5.0">; -+def PTX60 : SubtargetFeature<"ptx60", "PTXVersion", "60", -+ "Use PTX version 6.0">; - - //===----------------------------------------------------------------------===// - // NVPTX supported processors. -@@ -87,6 +91,7 @@ def : Proc<"sm_53", [SM53, PTX42]>; - def : Proc<"sm_60", [SM60, PTX50]>; - def : Proc<"sm_61", [SM61, PTX50]>; - def : Proc<"sm_62", [SM62, PTX50]>; -+def : Proc<"sm_70", [SM70, PTX60]>; - - def NVPTXInstrInfo : InstrInfo { - } -diff --git a/test/CodeGen/NVPTX/sm-version-70.ll b/test/CodeGen/NVPTX/sm-version-70.ll -new file mode 100644 -index 00000000000..8b72d50747a ---- /dev/null -+++ b/test/CodeGen/NVPTX/sm-version-70.ll -@@ -0,0 +1,5 @@ -+; RUN: llc < %s -march=nvptx -mcpu=sm_70 | FileCheck %s -+; RUN: llc < %s -march=nvptx64 -mcpu=sm_70 | FileCheck %s -+ -+; CHECK: .version 6.0 -+; CHECK: .target sm_70 diff --git a/deps/patches/llvm-3.9.0_D27296-libssp.patch b/deps/patches/llvm-3.9.0_D27296-libssp.patch deleted file mode 100644 index 7bdfa67f80034..0000000000000 --- a/deps/patches/llvm-3.9.0_D27296-libssp.patch +++ /dev/null @@ -1,47 +0,0 @@ -From e95516f77127ca534775d5f8d8cbb6e2e9c3f993 Mon Sep 17 00:00:00 2001 -From: Valentin Churavy -Date: Thu, 1 Dec 2016 18:48:30 +0900 -Subject: [PATCH] Don't assume mingw is providing SSP functions - -Summary: -Mingw is indirectly targeting msvcrt*.dll and we can't guarantee that -these functions will be available during JIT'ing. - -Differential Revision: https://reviews.llvm.org/D27296 ---- - lib/Target/X86/X86ISelLowering.cpp | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp -index 44eae35..a932792 100644 ---- a/lib/Target/X86/X86ISelLowering.cpp -+++ b/lib/Target/X86/X86ISelLowering.cpp -@@ -2016,7 +2016,7 @@ Value *X86TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const { - - void X86TargetLowering::insertSSPDeclarations(Module &M) const { - // MSVC CRT provides functionalities for stack protection. -- if (Subtarget.getTargetTriple().isOSMSVCRT()) { -+ if (Subtarget.getTargetTriple().isWindowsMSVCEnvironment()) { - // MSVC CRT has a global variable holding security cookie. - M.getOrInsertGlobal("__security_cookie", - Type::getInt8PtrTy(M.getContext())); -@@ -2038,14 +2038,14 @@ void X86TargetLowering::insertSSPDeclarations(Module &M) const { - - Value *X86TargetLowering::getSDagStackGuard(const Module &M) const { - // MSVC CRT has a global variable holding security cookie. -- if (Subtarget.getTargetTriple().isOSMSVCRT()) -+ if (Subtarget.getTargetTriple().isWindowsMSVCEnvironment()) - return M.getGlobalVariable("__security_cookie"); - return TargetLowering::getSDagStackGuard(M); - } - - Value *X86TargetLowering::getSSPStackGuardCheck(const Module &M) const { - // MSVC CRT has a function to validate security cookie. -- if (Subtarget.getTargetTriple().isOSMSVCRT()) -+ if (Subtarget.getTargetTriple().isWindowsMSVCEnvironment()) - return M.getFunction("__security_check_cookie"); - return TargetLowering::getSSPStackGuardCheck(M); - } --- -2.10.2 - diff --git a/deps/patches/llvm-3.9.0_threads.patch b/deps/patches/llvm-3.9.0_threads.patch deleted file mode 100644 index 1b28f8131322d..0000000000000 --- a/deps/patches/llvm-3.9.0_threads.patch +++ /dev/null @@ -1,5545 +0,0 @@ -From d1cc48989b13780f21c408fef17dceb104a09c9d Mon Sep 17 00:00:00 2001 -From: Alex Crichton -Date: Thu, 28 Jan 2016 20:44:50 -0800 -Subject: [PATCH] Don't compile usage of std::thread - -As of the time of this writing it's not actually used anywhere meaningfullly -throughout the LLVM repo that we need, and it unfortunately uses `std::thread` -which isn't available in mingw-w64 toolchains with the win32 threading model -(the one that we use). - -The change made to achive this was to just always use the single-threaded -support in `include/llvm/Support/thread.h`, and hopefuly that'll be enough... - -For reference, the upstream LLVM bug has been reported [1] - -[1]: https://llvm.org/bugs/show_bug.cgi?id=26365 ---- - include/llvm/ExecutionEngine/Orc/RPCChannel.h | 13 - - include/llvm/ExecutionEngine/Orc/RPCUtils.h | 16 +- - include/llvm/Support/ThreadPool.h | 4 + - include/llvm/Support/thread.h | 2 +- - lib/CodeGen/ParallelCG.cpp | 2 + - lib/LTO/ThinLTOCodeGenerator.cpp | 4 +- - lib/Support/ThreadPool.cpp | 6 +- - test/CMakeLists.txt | 1 - - tools/lli/CMakeLists.txt | 5 - - tools/lli/ChildTarget/CMakeLists.txt | 10 - - tools/lli/ChildTarget/ChildTarget.cpp | 78 -- - tools/lli/ChildTarget/LLVMBuild.txt | 21 - - tools/lli/LLVMBuild.txt | 3 - - tools/lli/OrcLazyJIT.cpp | 158 ---- - tools/lli/OrcLazyJIT.h | 163 ---- - tools/lli/RemoteJITUtils.h | 152 --- - tools/lli/lli.cpp | 7 + - tools/llvm-cov/CMakeLists.txt | 18 +- - tools/llvm-cov/CodeCoverage.cpp | 727 --------------- - tools/llvm-cov/CoverageFilters.cpp | 59 -- - tools/llvm-cov/CoverageFilters.h | 127 --- - tools/llvm-cov/CoverageReport.cpp | 235 ----- - tools/llvm-cov/CoverageReport.h | 41 - - tools/llvm-cov/CoverageSummaryInfo.cpp | 71 -- - tools/llvm-cov/CoverageSummaryInfo.h | 162 ---- - tools/llvm-cov/CoverageViewOptions.h | 52 -- - tools/llvm-cov/RenderingSupport.h | 61 -- - tools/llvm-cov/SourceCoverageView.cpp | 233 ----- - tools/llvm-cov/SourceCoverageView.h | 285 ------ - tools/llvm-cov/SourceCoverageViewHTML.cpp | 436 --------- - tools/llvm-cov/SourceCoverageViewHTML.h | 83 -- - tools/llvm-cov/SourceCoverageViewText.cpp | 213 ----- - tools/llvm-cov/SourceCoverageViewText.h | 83 -- - tools/llvm-cov/TestingSupport.cpp | 92 -- - tools/llvm-cov/gcov.cpp | 145 --- - tools/llvm-cov/llvm-cov.cpp | 79 -- - tools/sancov/sancov.cc | 1244 +------------------------ - 37 files changed, 43 insertions(+), 5048 deletions(-) - delete mode 100644 tools/lli/ChildTarget/CMakeLists.txt - delete mode 100644 tools/lli/ChildTarget/ChildTarget.cpp - delete mode 100644 tools/lli/ChildTarget/LLVMBuild.txt - delete mode 100644 tools/lli/OrcLazyJIT.cpp - delete mode 100644 tools/lli/OrcLazyJIT.h - delete mode 100644 tools/lli/RemoteJITUtils.h - delete mode 100644 tools/llvm-cov/CodeCoverage.cpp - delete mode 100644 tools/llvm-cov/CoverageFilters.cpp - delete mode 100644 tools/llvm-cov/CoverageFilters.h - delete mode 100644 tools/llvm-cov/CoverageReport.cpp - delete mode 100644 tools/llvm-cov/CoverageReport.h - delete mode 100644 tools/llvm-cov/CoverageSummaryInfo.cpp - delete mode 100644 tools/llvm-cov/CoverageSummaryInfo.h - delete mode 100644 tools/llvm-cov/CoverageViewOptions.h - delete mode 100644 tools/llvm-cov/RenderingSupport.h - delete mode 100644 tools/llvm-cov/SourceCoverageView.cpp - delete mode 100644 tools/llvm-cov/SourceCoverageView.h - delete mode 100644 tools/llvm-cov/SourceCoverageViewHTML.cpp - delete mode 100644 tools/llvm-cov/SourceCoverageViewHTML.h - delete mode 100644 tools/llvm-cov/SourceCoverageViewText.cpp - delete mode 100644 tools/llvm-cov/SourceCoverageViewText.h - delete mode 100644 tools/llvm-cov/TestingSupport.cpp - delete mode 100644 tools/llvm-cov/gcov.cpp - -diff --git a/include/llvm/ExecutionEngine/Orc/RPCChannel.h b/include/llvm/ExecutionEngine/Orc/RPCChannel.h -index c569e3c..9fb0141 100644 ---- a/include/llvm/ExecutionEngine/Orc/RPCChannel.h -+++ b/include/llvm/ExecutionEngine/Orc/RPCChannel.h -@@ -40,42 +40,29 @@ class RPCChannel { - - /// Flush the stream if possible. - virtual Error send() = 0; -- -- /// Get the lock for stream reading. -- std::mutex &getReadLock() { return readLock; } -- -- /// Get the lock for stream writing. -- std::mutex &getWriteLock() { return writeLock; } -- --private: -- std::mutex readLock, writeLock; - }; - - /// Notify the channel that we're starting a message send. - /// Locks the channel for writing. - inline Error startSendMessage(RPCChannel &C) { -- C.getWriteLock().lock(); - return Error::success(); - } - - /// Notify the channel that we're ending a message send. - /// Unlocks the channel for writing. - inline Error endSendMessage(RPCChannel &C) { -- C.getWriteLock().unlock(); - return Error::success(); - } - - /// Notify the channel that we're starting a message receive. - /// Locks the channel for reading. - inline Error startReceiveMessage(RPCChannel &C) { -- C.getReadLock().lock(); - return Error::success(); - } - - /// Notify the channel that we're ending a message receive. - /// Unlocks the channel for reading. - inline Error endReceiveMessage(RPCChannel &C) { -- C.getReadLock().unlock(); - return Error::success(); - } - -diff --git a/include/llvm/ExecutionEngine/Orc/RPCUtils.h b/include/llvm/ExecutionEngine/Orc/RPCUtils.h -index 966a496..b6c8ebd 100644 ---- a/include/llvm/ExecutionEngine/Orc/RPCUtils.h -+++ b/include/llvm/ExecutionEngine/Orc/RPCUtils.h -@@ -102,6 +102,7 @@ class RPCBase { - - template - static Error readResult(ChannelT &C, std::promise &P) { -+#if 0 - RetT Val; - auto Err = deserialize(C, Val); - auto Err2 = endReceiveMessage(C); -@@ -112,11 +113,14 @@ class RPCBase { - return Err; - } - P.set_value(std::move(Val)); -+#endif - return Error::success(); - } - - static void abandon(std::promise &P) { -+#if 0 - P.set_value(OptionalReturn()); -+#endif - } - - template -@@ -159,11 +163,17 @@ class RPCBase { - template - static Error readResult(ChannelT &C, std::promise &P) { - // Void functions don't have anything to deserialize, so we're good. -+#if 0 - P.set_value(true); -+#endif - return endReceiveMessage(C); - } - -- static void abandon(std::promise &P) { P.set_value(false); } -+ static void abandon(std::promise &P) { -+#if 0 -+ P.set_value(false); -+#endif -+ } - - template - static Error respond(ChannelT &C, SequenceNumberT SeqNo, -@@ -617,13 +627,11 @@ class RPC : public RPCBase { - } - - void reset() { -- std::lock_guard Lock(SeqNoLock); - NextSequenceNumber = 0; - FreeSequenceNumbers.clear(); - } - - SequenceNumberT getSequenceNumber() { -- std::lock_guard Lock(SeqNoLock); - if (FreeSequenceNumbers.empty()) - return NextSequenceNumber++; - auto SequenceNumber = FreeSequenceNumbers.back(); -@@ -632,12 +640,10 @@ class RPC : public RPCBase { - } - - void releaseSequenceNumber(SequenceNumberT SequenceNumber) { -- std::lock_guard Lock(SeqNoLock); - FreeSequenceNumbers.push_back(SequenceNumber); - } - - private: -- std::mutex SeqNoLock; - SequenceNumberT NextSequenceNumber = 0; - std::vector FreeSequenceNumbers; - }; -diff --git a/include/llvm/Support/ThreadPool.h b/include/llvm/Support/ThreadPool.h -index 665cec2..c3aa64d 100644 ---- a/include/llvm/Support/ThreadPool.h -+++ b/include/llvm/Support/ThreadPool.h -@@ -16,6 +16,8 @@ - - #include "llvm/Support/thread.h" - -+# if 0 -+ - #ifdef _MSC_VER - // concrt.h depends on eh.h for __uncaught_exception declaration - // even if we disable exceptions. -@@ -134,4 +136,6 @@ class ThreadPool { - }; - } - -+# endif -+ - #endif // LLVM_SUPPORT_THREAD_POOL_H -diff --git a/include/llvm/Support/thread.h b/include/llvm/Support/thread.h -index 9c45418..27d42d2 100644 ---- a/include/llvm/Support/thread.h -+++ b/include/llvm/Support/thread.h -@@ -19,7 +19,7 @@ - - #include "llvm/Config/llvm-config.h" - --#if LLVM_ENABLE_THREADS -+#if LLVM_ENABLE_THREADS && 0 - - #ifdef _MSC_VER - // concrt.h depends on eh.h for __uncaught_exception declaration -diff --git a/lib/CodeGen/ParallelCG.cpp b/lib/CodeGen/ParallelCG.cpp -index ccdaec1..1f35590 100644 ---- a/lib/CodeGen/ParallelCG.cpp -+++ b/lib/CodeGen/ParallelCG.cpp -@@ -49,6 +49,7 @@ std::unique_ptr llvm::splitCodeGen( - return M; - } - -+#if 0 - // Create ThreadPool in nested scope so that threads will be joined - // on destruction. - { -@@ -95,5 +96,6 @@ std::unique_ptr llvm::splitCodeGen( - PreserveLocals); - } - -+#endif - return {}; - } -diff --git a/lib/LTO/ThinLTOCodeGenerator.cpp b/lib/LTO/ThinLTOCodeGenerator.cpp -index bfb0980..e4f9977 100644 ---- a/lib/LTO/ThinLTOCodeGenerator.cpp -+++ b/lib/LTO/ThinLTOCodeGenerator.cpp -@@ -64,7 +64,7 @@ extern cl::opt LTODiscardValueNames; - namespace { - - static cl::opt ThreadCount("threads", -- cl::init(std::thread::hardware_concurrency())); -+ cl::init(1)); - - static void diagnosticHandler(const DiagnosticInfo &DI) { - DiagnosticPrinterRawOStream DP(errs()); -@@ -667,6 +667,7 @@ std::unique_ptr ThinLTOCodeGenerator::codegen(Module &TheModule) { - - // Main entry point for the ThinLTO processing - void ThinLTOCodeGenerator::run() { -+#if 0 - if (CodeGenOnly) { - // Perform only parallel codegen and return. - ThreadPool Pool; -@@ -832,4 +833,5 @@ void ThinLTOCodeGenerator::run() { - // If statistics were requested, print them out now. - if (llvm::AreStatisticsEnabled()) - llvm::PrintStatistics(); -+#endif - } -diff --git a/lib/Support/ThreadPool.cpp b/lib/Support/ThreadPool.cpp -index db03a4d..71f4933 100644 ---- a/lib/Support/ThreadPool.cpp -+++ b/lib/Support/ThreadPool.cpp -@@ -11,6 +11,8 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 -+ - #include "llvm/Support/ThreadPool.h" - - #include "llvm/Config/llvm-config.h" -@@ -18,7 +20,7 @@ - - using namespace llvm; - --#if LLVM_ENABLE_THREADS -+#if LLVM_ENABLE_THREADS && 0 - - // Default to std::thread::hardware_concurrency - ThreadPool::ThreadPool() : ThreadPool(std::thread::hardware_concurrency()) {} -@@ -156,3 +158,5 @@ ThreadPool::~ThreadPool() { - } - - #endif -+ -+#endif -diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt -index e5773bd..40122bd 100644 ---- a/test/CMakeLists.txt -+++ b/test/CMakeLists.txt -@@ -27,7 +27,6 @@ set(LLVM_TEST_DEPENDS - count - llc - lli -- lli-child-target - llvm-ar - llvm-as - llvm-bcanalyzer -diff --git a/tools/lli/CMakeLists.txt b/tools/lli/CMakeLists.txt -index 2bdd066..8a4c9d0 100644 ---- a/tools/lli/CMakeLists.txt -+++ b/tools/lli/CMakeLists.txt -@@ -1,7 +1,3 @@ --if ( LLVM_INCLUDE_UTILS ) -- add_subdirectory(ChildTarget) --endif() -- - set(LLVM_LINK_COMPONENTS - CodeGen - Core -diff --git a/tools/lli/ChildTarget/CMakeLists.txt b/tools/lli/ChildTarget/CMakeLists.txt -deleted file mode 100644 -index e4fe0c7..0000000 ---- a/tools/lli/ChildTarget/CMakeLists.txt -+++ /dev/null -@@ -1,10 +0,0 @@ --set(LLVM_LINK_COMPONENTS -- OrcJIT -- RuntimeDyld -- Support -- ) -- --add_llvm_utility(lli-child-target -- ChildTarget.cpp --) -- -diff --git a/tools/lli/ChildTarget/ChildTarget.cpp b/tools/lli/ChildTarget/ChildTarget.cpp -deleted file mode 100644 -index f6d2413..0000000 ---- a/tools/lli/ChildTarget/ChildTarget.cpp -+++ /dev/null -@@ -1,78 +0,0 @@ --#include "llvm/ExecutionEngine/Orc/OrcABISupport.h" --#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h" --#include "llvm/Support/Debug.h" --#include "llvm/Support/DynamicLibrary.h" --#include "llvm/Support/Process.h" --#include -- --#include "../RemoteJITUtils.h" -- --using namespace llvm; --using namespace llvm::orc; --using namespace llvm::sys; -- --#ifdef __x86_64__ --typedef OrcX86_64_SysV HostOrcArch; --#else --typedef OrcGenericABI HostOrcArch; --#endif -- --ExitOnError ExitOnErr; -- --int main(int argc, char *argv[]) { -- -- if (argc != 3) { -- errs() << "Usage: " << argv[0] << " \n"; -- return 1; -- } -- -- ExitOnErr.setBanner(std::string(argv[0]) + ":"); -- -- int InFD; -- int OutFD; -- { -- std::istringstream InFDStream(argv[1]), OutFDStream(argv[2]); -- InFDStream >> InFD; -- OutFDStream >> OutFD; -- } -- -- if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) { -- errs() << "Error loading program symbols.\n"; -- return 1; -- } -- -- auto SymbolLookup = [](const std::string &Name) { -- return RTDyldMemoryManager::getSymbolAddressInProcess(Name); -- }; -- -- auto RegisterEHFrames = [](uint8_t *Addr, uint32_t Size) { -- RTDyldMemoryManager::registerEHFramesInProcess(Addr, Size); -- }; -- -- auto DeregisterEHFrames = [](uint8_t *Addr, uint32_t Size) { -- RTDyldMemoryManager::deregisterEHFramesInProcess(Addr, Size); -- }; -- -- FDRPCChannel Channel(InFD, OutFD); -- typedef remote::OrcRemoteTargetServer JITServer; -- JITServer Server(Channel, SymbolLookup, RegisterEHFrames, DeregisterEHFrames); -- -- while (1) { -- uint32_t RawId; -- ExitOnErr(Server.startReceivingFunction(Channel, RawId)); -- auto Id = static_cast(RawId); -- switch (Id) { -- case JITServer::TerminateSessionId: -- ExitOnErr(Server.handleTerminateSession()); -- return 0; -- default: -- ExitOnErr(Server.handleKnownFunction(Id)); -- break; -- } -- } -- -- close(InFD); -- close(OutFD); -- -- return 0; --} -diff --git a/tools/lli/ChildTarget/LLVMBuild.txt b/tools/lli/ChildTarget/LLVMBuild.txt -deleted file mode 100644 -index daf6df1..0000000 ---- a/tools/lli/ChildTarget/LLVMBuild.txt -+++ /dev/null -@@ -1,21 +0,0 @@ --;===- ./tools/lli/ChildTarget/LLVMBuild.txt --------------------*- Conf -*--===; --; --; The LLVM Compiler Infrastructure --; --; This file is distributed under the University of Illinois Open Source --; License. See LICENSE.TXT for details. --; --;===------------------------------------------------------------------------===; --; --; This is an LLVMBuild description file for the components in this subdirectory. --; --; For more information on the LLVMBuild system, please see: --; --; http://llvm.org/docs/LLVMBuild.html --; --;===------------------------------------------------------------------------===; -- --[component_0] --type = Tool --name = lli-child-target --parent = lli -diff --git a/tools/lli/LLVMBuild.txt b/tools/lli/LLVMBuild.txt -index 9d889bf..4738504 100644 ---- a/tools/lli/LLVMBuild.txt -+++ b/tools/lli/LLVMBuild.txt -@@ -15,9 +15,6 @@ - ; - ;===------------------------------------------------------------------------===; - --[common] --subdirectories = ChildTarget -- - [component_0] - type = Tool - name = lli -diff --git a/tools/lli/OrcLazyJIT.cpp b/tools/lli/OrcLazyJIT.cpp -index b13e769..8b13789 100644 ---- a/tools/lli/OrcLazyJIT.cpp -+++ b/tools/lli/OrcLazyJIT.cpp -@@ -1,158 +1 @@ --//===------ OrcLazyJIT.cpp - Basic Orc-based JIT for lazy execution -------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// -- --#include "OrcLazyJIT.h" --#include "llvm/ExecutionEngine/Orc/OrcABISupport.h" --#include "llvm/Support/Debug.h" --#include "llvm/Support/DynamicLibrary.h" --#include --#include -- --using namespace llvm; -- --namespace { -- -- enum class DumpKind { NoDump, DumpFuncsToStdOut, DumpModsToStdErr, -- DumpModsToDisk }; -- -- cl::opt OrcDumpKind("orc-lazy-debug", -- cl::desc("Debug dumping for the orc-lazy JIT."), -- cl::init(DumpKind::NoDump), -- cl::values( -- clEnumValN(DumpKind::NoDump, "no-dump", -- "Don't dump anything."), -- clEnumValN(DumpKind::DumpFuncsToStdOut, -- "funcs-to-stdout", -- "Dump function names to stdout."), -- clEnumValN(DumpKind::DumpModsToStdErr, -- "mods-to-stderr", -- "Dump modules to stderr."), -- clEnumValN(DumpKind::DumpModsToDisk, -- "mods-to-disk", -- "Dump modules to the current " -- "working directory. (WARNING: " -- "will overwrite existing files)."), -- clEnumValEnd), -- cl::Hidden); -- -- cl::opt OrcInlineStubs("orc-lazy-inline-stubs", -- cl::desc("Try to inline stubs"), -- cl::init(true), cl::Hidden); --} -- --OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() { -- -- switch (OrcDumpKind) { -- case DumpKind::NoDump: -- return [](std::unique_ptr M) { return M; }; -- -- case DumpKind::DumpFuncsToStdOut: -- return [](std::unique_ptr M) { -- printf("[ "); -- -- for (const auto &F : *M) { -- if (F.isDeclaration()) -- continue; -- -- if (F.hasName()) { -- std::string Name(F.getName()); -- printf("%s ", Name.c_str()); -- } else -- printf(" "); -- } -- -- printf("]\n"); -- return M; -- }; -- -- case DumpKind::DumpModsToStdErr: -- return [](std::unique_ptr M) { -- dbgs() << "----- Module Start -----\n" << *M -- << "----- Module End -----\n"; -- -- return M; -- }; -- -- case DumpKind::DumpModsToDisk: -- return [](std::unique_ptr M) { -- std::error_code EC; -- raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC, -- sys::fs::F_Text); -- if (EC) { -- errs() << "Couldn't open " << M->getModuleIdentifier() -- << " for dumping.\nError:" << EC.message() << "\n"; -- exit(1); -- } -- Out << *M; -- return M; -- }; -- } -- llvm_unreachable("Unknown DumpKind"); --} -- --// Defined in lli.cpp. --CodeGenOpt::Level getOptLevel(); -- -- --template --static PtrTy fromTargetAddress(orc::TargetAddress Addr) { -- return reinterpret_cast(static_cast(Addr)); --} -- --int llvm::runOrcLazyJIT(std::unique_ptr M, int ArgC, char* ArgV[]) { -- // Add the program's symbols into the JIT's search space. -- if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) { -- errs() << "Error loading program symbols.\n"; -- return 1; -- } -- -- // Grab a target machine and try to build a factory function for the -- // target-specific Orc callback manager. -- EngineBuilder EB; -- EB.setOptLevel(getOptLevel()); -- auto TM = std::unique_ptr(EB.selectTarget()); -- Triple T(TM->getTargetTriple()); -- auto CompileCallbackMgr = orc::createLocalCompileCallbackManager(T, 0); -- -- // If we couldn't build the factory function then there must not be a callback -- // manager for this target. Bail out. -- if (!CompileCallbackMgr) { -- errs() << "No callback manager available for target '" -- << TM->getTargetTriple().str() << "'.\n"; -- return 1; -- } -- -- auto IndirectStubsMgrBuilder = orc::createLocalIndirectStubsManagerBuilder(T); -- -- // If we couldn't build a stubs-manager-builder for this target then bail out. -- if (!IndirectStubsMgrBuilder) { -- errs() << "No indirect stubs manager available for target '" -- << TM->getTargetTriple().str() << "'.\n"; -- return 1; -- } -- -- // Everything looks good. Build the JIT. -- OrcLazyJIT J(std::move(TM), std::move(CompileCallbackMgr), -- std::move(IndirectStubsMgrBuilder), -- OrcInlineStubs); -- -- // Add the module, look up main and run it. -- auto MainHandle = J.addModule(std::move(M)); -- auto MainSym = J.findSymbolIn(MainHandle, "main"); -- -- if (!MainSym) { -- errs() << "Could not find main function.\n"; -- return 1; -- } -- -- typedef int (*MainFnPtr)(int, char*[]); -- auto Main = fromTargetAddress(MainSym.getAddress()); -- return Main(ArgC, ArgV); --} - -diff --git a/tools/lli/OrcLazyJIT.h b/tools/lli/OrcLazyJIT.h -deleted file mode 100644 -index 733bdd8..0000000 ---- a/tools/lli/OrcLazyJIT.h -+++ /dev/null -@@ -1,163 +0,0 @@ --//===--- OrcLazyJIT.h - Basic Orc-based JIT for lazy execution --*- C++ -*-===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// Simple Orc-based JIT. Uses the compile-on-demand layer to break up and --// lazily compile modules. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_TOOLS_LLI_ORCLAZYJIT_H --#define LLVM_TOOLS_LLI_ORCLAZYJIT_H -- --#include "llvm/ADT/Triple.h" --#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" --#include "llvm/ExecutionEngine/Orc/CompileUtils.h" --#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" --#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" --#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" --#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" --#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" -- --namespace llvm { -- --class OrcLazyJIT { --public: -- -- typedef orc::JITCompileCallbackManager CompileCallbackMgr; -- typedef orc::ObjectLinkingLayer<> ObjLayerT; -- typedef orc::IRCompileLayer CompileLayerT; -- typedef std::function(std::unique_ptr)> -- TransformFtor; -- typedef orc::IRTransformLayer IRDumpLayerT; -- typedef orc::CompileOnDemandLayer CODLayerT; -- typedef CODLayerT::IndirectStubsManagerBuilderT -- IndirectStubsManagerBuilder; -- typedef CODLayerT::ModuleSetHandleT ModuleHandleT; -- -- OrcLazyJIT(std::unique_ptr TM, -- std::unique_ptr CCMgr, -- IndirectStubsManagerBuilder IndirectStubsMgrBuilder, -- bool InlineStubs) -- : TM(std::move(TM)), DL(this->TM->createDataLayout()), -- CCMgr(std::move(CCMgr)), -- ObjectLayer(), -- CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)), -- IRDumpLayer(CompileLayer, createDebugDumper()), -- CODLayer(IRDumpLayer, extractSingleFunction, *this->CCMgr, -- std::move(IndirectStubsMgrBuilder), InlineStubs), -- CXXRuntimeOverrides( -- [this](const std::string &S) { return mangle(S); }) {} -- -- ~OrcLazyJIT() { -- // Run any destructors registered with __cxa_atexit. -- CXXRuntimeOverrides.runDestructors(); -- // Run any IR destructors. -- for (auto &DtorRunner : IRStaticDestructorRunners) -- DtorRunner.runViaLayer(CODLayer); -- } -- -- ModuleHandleT addModule(std::unique_ptr M) { -- // Attach a data-layout if one isn't already present. -- if (M->getDataLayout().isDefault()) -- M->setDataLayout(DL); -- -- // Record the static constructors and destructors. We have to do this before -- // we hand over ownership of the module to the JIT. -- std::vector CtorNames, DtorNames; -- for (auto Ctor : orc::getConstructors(*M)) -- CtorNames.push_back(mangle(Ctor.Func->getName())); -- for (auto Dtor : orc::getDestructors(*M)) -- DtorNames.push_back(mangle(Dtor.Func->getName())); -- -- // Symbol resolution order: -- // 1) Search the JIT symbols. -- // 2) Check for C++ runtime overrides. -- // 3) Search the host process (LLI)'s symbol table. -- auto Resolver = -- orc::createLambdaResolver( -- [this](const std::string &Name) { -- if (auto Sym = CODLayer.findSymbol(Name, true)) -- return Sym.toRuntimeDyldSymbol(); -- if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name)) -- return Sym; -- -- if (auto Addr = -- RTDyldMemoryManager::getSymbolAddressInProcess(Name)) -- return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported); -- -- return RuntimeDyld::SymbolInfo(nullptr); -- }, -- [](const std::string &Name) { -- return RuntimeDyld::SymbolInfo(nullptr); -- } -- ); -- -- // Add the module to the JIT. -- std::vector> S; -- S.push_back(std::move(M)); -- auto H = CODLayer.addModuleSet(std::move(S), -- llvm::make_unique(), -- std::move(Resolver)); -- -- // Run the static constructors, and save the static destructor runner for -- // execution when the JIT is torn down. -- orc::CtorDtorRunner CtorRunner(std::move(CtorNames), H); -- CtorRunner.runViaLayer(CODLayer); -- -- IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H); -- -- return H; -- } -- -- orc::JITSymbol findSymbol(const std::string &Name) { -- return CODLayer.findSymbol(mangle(Name), true); -- } -- -- orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) { -- return CODLayer.findSymbolIn(H, mangle(Name), true); -- } -- --private: -- -- std::string mangle(const std::string &Name) { -- std::string MangledName; -- { -- raw_string_ostream MangledNameStream(MangledName); -- Mangler::getNameWithPrefix(MangledNameStream, Name, DL); -- } -- return MangledName; -- } -- -- static std::set extractSingleFunction(Function &F) { -- std::set Partition; -- Partition.insert(&F); -- return Partition; -- } -- -- static TransformFtor createDebugDumper(); -- -- std::unique_ptr TM; -- DataLayout DL; -- SectionMemoryManager CCMgrMemMgr; -- -- std::unique_ptr CCMgr; -- ObjLayerT ObjectLayer; -- CompileLayerT CompileLayer; -- IRDumpLayerT IRDumpLayer; -- CODLayerT CODLayer; -- -- orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides; -- std::vector> IRStaticDestructorRunners; --}; -- --int runOrcLazyJIT(std::unique_ptr M, int ArgC, char* ArgV[]); -- --} // end namespace llvm -- --#endif -diff --git a/tools/lli/RemoteJITUtils.h b/tools/lli/RemoteJITUtils.h -deleted file mode 100644 -index 15068d2..0000000 ---- a/tools/lli/RemoteJITUtils.h -+++ /dev/null -@@ -1,152 +0,0 @@ --//===-- RemoteJITUtils.h - Utilities for remote-JITing with LLI -*- C++ -*-===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// Utilities for remote-JITing with LLI. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_TOOLS_LLI_REMOTEJITUTILS_H --#define LLVM_TOOLS_LLI_REMOTEJITUTILS_H -- --#include "llvm/ExecutionEngine/Orc/RPCChannel.h" --#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" --#include -- --#if !defined(_MSC_VER) && !defined(__MINGW32__) --#include --#else --#include --#endif -- --/// RPC channel that reads from and writes from file descriptors. --class FDRPCChannel final : public llvm::orc::remote::RPCChannel { --public: -- FDRPCChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {} -- -- llvm::Error readBytes(char *Dst, unsigned Size) override { -- assert(Dst && "Attempt to read into null."); -- ssize_t Completed = 0; -- while (Completed < static_cast(Size)) { -- ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed); -- if (Read <= 0) { -- auto ErrNo = errno; -- if (ErrNo == EAGAIN || ErrNo == EINTR) -- continue; -- else -- return llvm::errorCodeToError( -- std::error_code(errno, std::generic_category())); -- } -- Completed += Read; -- } -- return llvm::Error::success(); -- } -- -- llvm::Error appendBytes(const char *Src, unsigned Size) override { -- assert(Src && "Attempt to append from null."); -- ssize_t Completed = 0; -- while (Completed < static_cast(Size)) { -- ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed); -- if (Written < 0) { -- auto ErrNo = errno; -- if (ErrNo == EAGAIN || ErrNo == EINTR) -- continue; -- else -- return llvm::errorCodeToError( -- std::error_code(errno, std::generic_category())); -- } -- Completed += Written; -- } -- return llvm::Error::success(); -- } -- -- llvm::Error send() override { return llvm::Error::success(); } -- --private: -- int InFD, OutFD; --}; -- --// launch the remote process (see lli.cpp) and return a channel to it. --std::unique_ptr launchRemote(); -- --namespace llvm { -- --// ForwardingMM - Adapter to connect MCJIT to Orc's Remote memory manager. --class ForwardingMemoryManager : public llvm::RTDyldMemoryManager { --public: -- void setMemMgr(std::unique_ptr MemMgr) { -- this->MemMgr = std::move(MemMgr); -- } -- -- void setResolver(std::unique_ptr Resolver) { -- this->Resolver = std::move(Resolver); -- } -- -- uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, -- unsigned SectionID, -- StringRef SectionName) override { -- return MemMgr->allocateCodeSection(Size, Alignment, SectionID, SectionName); -- } -- -- uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, -- unsigned SectionID, StringRef SectionName, -- bool IsReadOnly) override { -- return MemMgr->allocateDataSection(Size, Alignment, SectionID, SectionName, -- IsReadOnly); -- } -- -- void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, -- uintptr_t RODataSize, uint32_t RODataAlign, -- uintptr_t RWDataSize, -- uint32_t RWDataAlign) override { -- MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign, -- RWDataSize, RWDataAlign); -- } -- -- bool needsToReserveAllocationSpace() override { -- return MemMgr->needsToReserveAllocationSpace(); -- } -- -- void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, -- size_t Size) override { -- MemMgr->registerEHFrames(Addr, LoadAddr, Size); -- } -- -- void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, -- size_t Size) override { -- MemMgr->deregisterEHFrames(Addr, LoadAddr, Size); -- } -- -- bool finalizeMemory(std::string *ErrMsg = nullptr) override { -- return MemMgr->finalizeMemory(ErrMsg); -- } -- -- void notifyObjectLoaded(RuntimeDyld &RTDyld, -- const object::ObjectFile &Obj) override { -- MemMgr->notifyObjectLoaded(RTDyld, Obj); -- } -- -- // Don't hide the sibling notifyObjectLoaded from RTDyldMemoryManager. -- using RTDyldMemoryManager::notifyObjectLoaded; -- -- RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override { -- return Resolver->findSymbol(Name); -- } -- -- RuntimeDyld::SymbolInfo -- findSymbolInLogicalDylib(const std::string &Name) override { -- return Resolver->findSymbolInLogicalDylib(Name); -- } -- --private: -- std::unique_ptr MemMgr; -- std::unique_ptr Resolver; --}; --} -- --#endif -diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp -index 92de5da..7203af2 100644 ---- a/tools/lli/lli.cpp -+++ b/tools/lli/lli.cpp -@@ -13,6 +13,8 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 -+ - #include "OrcLazyJIT.h" - #include "RemoteJITUtils.h" - #include "llvm/IR/LLVMContext.h" -@@ -751,3 +753,8 @@ std::unique_ptr launchRemote() { - return llvm::make_unique(PipeFD[1][0], PipeFD[0][1]); - #endif - } -+#endif -+ -+int main(int argc, char **argv, char * const *envp) { -+ return 0; -+} -diff --git a/tools/llvm-cov/CodeCoverage.cpp b/tools/llvm-cov/CodeCoverage.cpp -index 0a4d1a6..8b13789 100644 ---- a/tools/llvm-cov/CodeCoverage.cpp -+++ b/tools/llvm-cov/CodeCoverage.cpp -@@ -1,727 +1 @@ --//===- CodeCoverage.cpp - Coverage tool based on profiling instrumentation-===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// The 'CodeCoverageTool' class implements a command line tool to analyze and --// report coverage information using the profiling instrumentation and code --// coverage mapping. --// --//===----------------------------------------------------------------------===// - --#include "CoverageFilters.h" --#include "CoverageReport.h" --#include "CoverageViewOptions.h" --#include "RenderingSupport.h" --#include "SourceCoverageView.h" --#include "llvm/ADT/SmallString.h" --#include "llvm/ADT/StringRef.h" --#include "llvm/ADT/Triple.h" --#include "llvm/ProfileData/Coverage/CoverageMapping.h" --#include "llvm/ProfileData/InstrProfReader.h" --#include "llvm/Support/CommandLine.h" --#include "llvm/Support/FileSystem.h" --#include "llvm/Support/Format.h" --#include "llvm/Support/MemoryBuffer.h" --#include "llvm/Support/Path.h" --#include "llvm/Support/Process.h" --#include "llvm/Support/Program.h" --#include "llvm/Support/ThreadPool.h" --#include "llvm/Support/ToolOutputFile.h" --#include --#include -- --using namespace llvm; --using namespace coverage; -- --namespace { --/// \brief The implementation of the coverage tool. --class CodeCoverageTool { --public: -- enum Command { -- /// \brief The show command. -- Show, -- /// \brief The report command. -- Report -- }; -- -- /// \brief Print the error message to the error output stream. -- void error(const Twine &Message, StringRef Whence = ""); -- -- /// \brief Record (but do not print) an error message in a thread-safe way. -- void deferError(const Twine &Message, StringRef Whence = ""); -- -- /// \brief Record (but do not print) a warning message in a thread-safe way. -- void deferWarning(const Twine &Message, StringRef Whence = ""); -- -- /// \brief Print (and then clear) all deferred error and warning messages. -- void consumeDeferredMessages(); -- -- /// \brief Append a reference to a private copy of \p Path into SourceFiles. -- void addCollectedPath(const std::string &Path); -- -- /// \brief Return a memory buffer for the given source file. -- ErrorOr getSourceFile(StringRef SourceFile); -- -- /// \brief Create source views for the expansions of the view. -- void attachExpansionSubViews(SourceCoverageView &View, -- ArrayRef Expansions, -- const CoverageMapping &Coverage); -- -- /// \brief Create the source view of a particular function. -- std::unique_ptr -- createFunctionView(const FunctionRecord &Function, -- const CoverageMapping &Coverage); -- -- /// \brief Create the main source view of a particular source file. -- std::unique_ptr -- createSourceFileView(StringRef SourceFile, const CoverageMapping &Coverage); -- -- /// \brief Load the coverage mapping data. Return nullptr if an error occured. -- std::unique_ptr load(); -- -- /// \brief If a demangler is available, demangle all symbol names. -- void demangleSymbols(const CoverageMapping &Coverage); -- -- /// \brief Demangle \p Sym if possible. Otherwise, just return \p Sym. -- StringRef getSymbolForHumans(StringRef Sym) const; -- -- int run(Command Cmd, int argc, const char **argv); -- -- typedef llvm::function_ref CommandLineParserType; -- -- int show(int argc, const char **argv, -- CommandLineParserType commandLineParser); -- -- int report(int argc, const char **argv, -- CommandLineParserType commandLineParser); -- -- std::string ObjectFilename; -- CoverageViewOptions ViewOpts; -- std::string PGOFilename; -- CoverageFiltersMatchAll Filters; -- std::vector SourceFiles; -- bool CompareFilenamesOnly; -- StringMap RemappedFilenames; -- std::string CoverageArch; -- --private: -- /// A cache for demangled symbol names. -- StringMap DemangledNames; -- -- /// File paths (absolute, or otherwise) to input source files. -- std::vector CollectedPaths; -- -- /// Errors and warnings which have not been printed. -- std::mutex DeferredMessagesLock; -- std::vector DeferredMessages; -- -- /// A container for input source file buffers. -- std::mutex LoadedSourceFilesLock; -- std::vector>> -- LoadedSourceFiles; --}; --} -- --static std::string getErrorString(const Twine &Message, StringRef Whence, -- bool Warning) { -- std::string Str = (Warning ? "warning" : "error"); -- Str += ": "; -- if (!Whence.empty()) -- Str += Whence.str() + ": "; -- Str += Message.str() + "\n"; -- return Str; --} -- --void CodeCoverageTool::error(const Twine &Message, StringRef Whence) { -- errs() << getErrorString(Message, Whence, false); --} -- --void CodeCoverageTool::deferError(const Twine &Message, StringRef Whence) { -- std::unique_lock Guard{DeferredMessagesLock}; -- DeferredMessages.emplace_back(getErrorString(Message, Whence, false)); --} -- --void CodeCoverageTool::deferWarning(const Twine &Message, StringRef Whence) { -- std::unique_lock Guard{DeferredMessagesLock}; -- DeferredMessages.emplace_back(getErrorString(Message, Whence, true)); --} -- --void CodeCoverageTool::consumeDeferredMessages() { -- std::unique_lock Guard{DeferredMessagesLock}; -- for (const std::string &Message : DeferredMessages) -- ViewOpts.colored_ostream(errs(), raw_ostream::RED) << Message; -- DeferredMessages.clear(); --} -- --void CodeCoverageTool::addCollectedPath(const std::string &Path) { -- CollectedPaths.push_back(Path); -- SourceFiles.emplace_back(CollectedPaths.back()); --} -- --ErrorOr --CodeCoverageTool::getSourceFile(StringRef SourceFile) { -- // If we've remapped filenames, look up the real location for this file. -- std::unique_lock Guard{LoadedSourceFilesLock}; -- if (!RemappedFilenames.empty()) { -- auto Loc = RemappedFilenames.find(SourceFile); -- if (Loc != RemappedFilenames.end()) -- SourceFile = Loc->second; -- } -- for (const auto &Files : LoadedSourceFiles) -- if (sys::fs::equivalent(SourceFile, Files.first)) -- return *Files.second; -- auto Buffer = MemoryBuffer::getFile(SourceFile); -- if (auto EC = Buffer.getError()) { -- deferError(EC.message(), SourceFile); -- return EC; -- } -- LoadedSourceFiles.emplace_back(SourceFile, std::move(Buffer.get())); -- return *LoadedSourceFiles.back().second; --} -- --void CodeCoverageTool::attachExpansionSubViews( -- SourceCoverageView &View, ArrayRef Expansions, -- const CoverageMapping &Coverage) { -- if (!ViewOpts.ShowExpandedRegions) -- return; -- for (const auto &Expansion : Expansions) { -- auto ExpansionCoverage = Coverage.getCoverageForExpansion(Expansion); -- if (ExpansionCoverage.empty()) -- continue; -- auto SourceBuffer = getSourceFile(ExpansionCoverage.getFilename()); -- if (!SourceBuffer) -- continue; -- -- auto SubViewExpansions = ExpansionCoverage.getExpansions(); -- auto SubView = -- SourceCoverageView::create(Expansion.Function.Name, SourceBuffer.get(), -- ViewOpts, std::move(ExpansionCoverage)); -- attachExpansionSubViews(*SubView, SubViewExpansions, Coverage); -- View.addExpansion(Expansion.Region, std::move(SubView)); -- } --} -- --std::unique_ptr --CodeCoverageTool::createFunctionView(const FunctionRecord &Function, -- const CoverageMapping &Coverage) { -- auto FunctionCoverage = Coverage.getCoverageForFunction(Function); -- if (FunctionCoverage.empty()) -- return nullptr; -- auto SourceBuffer = getSourceFile(FunctionCoverage.getFilename()); -- if (!SourceBuffer) -- return nullptr; -- -- auto Expansions = FunctionCoverage.getExpansions(); -- auto View = SourceCoverageView::create(getSymbolForHumans(Function.Name), -- SourceBuffer.get(), ViewOpts, -- std::move(FunctionCoverage)); -- attachExpansionSubViews(*View, Expansions, Coverage); -- -- return View; --} -- --std::unique_ptr --CodeCoverageTool::createSourceFileView(StringRef SourceFile, -- const CoverageMapping &Coverage) { -- auto SourceBuffer = getSourceFile(SourceFile); -- if (!SourceBuffer) -- return nullptr; -- auto FileCoverage = Coverage.getCoverageForFile(SourceFile); -- if (FileCoverage.empty()) -- return nullptr; -- -- auto Expansions = FileCoverage.getExpansions(); -- auto View = SourceCoverageView::create(SourceFile, SourceBuffer.get(), -- ViewOpts, std::move(FileCoverage)); -- attachExpansionSubViews(*View, Expansions, Coverage); -- -- for (const auto *Function : Coverage.getInstantiations(SourceFile)) { -- auto SubViewCoverage = Coverage.getCoverageForFunction(*Function); -- auto SubViewExpansions = SubViewCoverage.getExpansions(); -- auto SubView = SourceCoverageView::create( -- getSymbolForHumans(Function->Name), SourceBuffer.get(), ViewOpts, -- std::move(SubViewCoverage)); -- attachExpansionSubViews(*SubView, SubViewExpansions, Coverage); -- -- if (SubView) { -- unsigned FileID = Function->CountedRegions.front().FileID; -- unsigned Line = 0; -- for (const auto &CR : Function->CountedRegions) -- if (CR.FileID == FileID) -- Line = std::max(CR.LineEnd, Line); -- View->addInstantiation(Function->Name, Line, std::move(SubView)); -- } -- } -- return View; --} -- --static bool modifiedTimeGT(StringRef LHS, StringRef RHS) { -- sys::fs::file_status Status; -- if (sys::fs::status(LHS, Status)) -- return false; -- auto LHSTime = Status.getLastModificationTime(); -- if (sys::fs::status(RHS, Status)) -- return false; -- auto RHSTime = Status.getLastModificationTime(); -- return LHSTime > RHSTime; --} -- --std::unique_ptr CodeCoverageTool::load() { -- if (modifiedTimeGT(ObjectFilename, PGOFilename)) -- errs() << "warning: profile data may be out of date - object is newer\n"; -- auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename, -- CoverageArch); -- if (Error E = CoverageOrErr.takeError()) { -- colored_ostream(errs(), raw_ostream::RED) -- << "error: Failed to load coverage: " << toString(std::move(E)) << "\n"; -- return nullptr; -- } -- auto Coverage = std::move(CoverageOrErr.get()); -- unsigned Mismatched = Coverage->getMismatchedCount(); -- if (Mismatched) { -- colored_ostream(errs(), raw_ostream::RED) -- << "warning: " << Mismatched << " functions have mismatched data. "; -- errs() << "\n"; -- } -- -- if (CompareFilenamesOnly) { -- auto CoveredFiles = Coverage.get()->getUniqueSourceFiles(); -- for (auto &SF : SourceFiles) { -- StringRef SFBase = sys::path::filename(SF); -- for (const auto &CF : CoveredFiles) -- if (SFBase == sys::path::filename(CF)) { -- RemappedFilenames[CF] = SF; -- SF = CF; -- break; -- } -- } -- } -- -- demangleSymbols(*Coverage); -- -- return Coverage; --} -- --void CodeCoverageTool::demangleSymbols(const CoverageMapping &Coverage) { -- if (!ViewOpts.hasDemangler()) -- return; -- -- // Pass function names to the demangler in a temporary file. -- int InputFD; -- SmallString<256> InputPath; -- std::error_code EC = -- sys::fs::createTemporaryFile("demangle-in", "list", InputFD, InputPath); -- if (EC) { -- error(InputPath, EC.message()); -- return; -- } -- tool_output_file InputTOF{InputPath, InputFD}; -- -- unsigned NumSymbols = 0; -- for (const auto &Function : Coverage.getCoveredFunctions()) { -- InputTOF.os() << Function.Name << '\n'; -- ++NumSymbols; -- } -- InputTOF.os().close(); -- -- // Use another temporary file to store the demangler's output. -- int OutputFD; -- SmallString<256> OutputPath; -- EC = sys::fs::createTemporaryFile("demangle-out", "list", OutputFD, -- OutputPath); -- if (EC) { -- error(OutputPath, EC.message()); -- return; -- } -- tool_output_file OutputTOF{OutputPath, OutputFD}; -- OutputTOF.os().close(); -- -- // Invoke the demangler. -- std::vector ArgsV; -- for (const std::string &Arg : ViewOpts.DemanglerOpts) -- ArgsV.push_back(Arg.c_str()); -- ArgsV.push_back(nullptr); -- StringRef InputPathRef = InputPath.str(); -- StringRef OutputPathRef = OutputPath.str(); -- StringRef StderrRef; -- const StringRef *Redirects[] = {&InputPathRef, &OutputPathRef, &StderrRef}; -- std::string ErrMsg; -- int RC = sys::ExecuteAndWait(ViewOpts.DemanglerOpts[0], ArgsV.data(), -- /*env=*/nullptr, Redirects, /*secondsToWait=*/0, -- /*memoryLimit=*/0, &ErrMsg); -- if (RC) { -- error(ErrMsg, ViewOpts.DemanglerOpts[0]); -- return; -- } -- -- // Parse the demangler's output. -- auto BufOrError = MemoryBuffer::getFile(OutputPath); -- if (!BufOrError) { -- error(OutputPath, BufOrError.getError().message()); -- return; -- } -- -- std::unique_ptr DemanglerBuf = std::move(*BufOrError); -- -- SmallVector Symbols; -- StringRef DemanglerData = DemanglerBuf->getBuffer(); -- DemanglerData.split(Symbols, '\n', /*MaxSplit=*/NumSymbols, -- /*KeepEmpty=*/false); -- if (Symbols.size() != NumSymbols) { -- error("Demangler did not provide expected number of symbols"); -- return; -- } -- -- // Cache the demangled names. -- unsigned I = 0; -- for (const auto &Function : Coverage.getCoveredFunctions()) -- DemangledNames[Function.Name] = Symbols[I++]; --} -- --StringRef CodeCoverageTool::getSymbolForHumans(StringRef Sym) const { -- const auto DemangledName = DemangledNames.find(Sym); -- if (DemangledName == DemangledNames.end()) -- return Sym; -- return DemangledName->getValue(); --} -- --int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { -- cl::opt ObjectFilename( -- cl::Positional, cl::Required, cl::location(this->ObjectFilename), -- cl::desc("Covered executable or object file.")); -- -- cl::list InputSourceFiles( -- cl::Positional, cl::desc(""), cl::ZeroOrMore); -- -- cl::opt PGOFilename( -- "instr-profile", cl::Required, cl::location(this->PGOFilename), -- cl::desc( -- "File with the profile data obtained after an instrumented run")); -- -- cl::opt Arch( -- "arch", cl::desc("architecture of the coverage mapping binary")); -- -- cl::opt DebugDump("dump", cl::Optional, -- cl::desc("Show internal debug dump")); -- -- cl::opt Format( -- "format", cl::desc("Output format for line-based coverage reports"), -- cl::values(clEnumValN(CoverageViewOptions::OutputFormat::Text, "text", -- "Text output"), -- clEnumValN(CoverageViewOptions::OutputFormat::HTML, "html", -- "HTML output"), -- clEnumValEnd), -- cl::init(CoverageViewOptions::OutputFormat::Text)); -- -- cl::opt FilenameEquivalence( -- "filename-equivalence", cl::Optional, -- cl::desc("Treat source files as equivalent to paths in the coverage data " -- "when the file names match, even if the full paths do not")); -- -- cl::OptionCategory FilteringCategory("Function filtering options"); -- -- cl::list NameFilters( -- "name", cl::Optional, -- cl::desc("Show code coverage only for functions with the given name"), -- cl::ZeroOrMore, cl::cat(FilteringCategory)); -- -- cl::list NameRegexFilters( -- "name-regex", cl::Optional, -- cl::desc("Show code coverage only for functions that match the given " -- "regular expression"), -- cl::ZeroOrMore, cl::cat(FilteringCategory)); -- -- cl::opt RegionCoverageLtFilter( -- "region-coverage-lt", cl::Optional, -- cl::desc("Show code coverage only for functions with region coverage " -- "less than the given threshold"), -- cl::cat(FilteringCategory)); -- -- cl::opt RegionCoverageGtFilter( -- "region-coverage-gt", cl::Optional, -- cl::desc("Show code coverage only for functions with region coverage " -- "greater than the given threshold"), -- cl::cat(FilteringCategory)); -- -- cl::opt LineCoverageLtFilter( -- "line-coverage-lt", cl::Optional, -- cl::desc("Show code coverage only for functions with line coverage less " -- "than the given threshold"), -- cl::cat(FilteringCategory)); -- -- cl::opt LineCoverageGtFilter( -- "line-coverage-gt", cl::Optional, -- cl::desc("Show code coverage only for functions with line coverage " -- "greater than the given threshold"), -- cl::cat(FilteringCategory)); -- -- cl::opt UseColor( -- "use-color", cl::desc("Emit colored output (default=autodetect)"), -- cl::init(cl::BOU_UNSET)); -- -- cl::list DemanglerOpts( -- "Xdemangler", cl::desc("|")); -- -- auto commandLineParser = [&, this](int argc, const char **argv) -> int { -- cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); -- ViewOpts.Debug = DebugDump; -- CompareFilenamesOnly = FilenameEquivalence; -- -- ViewOpts.Format = Format; -- switch (ViewOpts.Format) { -- case CoverageViewOptions::OutputFormat::Text: -- ViewOpts.Colors = UseColor == cl::BOU_UNSET -- ? sys::Process::StandardOutHasColors() -- : UseColor == cl::BOU_TRUE; -- break; -- case CoverageViewOptions::OutputFormat::HTML: -- if (UseColor == cl::BOU_FALSE) -- error("Color output cannot be disabled when generating html."); -- ViewOpts.Colors = true; -- break; -- } -- -- // If a demangler is supplied, check if it exists and register it. -- if (DemanglerOpts.size()) { -- auto DemanglerPathOrErr = sys::findProgramByName(DemanglerOpts[0]); -- if (!DemanglerPathOrErr) { -- error("Could not find the demangler!", -- DemanglerPathOrErr.getError().message()); -- return 1; -- } -- DemanglerOpts[0] = *DemanglerPathOrErr; -- ViewOpts.DemanglerOpts.swap(DemanglerOpts); -- } -- -- // Create the function filters -- if (!NameFilters.empty() || !NameRegexFilters.empty()) { -- auto NameFilterer = new CoverageFilters; -- for (const auto &Name : NameFilters) -- NameFilterer->push_back(llvm::make_unique(Name)); -- for (const auto &Regex : NameRegexFilters) -- NameFilterer->push_back( -- llvm::make_unique(Regex)); -- Filters.push_back(std::unique_ptr(NameFilterer)); -- } -- if (RegionCoverageLtFilter.getNumOccurrences() || -- RegionCoverageGtFilter.getNumOccurrences() || -- LineCoverageLtFilter.getNumOccurrences() || -- LineCoverageGtFilter.getNumOccurrences()) { -- auto StatFilterer = new CoverageFilters; -- if (RegionCoverageLtFilter.getNumOccurrences()) -- StatFilterer->push_back(llvm::make_unique( -- RegionCoverageFilter::LessThan, RegionCoverageLtFilter)); -- if (RegionCoverageGtFilter.getNumOccurrences()) -- StatFilterer->push_back(llvm::make_unique( -- RegionCoverageFilter::GreaterThan, RegionCoverageGtFilter)); -- if (LineCoverageLtFilter.getNumOccurrences()) -- StatFilterer->push_back(llvm::make_unique( -- LineCoverageFilter::LessThan, LineCoverageLtFilter)); -- if (LineCoverageGtFilter.getNumOccurrences()) -- StatFilterer->push_back(llvm::make_unique( -- RegionCoverageFilter::GreaterThan, LineCoverageGtFilter)); -- Filters.push_back(std::unique_ptr(StatFilterer)); -- } -- -- if (!Arch.empty() && -- Triple(Arch).getArch() == llvm::Triple::ArchType::UnknownArch) { -- errs() << "error: Unknown architecture: " << Arch << "\n"; -- return 1; -- } -- CoverageArch = Arch; -- -- for (const auto &File : InputSourceFiles) { -- SmallString<128> Path(File); -- if (!CompareFilenamesOnly) -- if (std::error_code EC = sys::fs::make_absolute(Path)) { -- errs() << "error: " << File << ": " << EC.message(); -- return 1; -- } -- addCollectedPath(Path.str()); -- } -- return 0; -- }; -- -- switch (Cmd) { -- case Show: -- return show(argc, argv, commandLineParser); -- case Report: -- return report(argc, argv, commandLineParser); -- } -- return 0; --} -- --int CodeCoverageTool::show(int argc, const char **argv, -- CommandLineParserType commandLineParser) { -- -- cl::OptionCategory ViewCategory("Viewing options"); -- -- cl::opt ShowLineExecutionCounts( -- "show-line-counts", cl::Optional, -- cl::desc("Show the execution counts for each line"), cl::init(true), -- cl::cat(ViewCategory)); -- -- cl::opt ShowRegions( -- "show-regions", cl::Optional, -- cl::desc("Show the execution counts for each region"), -- cl::cat(ViewCategory)); -- -- cl::opt ShowBestLineRegionsCounts( -- "show-line-counts-or-regions", cl::Optional, -- cl::desc("Show the execution counts for each line, or the execution " -- "counts for each region on lines that have multiple regions"), -- cl::cat(ViewCategory)); -- -- cl::opt ShowExpansions("show-expansions", cl::Optional, -- cl::desc("Show expanded source regions"), -- cl::cat(ViewCategory)); -- -- cl::opt ShowInstantiations("show-instantiations", cl::Optional, -- cl::desc("Show function instantiations"), -- cl::cat(ViewCategory)); -- -- cl::opt ShowOutputDirectory( -- "output-dir", cl::init(""), -- cl::desc("Directory in which coverage information is written out")); -- cl::alias ShowOutputDirectoryA("o", cl::desc("Alias for --output-dir"), -- cl::aliasopt(ShowOutputDirectory)); -- -- auto Err = commandLineParser(argc, argv); -- if (Err) -- return Err; -- -- ViewOpts.ShowLineNumbers = true; -- ViewOpts.ShowLineStats = ShowLineExecutionCounts.getNumOccurrences() != 0 || -- !ShowRegions || ShowBestLineRegionsCounts; -- ViewOpts.ShowRegionMarkers = ShowRegions || ShowBestLineRegionsCounts; -- ViewOpts.ShowLineStatsOrRegionMarkers = ShowBestLineRegionsCounts; -- ViewOpts.ShowExpandedRegions = ShowExpansions; -- ViewOpts.ShowFunctionInstantiations = ShowInstantiations; -- ViewOpts.ShowOutputDirectory = ShowOutputDirectory; -- -- if (ViewOpts.hasOutputDirectory()) { -- if (auto E = sys::fs::create_directories(ViewOpts.ShowOutputDirectory)) { -- error("Could not create output directory!", E.message()); -- return 1; -- } -- } -- -- auto Coverage = load(); -- if (!Coverage) -- return 1; -- -- auto Printer = CoveragePrinter::create(ViewOpts); -- -- if (!Filters.empty()) { -- auto OSOrErr = Printer->createViewFile("functions", /*InToplevel=*/true); -- if (Error E = OSOrErr.takeError()) { -- error("Could not create view file!", toString(std::move(E))); -- return 1; -- } -- auto OS = std::move(OSOrErr.get()); -- -- // Show functions. -- for (const auto &Function : Coverage->getCoveredFunctions()) { -- if (!Filters.matches(Function)) -- continue; -- -- auto mainView = createFunctionView(Function, *Coverage); -- if (!mainView) { -- ViewOpts.colored_ostream(errs(), raw_ostream::RED) -- << "warning: Could not read coverage for '" << Function.Name << "'." -- << "\n"; -- continue; -- } -- -- mainView->print(*OS.get(), /*WholeFile=*/false, /*ShowSourceName=*/true); -- } -- -- Printer->closeViewFile(std::move(OS)); -- return 0; -- } -- -- // Show files -- bool ShowFilenames = SourceFiles.size() != 1; -- -- if (SourceFiles.empty()) -- // Get the source files from the function coverage mapping. -- for (StringRef Filename : Coverage->getUniqueSourceFiles()) -- SourceFiles.push_back(Filename); -- -- // Create an index out of the source files. -- if (ViewOpts.hasOutputDirectory()) { -- if (Error E = Printer->createIndexFile(SourceFiles)) { -- error("Could not create index file!", toString(std::move(E))); -- return 1; -- } -- } -- -- // In -output-dir mode, it's safe to use multiple threads to print files. -- unsigned ThreadCount = 1; -- if (ViewOpts.hasOutputDirectory()) -- ThreadCount = std::thread::hardware_concurrency(); -- ThreadPool Pool(ThreadCount); -- -- for (StringRef SourceFile : SourceFiles) { -- Pool.async([this, SourceFile, &Coverage, &Printer, ShowFilenames] { -- auto View = createSourceFileView(SourceFile, *Coverage); -- if (!View) { -- deferWarning("The file '" + SourceFile.str() + "' isn't covered."); -- return; -- } -- -- auto OSOrErr = Printer->createViewFile(SourceFile, /*InToplevel=*/false); -- if (Error E = OSOrErr.takeError()) { -- deferError("Could not create view file!", toString(std::move(E))); -- return; -- } -- auto OS = std::move(OSOrErr.get()); -- -- View->print(*OS.get(), /*Wholefile=*/true, -- /*ShowSourceName=*/ShowFilenames); -- Printer->closeViewFile(std::move(OS)); -- }); -- } -- -- Pool.wait(); -- -- consumeDeferredMessages(); -- -- return 0; --} -- --int CodeCoverageTool::report(int argc, const char **argv, -- CommandLineParserType commandLineParser) { -- auto Err = commandLineParser(argc, argv); -- if (Err) -- return Err; -- -- if (ViewOpts.Format == CoverageViewOptions::OutputFormat::HTML) -- error("HTML output for summary reports is not yet supported."); -- -- auto Coverage = load(); -- if (!Coverage) -- return 1; -- -- CoverageReport Report(ViewOpts, std::move(Coverage)); -- if (SourceFiles.empty()) -- Report.renderFileReports(llvm::outs()); -- else -- Report.renderFunctionReports(SourceFiles, llvm::outs()); -- return 0; --} -- --int showMain(int argc, const char *argv[]) { -- CodeCoverageTool Tool; -- return Tool.run(CodeCoverageTool::Show, argc, argv); --} -- --int reportMain(int argc, const char *argv[]) { -- CodeCoverageTool Tool; -- return Tool.run(CodeCoverageTool::Report, argc, argv); --} -diff --git a/tools/llvm-cov/CoverageFilters.cpp b/tools/llvm-cov/CoverageFilters.cpp -index 325dd72..8b13789 100644 ---- a/tools/llvm-cov/CoverageFilters.cpp -+++ b/tools/llvm-cov/CoverageFilters.cpp -@@ -1,59 +1 @@ --//===- CoverageFilters.cpp - Function coverage mapping filters ------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// These classes provide filtering for function coverage mapping records. --// --//===----------------------------------------------------------------------===// - --#include "CoverageFilters.h" --#include "CoverageSummaryInfo.h" --#include "llvm/Support/Regex.h" -- --using namespace llvm; -- --bool NameCoverageFilter::matches(const coverage::FunctionRecord &Function) { -- StringRef FuncName = Function.Name; -- return FuncName.find(Name) != StringRef::npos; --} -- --bool --NameRegexCoverageFilter::matches(const coverage::FunctionRecord &Function) { -- return llvm::Regex(Regex).match(Function.Name); --} -- --bool RegionCoverageFilter::matches(const coverage::FunctionRecord &Function) { -- return PassesThreshold(FunctionCoverageSummary::get(Function) -- .RegionCoverage.getPercentCovered()); --} -- --bool LineCoverageFilter::matches(const coverage::FunctionRecord &Function) { -- return PassesThreshold( -- FunctionCoverageSummary::get(Function).LineCoverage.getPercentCovered()); --} -- --void CoverageFilters::push_back(std::unique_ptr Filter) { -- Filters.push_back(std::move(Filter)); --} -- --bool CoverageFilters::matches(const coverage::FunctionRecord &Function) { -- for (const auto &Filter : Filters) { -- if (Filter->matches(Function)) -- return true; -- } -- return false; --} -- --bool --CoverageFiltersMatchAll::matches(const coverage::FunctionRecord &Function) { -- for (const auto &Filter : Filters) { -- if (!Filter->matches(Function)) -- return false; -- } -- return true; --} -diff --git a/tools/llvm-cov/CoverageFilters.h b/tools/llvm-cov/CoverageFilters.h -deleted file mode 100644 -index 756c4b4..0000000 ---- a/tools/llvm-cov/CoverageFilters.h -+++ /dev/null -@@ -1,127 +0,0 @@ --//===- CoverageFilters.h - Function coverage mapping filters --------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// These classes provide filtering for function coverage mapping records. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGEFILTERS_H --#define LLVM_COV_COVERAGEFILTERS_H -- --#include "llvm/ProfileData/Coverage/CoverageMapping.h" --#include --#include -- --namespace llvm { -- --/// \brief Matches specific functions that pass the requirement of this filter. --class CoverageFilter { --public: -- virtual ~CoverageFilter() {} -- -- /// \brief Return true if the function passes the requirements of this filter. -- virtual bool matches(const coverage::FunctionRecord &Function) { -- return true; -- } --}; -- --/// \brief Matches functions that contain a specific string in their name. --class NameCoverageFilter : public CoverageFilter { -- StringRef Name; -- --public: -- NameCoverageFilter(StringRef Name) : Name(Name) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief Matches functions whose name matches a certain regular expression. --class NameRegexCoverageFilter : public CoverageFilter { -- StringRef Regex; -- --public: -- NameRegexCoverageFilter(StringRef Regex) : Regex(Regex) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief Matches numbers that pass a certain threshold. --template class StatisticThresholdFilter { --public: -- enum Operation { LessThan, GreaterThan }; -- --protected: -- Operation Op; -- T Threshold; -- -- StatisticThresholdFilter(Operation Op, T Threshold) -- : Op(Op), Threshold(Threshold) {} -- -- /// \brief Return true if the given number is less than -- /// or greater than the certain threshold. -- bool PassesThreshold(T Value) const { -- switch (Op) { -- case LessThan: -- return Value < Threshold; -- case GreaterThan: -- return Value > Threshold; -- } -- return false; -- } --}; -- --/// \brief Matches functions whose region coverage percentage --/// is above/below a certain percentage. --class RegionCoverageFilter : public CoverageFilter, -- public StatisticThresholdFilter { --public: -- RegionCoverageFilter(Operation Op, double Threshold) -- : StatisticThresholdFilter(Op, Threshold) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief Matches functions whose line coverage percentage --/// is above/below a certain percentage. --class LineCoverageFilter : public CoverageFilter, -- public StatisticThresholdFilter { --public: -- LineCoverageFilter(Operation Op, double Threshold) -- : StatisticThresholdFilter(Op, Threshold) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief A collection of filters. --/// Matches functions that match any filters contained --/// in an instance of this class. --class CoverageFilters : public CoverageFilter { --protected: -- std::vector> Filters; -- --public: -- /// \brief Append a filter to this collection. -- void push_back(std::unique_ptr Filter); -- -- bool empty() const { return Filters.empty(); } -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief A collection of filters. --/// Matches functions that match all of the filters contained --/// in an instance of this class. --class CoverageFiltersMatchAll : public CoverageFilters { --public: -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --} // namespace llvm -- --#endif // LLVM_COV_COVERAGEFILTERS_H -diff --git a/tools/llvm-cov/CoverageReport.cpp b/tools/llvm-cov/CoverageReport.cpp -index 10e53b3..8b13789 100644 ---- a/tools/llvm-cov/CoverageReport.cpp -+++ b/tools/llvm-cov/CoverageReport.cpp -@@ -1,235 +1 @@ --//===- CoverageReport.cpp - Code coverage report -------------------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// This class implements rendering of a code coverage report. --// --//===----------------------------------------------------------------------===// - --#include "CoverageReport.h" --#include "RenderingSupport.h" --#include "llvm/Support/FileSystem.h" --#include "llvm/Support/Format.h" -- --using namespace llvm; --namespace { --/// \brief Helper struct which prints trimmed and aligned columns. --struct Column { -- enum TrimKind { NoTrim, WidthTrim, LeftTrim, RightTrim }; -- -- enum AlignmentKind { LeftAlignment, RightAlignment }; -- -- StringRef Str; -- unsigned Width; -- TrimKind Trim; -- AlignmentKind Alignment; -- -- Column(StringRef Str, unsigned Width) -- : Str(Str), Width(Width), Trim(WidthTrim), Alignment(LeftAlignment) {} -- -- Column &set(TrimKind Value) { -- Trim = Value; -- return *this; -- } -- -- Column &set(AlignmentKind Value) { -- Alignment = Value; -- return *this; -- } -- -- void render(raw_ostream &OS) const; --}; -- --raw_ostream &operator<<(raw_ostream &OS, const Column &Value) { -- Value.render(OS); -- return OS; --} --} -- --void Column::render(raw_ostream &OS) const { -- if (Str.size() <= Width) { -- if (Alignment == RightAlignment) { -- OS.indent(Width - Str.size()); -- OS << Str; -- return; -- } -- OS << Str; -- OS.indent(Width - Str.size()); -- return; -- } -- -- switch (Trim) { -- case NoTrim: -- OS << Str; -- break; -- case WidthTrim: -- OS << Str.substr(0, Width); -- break; -- case LeftTrim: -- OS << "..." << Str.substr(Str.size() - Width + 3); -- break; -- case RightTrim: -- OS << Str.substr(0, Width - 3) << "..."; -- break; -- } --} -- --static Column column(StringRef Str, unsigned Width) { -- return Column(Str, Width); --} -- --template --static Column column(StringRef Str, unsigned Width, const T &Value) { -- return Column(Str, Width).set(Value); --} -- --static size_t FileReportColumns[] = {25, 10, 8, 8, 10, 10}; --static size_t FunctionReportColumns[] = {25, 10, 8, 8, 10, 8, 8}; -- --/// \brief Adjust column widths to fit long file paths and function names. --static void adjustColumnWidths(coverage::CoverageMapping *CM) { -- for (StringRef Filename : CM->getUniqueSourceFiles()) { -- FileReportColumns[0] = std::max(FileReportColumns[0], Filename.size()); -- for (const auto &F : CM->getCoveredFunctions(Filename)) { -- FunctionReportColumns[0] = -- std::max(FunctionReportColumns[0], F.Name.size()); -- } -- } --} -- --/// \brief Prints a horizontal divider which spans across the given columns. --template --static void renderDivider(T (&Columns)[N], raw_ostream &OS) { -- unsigned Length = 0; -- for (unsigned I = 0; I < N; ++I) -- Length += Columns[I]; -- for (unsigned I = 0; I < Length; ++I) -- OS << '-'; --} -- --/// \brief Return the color which correponds to the coverage --/// percentage of a certain metric. --template --static raw_ostream::Colors determineCoveragePercentageColor(const T &Info) { -- if (Info.isFullyCovered()) -- return raw_ostream::GREEN; -- return Info.getPercentCovered() >= 80.0 ? raw_ostream::YELLOW -- : raw_ostream::RED; --} -- --void CoverageReport::render(const FileCoverageSummary &File, raw_ostream &OS) { -- OS << column(File.Name, FileReportColumns[0], Column::NoTrim) -- << format("%*u", FileReportColumns[1], -- (unsigned)File.RegionCoverage.NumRegions); -- Options.colored_ostream(OS, File.RegionCoverage.isFullyCovered() -- ? raw_ostream::GREEN -- : raw_ostream::RED) -- << format("%*u", FileReportColumns[2], (unsigned)File.RegionCoverage.NotCovered); -- Options.colored_ostream(OS, -- determineCoveragePercentageColor(File.RegionCoverage)) -- << format("%*.2f", FileReportColumns[3] - 1, -- File.RegionCoverage.getPercentCovered()) << '%'; -- OS << format("%*u", FileReportColumns[4], -- (unsigned)File.FunctionCoverage.NumFunctions); -- Options.colored_ostream( -- OS, determineCoveragePercentageColor(File.FunctionCoverage)) -- << format("%*.2f", FileReportColumns[5] - 1, -- File.FunctionCoverage.getPercentCovered()) << '%'; -- OS << "\n"; --} -- --void CoverageReport::render(const FunctionCoverageSummary &Function, -- raw_ostream &OS) { -- OS << column(Function.Name, FunctionReportColumns[0], Column::RightTrim) -- << format("%*u", FunctionReportColumns[1], -- (unsigned)Function.RegionCoverage.NumRegions); -- Options.colored_ostream(OS, Function.RegionCoverage.isFullyCovered() -- ? raw_ostream::GREEN -- : raw_ostream::RED) -- << format("%*u", FunctionReportColumns[2], -- (unsigned)Function.RegionCoverage.NotCovered); -- Options.colored_ostream( -- OS, determineCoveragePercentageColor(Function.RegionCoverage)) -- << format("%*.2f", FunctionReportColumns[3] - 1, -- Function.RegionCoverage.getPercentCovered()) << '%'; -- OS << format("%*u", FunctionReportColumns[4], -- (unsigned)Function.LineCoverage.NumLines); -- Options.colored_ostream(OS, Function.LineCoverage.isFullyCovered() -- ? raw_ostream::GREEN -- : raw_ostream::RED) -- << format("%*u", FunctionReportColumns[5], -- (unsigned)Function.LineCoverage.NotCovered); -- Options.colored_ostream( -- OS, determineCoveragePercentageColor(Function.LineCoverage)) -- << format("%*.2f", FunctionReportColumns[6] - 1, -- Function.LineCoverage.getPercentCovered()) << '%'; -- OS << "\n"; --} -- --void CoverageReport::renderFunctionReports(ArrayRef Files, -- raw_ostream &OS) { -- adjustColumnWidths(Coverage.get()); -- bool isFirst = true; -- for (StringRef Filename : Files) { -- if (isFirst) -- isFirst = false; -- else -- OS << "\n"; -- OS << "File '" << Filename << "':\n"; -- OS << column("Name", FunctionReportColumns[0]) -- << column("Regions", FunctionReportColumns[1], Column::RightAlignment) -- << column("Miss", FunctionReportColumns[2], Column::RightAlignment) -- << column("Cover", FunctionReportColumns[3], Column::RightAlignment) -- << column("Lines", FunctionReportColumns[4], Column::RightAlignment) -- << column("Miss", FunctionReportColumns[5], Column::RightAlignment) -- << column("Cover", FunctionReportColumns[6], Column::RightAlignment); -- OS << "\n"; -- renderDivider(FunctionReportColumns, OS); -- OS << "\n"; -- FunctionCoverageSummary Totals("TOTAL"); -- for (const auto &F : Coverage->getCoveredFunctions(Filename)) { -- FunctionCoverageSummary Function = FunctionCoverageSummary::get(F); -- ++Totals.ExecutionCount; -- Totals.RegionCoverage += Function.RegionCoverage; -- Totals.LineCoverage += Function.LineCoverage; -- render(Function, OS); -- } -- if (Totals.ExecutionCount) { -- renderDivider(FunctionReportColumns, OS); -- OS << "\n"; -- render(Totals, OS); -- } -- } --} -- --void CoverageReport::renderFileReports(raw_ostream &OS) { -- adjustColumnWidths(Coverage.get()); -- OS << column("Filename", FileReportColumns[0]) -- << column("Regions", FileReportColumns[1], Column::RightAlignment) -- << column("Miss", FileReportColumns[2], Column::RightAlignment) -- << column("Cover", FileReportColumns[3], Column::RightAlignment) -- << column("Functions", FileReportColumns[4], Column::RightAlignment) -- << column("Executed", FileReportColumns[5], Column::RightAlignment) -- << "\n"; -- renderDivider(FileReportColumns, OS); -- OS << "\n"; -- -- FileCoverageSummary Totals("TOTAL"); -- for (StringRef Filename : Coverage->getUniqueSourceFiles()) { -- FileCoverageSummary Summary(Filename); -- for (const auto &F : Coverage->getCoveredFunctions(Filename)) { -- FunctionCoverageSummary Function = FunctionCoverageSummary::get(F); -- Summary.addFunction(Function); -- Totals.addFunction(Function); -- } -- render(Summary, OS); -- } -- renderDivider(FileReportColumns, OS); -- OS << "\n"; -- render(Totals, OS); --} -diff --git a/tools/llvm-cov/CoverageReport.h b/tools/llvm-cov/CoverageReport.h -deleted file mode 100644 -index bb3d734..0000000 ---- a/tools/llvm-cov/CoverageReport.h -+++ /dev/null -@@ -1,41 +0,0 @@ --//===- CoverageReport.h - Code coverage report ---------------------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// This class implements rendering of a code coverage report. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGEREPORT_H --#define LLVM_COV_COVERAGEREPORT_H -- --#include "CoverageSummaryInfo.h" --#include "CoverageViewOptions.h" -- --namespace llvm { -- --/// \brief Displays the code coverage report. --class CoverageReport { -- const CoverageViewOptions &Options; -- std::unique_ptr Coverage; -- -- void render(const FileCoverageSummary &File, raw_ostream &OS); -- void render(const FunctionCoverageSummary &Function, raw_ostream &OS); -- --public: -- CoverageReport(const CoverageViewOptions &Options, -- std::unique_ptr Coverage) -- : Options(Options), Coverage(std::move(Coverage)) {} -- -- void renderFunctionReports(ArrayRef Files, raw_ostream &OS); -- -- void renderFileReports(raw_ostream &OS); --}; --} -- --#endif // LLVM_COV_COVERAGEREPORT_H -diff --git a/tools/llvm-cov/CoverageSummaryInfo.cpp b/tools/llvm-cov/CoverageSummaryInfo.cpp -index de89750..8b13789 100644 ---- a/tools/llvm-cov/CoverageSummaryInfo.cpp -+++ b/tools/llvm-cov/CoverageSummaryInfo.cpp -@@ -1,71 +1 @@ --//===- CoverageSummaryInfo.cpp - Coverage summary for function/file -------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// These structures are used to represent code coverage metrics --// for functions/files. --// --//===----------------------------------------------------------------------===// - --#include "CoverageSummaryInfo.h" -- --using namespace llvm; --using namespace coverage; -- --FunctionCoverageSummary --FunctionCoverageSummary::get(const coverage::FunctionRecord &Function) { -- // Compute the region coverage -- size_t NumCodeRegions = 0, CoveredRegions = 0; -- for (auto &CR : Function.CountedRegions) { -- if (CR.Kind != CounterMappingRegion::CodeRegion) -- continue; -- ++NumCodeRegions; -- if (CR.ExecutionCount != 0) -- ++CoveredRegions; -- } -- -- // Compute the line coverage -- size_t NumLines = 0, CoveredLines = 0; -- for (unsigned FileID = 0, E = Function.Filenames.size(); FileID < E; -- ++FileID) { -- // Find the line start and end of the function's source code -- // in that particular file -- unsigned LineStart = std::numeric_limits::max(); -- unsigned LineEnd = 0; -- for (auto &CR : Function.CountedRegions) { -- if (CR.FileID != FileID) -- continue; -- LineStart = std::min(LineStart, CR.LineStart); -- LineEnd = std::max(LineEnd, CR.LineEnd); -- } -- unsigned LineCount = LineEnd - LineStart + 1; -- -- // Get counters -- llvm::SmallVector ExecutionCounts; -- ExecutionCounts.resize(LineCount, 0); -- for (auto &CR : Function.CountedRegions) { -- if (CR.FileID != FileID) -- continue; -- // Ignore the lines that were skipped by the preprocessor. -- auto ExecutionCount = CR.ExecutionCount; -- if (CR.Kind == CounterMappingRegion::SkippedRegion) { -- LineCount -= CR.LineEnd - CR.LineStart + 1; -- ExecutionCount = 1; -- } -- for (unsigned I = CR.LineStart; I <= CR.LineEnd; ++I) -- ExecutionCounts[I - LineStart] = ExecutionCount; -- } -- CoveredLines += LineCount - std::count(ExecutionCounts.begin(), -- ExecutionCounts.end(), 0); -- NumLines += LineCount; -- } -- return FunctionCoverageSummary( -- Function.Name, Function.ExecutionCount, -- RegionCoverageInfo(CoveredRegions, NumCodeRegions), -- LineCoverageInfo(CoveredLines, 0, NumLines)); --} -diff --git a/tools/llvm-cov/CoverageSummaryInfo.h b/tools/llvm-cov/CoverageSummaryInfo.h -deleted file mode 100644 -index 822742b..0000000 ---- a/tools/llvm-cov/CoverageSummaryInfo.h -+++ /dev/null -@@ -1,162 +0,0 @@ --//===- CoverageSummaryInfo.h - Coverage summary for function/file ---------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// These structures are used to represent code coverage metrics --// for functions/files. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGESUMMARYINFO_H --#define LLVM_COV_COVERAGESUMMARYINFO_H -- --#include "llvm/ProfileData/Coverage/CoverageMapping.h" --#include "llvm/Support/raw_ostream.h" -- --namespace llvm { -- --/// \brief Provides information about region coverage for a function/file. --struct RegionCoverageInfo { -- /// \brief The number of regions that were executed at least once. -- size_t Covered; -- -- /// \brief The number of regions that weren't executed. -- size_t NotCovered; -- -- /// \brief The total number of regions in a function/file. -- size_t NumRegions; -- -- RegionCoverageInfo() : Covered(0), NotCovered(0), NumRegions(0) {} -- -- RegionCoverageInfo(size_t Covered, size_t NumRegions) -- : Covered(Covered), NotCovered(NumRegions - Covered), -- NumRegions(NumRegions) {} -- -- RegionCoverageInfo &operator+=(const RegionCoverageInfo &RHS) { -- Covered += RHS.Covered; -- NotCovered += RHS.NotCovered; -- NumRegions += RHS.NumRegions; -- return *this; -- } -- -- bool isFullyCovered() const { return Covered == NumRegions; } -- -- double getPercentCovered() const { -- if (NumRegions == 0) -- return 0.0; -- return double(Covered) / double(NumRegions) * 100.0; -- } --}; -- --/// \brief Provides information about line coverage for a function/file. --struct LineCoverageInfo { -- /// \brief The number of lines that were executed at least once. -- size_t Covered; -- -- /// \brief The number of lines that weren't executed. -- size_t NotCovered; -- -- /// \brief The number of lines that aren't code. -- size_t NonCodeLines; -- -- /// \brief The total number of lines in a function/file. -- size_t NumLines; -- -- LineCoverageInfo() -- : Covered(0), NotCovered(0), NonCodeLines(0), NumLines(0) {} -- -- LineCoverageInfo(size_t Covered, size_t NumNonCodeLines, size_t NumLines) -- : Covered(Covered), NotCovered(NumLines - NumNonCodeLines - Covered), -- NonCodeLines(NumNonCodeLines), NumLines(NumLines) {} -- -- LineCoverageInfo &operator+=(const LineCoverageInfo &RHS) { -- Covered += RHS.Covered; -- NotCovered += RHS.NotCovered; -- NonCodeLines += RHS.NonCodeLines; -- NumLines += RHS.NumLines; -- return *this; -- } -- -- bool isFullyCovered() const { return Covered == (NumLines - NonCodeLines); } -- -- double getPercentCovered() const { -- if (NumLines - NonCodeLines == 0) -- return 0.0; -- return double(Covered) / double(NumLines - NonCodeLines) * 100.0; -- } --}; -- --/// \brief Provides information about function coverage for a file. --struct FunctionCoverageInfo { -- /// \brief The number of functions that were executed. -- size_t Executed; -- -- /// \brief The total number of functions in this file. -- size_t NumFunctions; -- -- FunctionCoverageInfo() : Executed(0), NumFunctions(0) {} -- -- FunctionCoverageInfo(size_t Executed, size_t NumFunctions) -- : Executed(Executed), NumFunctions(NumFunctions) {} -- -- void addFunction(bool Covered) { -- if (Covered) -- ++Executed; -- ++NumFunctions; -- } -- -- bool isFullyCovered() const { return Executed == NumFunctions; } -- -- double getPercentCovered() const { -- if (NumFunctions == 0) -- return 0.0; -- return double(Executed) / double(NumFunctions) * 100.0; -- } --}; -- --/// \brief A summary of function's code coverage. --struct FunctionCoverageSummary { -- StringRef Name; -- uint64_t ExecutionCount; -- RegionCoverageInfo RegionCoverage; -- LineCoverageInfo LineCoverage; -- -- FunctionCoverageSummary(StringRef Name) : Name(Name), ExecutionCount(0) {} -- -- FunctionCoverageSummary(StringRef Name, uint64_t ExecutionCount, -- const RegionCoverageInfo &RegionCoverage, -- const LineCoverageInfo &LineCoverage) -- : Name(Name), ExecutionCount(ExecutionCount), -- RegionCoverage(RegionCoverage), LineCoverage(LineCoverage) { -- } -- -- /// \brief Compute the code coverage summary for the given function coverage -- /// mapping record. -- static FunctionCoverageSummary -- get(const coverage::FunctionRecord &Function); --}; -- --/// \brief A summary of file's code coverage. --struct FileCoverageSummary { -- StringRef Name; -- RegionCoverageInfo RegionCoverage; -- LineCoverageInfo LineCoverage; -- FunctionCoverageInfo FunctionCoverage; -- -- FileCoverageSummary(StringRef Name) : Name(Name) {} -- -- void addFunction(const FunctionCoverageSummary &Function) { -- RegionCoverage += Function.RegionCoverage; -- LineCoverage += Function.LineCoverage; -- FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); -- } --}; -- --} // namespace llvm -- --#endif // LLVM_COV_COVERAGESUMMARYINFO_H -diff --git a/tools/llvm-cov/CoverageViewOptions.h b/tools/llvm-cov/CoverageViewOptions.h -deleted file mode 100644 -index 350c264..0000000 ---- a/tools/llvm-cov/CoverageViewOptions.h -+++ /dev/null -@@ -1,52 +0,0 @@ --//===- CoverageViewOptions.h - Code coverage display options -------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGEVIEWOPTIONS_H --#define LLVM_COV_COVERAGEVIEWOPTIONS_H -- --#include "RenderingSupport.h" --#include -- --namespace llvm { -- --/// \brief The options for displaying the code coverage information. --struct CoverageViewOptions { -- enum class OutputFormat { -- Text, -- HTML -- }; -- -- bool Debug; -- bool Colors; -- bool ShowLineNumbers; -- bool ShowLineStats; -- bool ShowRegionMarkers; -- bool ShowLineStatsOrRegionMarkers; -- bool ShowExpandedRegions; -- bool ShowFunctionInstantiations; -- bool ShowFullFilenames; -- OutputFormat Format; -- std::string ShowOutputDirectory; -- std::vector DemanglerOpts; -- -- /// \brief Change the output's stream color if the colors are enabled. -- ColoredRawOstream colored_ostream(raw_ostream &OS, -- raw_ostream::Colors Color) const { -- return llvm::colored_ostream(OS, Color, Colors); -- } -- -- /// \brief Check if an output directory has been specified. -- bool hasOutputDirectory() const { return !ShowOutputDirectory.empty(); } -- -- /// \brief Check if a demangler has been specified. -- bool hasDemangler() const { return !DemanglerOpts.empty(); } --}; --} -- --#endif // LLVM_COV_COVERAGEVIEWOPTIONS_H -diff --git a/tools/llvm-cov/RenderingSupport.h b/tools/llvm-cov/RenderingSupport.h -deleted file mode 100644 -index aa70fbc..0000000 ---- a/tools/llvm-cov/RenderingSupport.h -+++ /dev/null -@@ -1,61 +0,0 @@ --//===- RenderingSupport.h - output stream rendering support functions ----===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_RENDERINGSUPPORT_H --#define LLVM_COV_RENDERINGSUPPORT_H -- --#include "llvm/Support/raw_ostream.h" --#include -- --namespace llvm { -- --/// \brief A helper class that resets the output stream's color if needed --/// when destroyed. --class ColoredRawOstream { -- ColoredRawOstream(const ColoredRawOstream &OS) = delete; -- --public: -- raw_ostream &OS; -- bool IsColorUsed; -- -- ColoredRawOstream(raw_ostream &OS, bool IsColorUsed) -- : OS(OS), IsColorUsed(IsColorUsed) {} -- -- ColoredRawOstream(ColoredRawOstream &&Other) -- : OS(Other.OS), IsColorUsed(Other.IsColorUsed) { -- // Reset the other IsColorUsed so that the other object won't reset the -- // color when destroyed. -- Other.IsColorUsed = false; -- } -- -- ~ColoredRawOstream() { -- if (IsColorUsed) -- OS.resetColor(); -- } --}; -- --template --inline raw_ostream &operator<<(const ColoredRawOstream &OS, T &&Value) { -- return OS.OS << std::forward(Value); --} -- --/// \brief Change the color of the output stream if the `IsColorUsed` flag --/// is true. Returns an object that resets the color when destroyed. --inline ColoredRawOstream colored_ostream(raw_ostream &OS, -- raw_ostream::Colors Color, -- bool IsColorUsed = true, -- bool Bold = false, bool BG = false) { -- if (IsColorUsed) -- OS.changeColor(Color, Bold, BG); -- return ColoredRawOstream(OS, IsColorUsed); --} -- --} // namespace llvm -- --#endif // LLVM_COV_RENDERINGSUPPORT_H -diff --git a/tools/llvm-cov/SourceCoverageView.cpp b/tools/llvm-cov/SourceCoverageView.cpp -index baf7c14..8b13789 100644 ---- a/tools/llvm-cov/SourceCoverageView.cpp -+++ b/tools/llvm-cov/SourceCoverageView.cpp -@@ -1,233 +1 @@ --//===- SourceCoverageView.cpp - Code coverage view for source code --------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This class implements rendering for code coverage of source code. --/// --//===----------------------------------------------------------------------===// - --#include "SourceCoverageView.h" --#include "SourceCoverageViewHTML.h" --#include "SourceCoverageViewText.h" --#include "llvm/ADT/SmallString.h" --#include "llvm/ADT/StringExtras.h" --#include "llvm/Support/FileSystem.h" --#include "llvm/Support/LineIterator.h" --#include "llvm/Support/Path.h" -- --using namespace llvm; -- --void CoveragePrinter::StreamDestructor::operator()(raw_ostream *OS) const { -- if (OS == &outs()) -- return; -- delete OS; --} -- --std::string CoveragePrinter::getOutputPath(StringRef Path, StringRef Extension, -- bool InToplevel, bool Relative) { -- assert(Extension.size() && "The file extension may not be empty"); -- -- SmallString<256> FullPath; -- -- if (!Relative) -- FullPath.append(Opts.ShowOutputDirectory); -- -- if (!InToplevel) -- sys::path::append(FullPath, getCoverageDir()); -- -- SmallString<256> ParentPath = sys::path::parent_path(Path); -- sys::path::remove_dots(ParentPath, /*remove_dot_dots=*/true); -- sys::path::append(FullPath, sys::path::relative_path(ParentPath)); -- -- auto PathFilename = (sys::path::filename(Path) + "." + Extension).str(); -- sys::path::append(FullPath, PathFilename); -- -- return FullPath.str(); --} -- --Expected --CoveragePrinter::createOutputStream(StringRef Path, StringRef Extension, -- bool InToplevel) { -- if (!Opts.hasOutputDirectory()) -- return OwnedStream(&outs()); -- -- std::string FullPath = getOutputPath(Path, Extension, InToplevel, false); -- -- auto ParentDir = sys::path::parent_path(FullPath); -- if (auto E = sys::fs::create_directories(ParentDir)) -- return errorCodeToError(E); -- -- std::error_code E; -- raw_ostream *RawStream = new raw_fd_ostream(FullPath, E, sys::fs::F_RW); -- auto OS = CoveragePrinter::OwnedStream(RawStream); -- if (E) -- return errorCodeToError(E); -- return std::move(OS); --} -- --std::unique_ptr --CoveragePrinter::create(const CoverageViewOptions &Opts) { -- switch (Opts.Format) { -- case CoverageViewOptions::OutputFormat::Text: -- return llvm::make_unique(Opts); -- case CoverageViewOptions::OutputFormat::HTML: -- return llvm::make_unique(Opts); -- } -- llvm_unreachable("Unknown coverage output format!"); --} -- --std::string SourceCoverageView::formatCount(uint64_t N) { -- std::string Number = utostr(N); -- int Len = Number.size(); -- if (Len <= 3) -- return Number; -- int IntLen = Len % 3 == 0 ? 3 : Len % 3; -- std::string Result(Number.data(), IntLen); -- if (IntLen != 3) { -- Result.push_back('.'); -- Result += Number.substr(IntLen, 3 - IntLen); -- } -- Result.push_back(" kMGTPEZY"[(Len - 1) / 3]); -- return Result; --} -- --bool SourceCoverageView::shouldRenderRegionMarkers( -- bool LineHasMultipleRegions) const { -- return getOptions().ShowRegionMarkers && -- (!getOptions().ShowLineStatsOrRegionMarkers || LineHasMultipleRegions); --} -- --bool SourceCoverageView::hasSubViews() const { -- return !ExpansionSubViews.empty() || !InstantiationSubViews.empty(); --} -- --std::unique_ptr --SourceCoverageView::create(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo) { -- switch (Options.Format) { -- case CoverageViewOptions::OutputFormat::Text: -- return llvm::make_unique(SourceName, File, Options, -- std::move(CoverageInfo)); -- case CoverageViewOptions::OutputFormat::HTML: -- return llvm::make_unique(SourceName, File, Options, -- std::move(CoverageInfo)); -- } -- llvm_unreachable("Unknown coverage output format!"); --} -- --void SourceCoverageView::addExpansion( -- const coverage::CounterMappingRegion &Region, -- std::unique_ptr View) { -- ExpansionSubViews.emplace_back(Region, std::move(View)); --} -- --void SourceCoverageView::addInstantiation( -- StringRef FunctionName, unsigned Line, -- std::unique_ptr View) { -- InstantiationSubViews.emplace_back(FunctionName, Line, std::move(View)); --} -- --void SourceCoverageView::print(raw_ostream &OS, bool WholeFile, -- bool ShowSourceName, unsigned ViewDepth) { -- if (ShowSourceName) -- renderSourceName(OS); -- -- renderViewHeader(OS); -- -- // We need the expansions and instantiations sorted so we can go through them -- // while we iterate lines. -- std::sort(ExpansionSubViews.begin(), ExpansionSubViews.end()); -- std::sort(InstantiationSubViews.begin(), InstantiationSubViews.end()); -- auto NextESV = ExpansionSubViews.begin(); -- auto EndESV = ExpansionSubViews.end(); -- auto NextISV = InstantiationSubViews.begin(); -- auto EndISV = InstantiationSubViews.end(); -- -- // Get the coverage information for the file. -- auto NextSegment = CoverageInfo.begin(); -- auto EndSegment = CoverageInfo.end(); -- -- unsigned FirstLine = NextSegment != EndSegment ? NextSegment->Line : 0; -- const coverage::CoverageSegment *WrappedSegment = nullptr; -- SmallVector LineSegments; -- for (line_iterator LI(File, /*SkipBlanks=*/false); !LI.is_at_eof(); ++LI) { -- // If we aren't rendering the whole file, we need to filter out the prologue -- // and epilogue. -- if (!WholeFile) { -- if (NextSegment == EndSegment) -- break; -- else if (LI.line_number() < FirstLine) -- continue; -- } -- -- // Collect the coverage information relevant to this line. -- if (LineSegments.size()) -- WrappedSegment = LineSegments.back(); -- LineSegments.clear(); -- while (NextSegment != EndSegment && NextSegment->Line == LI.line_number()) -- LineSegments.push_back(&*NextSegment++); -- -- // Calculate a count to be for the line as a whole. -- LineCoverageStats LineCount; -- if (WrappedSegment && WrappedSegment->HasCount) -- LineCount.addRegionCount(WrappedSegment->Count); -- for (const auto *S : LineSegments) -- if (S->HasCount && S->IsRegionEntry) -- LineCount.addRegionStartCount(S->Count); -- -- renderLinePrefix(OS, ViewDepth); -- if (getOptions().ShowLineStats) -- renderLineCoverageColumn(OS, LineCount); -- if (getOptions().ShowLineNumbers) -- renderLineNumberColumn(OS, LI.line_number()); -- -- // If there are expansion subviews, we want to highlight the first one. -- unsigned ExpansionColumn = 0; -- if (NextESV != EndESV && NextESV->getLine() == LI.line_number() && -- getOptions().Colors) -- ExpansionColumn = NextESV->getStartCol(); -- -- // Display the source code for the current line. -- renderLine(OS, {*LI, LI.line_number()}, WrappedSegment, LineSegments, -- ExpansionColumn, ViewDepth); -- -- // Show the region markers. -- if (shouldRenderRegionMarkers(LineCount.hasMultipleRegions())) -- renderRegionMarkers(OS, LineSegments, ViewDepth); -- -- // Show the expansions and instantiations for this line. -- bool RenderedSubView = false; -- for (; NextESV != EndESV && NextESV->getLine() == LI.line_number(); -- ++NextESV) { -- renderViewDivider(OS, ViewDepth + 1); -- -- // Re-render the current line and highlight the expansion range for -- // this subview. -- if (RenderedSubView) { -- ExpansionColumn = NextESV->getStartCol(); -- renderExpansionSite(OS, {*LI, LI.line_number()}, WrappedSegment, -- LineSegments, ExpansionColumn, ViewDepth); -- renderViewDivider(OS, ViewDepth + 1); -- } -- -- renderExpansionView(OS, *NextESV, ViewDepth + 1); -- RenderedSubView = true; -- } -- for (; NextISV != EndISV && NextISV->Line == LI.line_number(); ++NextISV) { -- renderViewDivider(OS, ViewDepth + 1); -- renderInstantiationView(OS, *NextISV, ViewDepth + 1); -- RenderedSubView = true; -- } -- if (RenderedSubView) -- renderViewDivider(OS, ViewDepth + 1); -- renderLineSuffix(OS, ViewDepth); -- } -- -- renderViewFooter(OS); --} -diff --git a/tools/llvm-cov/SourceCoverageView.h b/tools/llvm-cov/SourceCoverageView.h -deleted file mode 100644 -index feef959..0000000 ---- a/tools/llvm-cov/SourceCoverageView.h -+++ /dev/null -@@ -1,285 +0,0 @@ --//===- SourceCoverageView.h - Code coverage view for source code ----------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This class implements rendering for code coverage of source code. --/// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_SOURCECOVERAGEVIEW_H --#define LLVM_COV_SOURCECOVERAGEVIEW_H -- --#include "CoverageViewOptions.h" --#include "llvm/ProfileData/Coverage/CoverageMapping.h" --#include "llvm/Support/MemoryBuffer.h" --#include -- --namespace llvm { -- --class SourceCoverageView; -- --/// \brief A view that represents a macro or include expansion. --struct ExpansionView { -- coverage::CounterMappingRegion Region; -- std::unique_ptr View; -- -- ExpansionView(const coverage::CounterMappingRegion &Region, -- std::unique_ptr View) -- : Region(Region), View(std::move(View)) {} -- ExpansionView(ExpansionView &&RHS) -- : Region(std::move(RHS.Region)), View(std::move(RHS.View)) {} -- ExpansionView &operator=(ExpansionView &&RHS) { -- Region = std::move(RHS.Region); -- View = std::move(RHS.View); -- return *this; -- } -- -- unsigned getLine() const { return Region.LineStart; } -- unsigned getStartCol() const { return Region.ColumnStart; } -- unsigned getEndCol() const { return Region.ColumnEnd; } -- -- friend bool operator<(const ExpansionView &LHS, const ExpansionView &RHS) { -- return LHS.Region.startLoc() < RHS.Region.startLoc(); -- } --}; -- --/// \brief A view that represents a function instantiation. --struct InstantiationView { -- StringRef FunctionName; -- unsigned Line; -- std::unique_ptr View; -- -- InstantiationView(StringRef FunctionName, unsigned Line, -- std::unique_ptr View) -- : FunctionName(FunctionName), Line(Line), View(std::move(View)) {} -- InstantiationView(InstantiationView &&RHS) -- : FunctionName(std::move(RHS.FunctionName)), Line(std::move(RHS.Line)), -- View(std::move(RHS.View)) {} -- InstantiationView &operator=(InstantiationView &&RHS) { -- FunctionName = std::move(RHS.FunctionName); -- Line = std::move(RHS.Line); -- View = std::move(RHS.View); -- return *this; -- } -- -- friend bool operator<(const InstantiationView &LHS, -- const InstantiationView &RHS) { -- return LHS.Line < RHS.Line; -- } --}; -- --/// \brief Coverage statistics for a single line. --struct LineCoverageStats { -- uint64_t ExecutionCount; -- unsigned RegionCount; -- bool Mapped; -- -- LineCoverageStats() : ExecutionCount(0), RegionCount(0), Mapped(false) {} -- -- bool isMapped() const { return Mapped; } -- -- bool hasMultipleRegions() const { return RegionCount > 1; } -- -- void addRegionStartCount(uint64_t Count) { -- // The max of all region starts is the most interesting value. -- addRegionCount(RegionCount ? std::max(ExecutionCount, Count) : Count); -- ++RegionCount; -- } -- -- void addRegionCount(uint64_t Count) { -- Mapped = true; -- ExecutionCount = Count; -- } --}; -- --/// \brief A file manager that handles format-aware file creation. --class CoveragePrinter { -- const CoverageViewOptions &Opts; -- --public: -- struct StreamDestructor { -- void operator()(raw_ostream *OS) const; -- }; -- -- using OwnedStream = std::unique_ptr; -- --protected: -- CoveragePrinter(const CoverageViewOptions &Opts) : Opts(Opts) {} -- -- /// \brief Return `OutputDir/ToplevelDir/Path.Extension`. If \p InToplevel is -- /// false, skip the ToplevelDir component. If \p Relative is false, skip the -- /// OutputDir component. -- std::string getOutputPath(StringRef Path, StringRef Extension, -- bool InToplevel, bool Relative = true); -- -- /// \brief If directory output is enabled, create a file in that directory -- /// at the path given by getOutputPath(). Otherwise, return stdout. -- Expected createOutputStream(StringRef Path, StringRef Extension, -- bool InToplevel); -- -- /// \brief Return the sub-directory name for file coverage reports. -- static StringRef getCoverageDir() { return "coverage"; } -- --public: -- static std::unique_ptr -- create(const CoverageViewOptions &Opts); -- -- virtual ~CoveragePrinter() {} -- -- /// @name File Creation Interface -- /// @{ -- -- /// \brief Create a file to print a coverage view into. -- virtual Expected createViewFile(StringRef Path, -- bool InToplevel) = 0; -- -- /// \brief Close a file which has been used to print a coverage view. -- virtual void closeViewFile(OwnedStream OS) = 0; -- -- /// \brief Create an index which lists reports for the given source files. -- virtual Error createIndexFile(ArrayRef SourceFiles) = 0; -- -- /// @} --}; -- --/// \brief A code coverage view of a source file or function. --/// --/// A source coverage view and its nested sub-views form a file-oriented --/// representation of code coverage data. This view can be printed out by a --/// renderer which implements the Rendering Interface. --class SourceCoverageView { -- /// A function or file name. -- StringRef SourceName; -- -- /// A memory buffer backing the source on display. -- const MemoryBuffer &File; -- -- /// Various options to guide the coverage renderer. -- const CoverageViewOptions &Options; -- -- /// Complete coverage information about the source on display. -- coverage::CoverageData CoverageInfo; -- -- /// A container for all expansions (e.g macros) in the source on display. -- std::vector ExpansionSubViews; -- -- /// A container for all instantiations (e.g template functions) in the source -- /// on display. -- std::vector InstantiationSubViews; -- --protected: -- struct LineRef { -- StringRef Line; -- int64_t LineNo; -- -- LineRef(StringRef Line, int64_t LineNo) : Line(Line), LineNo(LineNo) {} -- }; -- -- using CoverageSegmentArray = ArrayRef; -- -- /// @name Rendering Interface -- /// @{ -- -- /// \brief Render a header for the view. -- virtual void renderViewHeader(raw_ostream &OS) = 0; -- -- /// \brief Render a footer for the view. -- virtual void renderViewFooter(raw_ostream &OS) = 0; -- -- /// \brief Render the source name for the view. -- virtual void renderSourceName(raw_ostream &OS) = 0; -- -- /// \brief Render the line prefix at the given \p ViewDepth. -- virtual void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) = 0; -- -- /// \brief Render the line suffix at the given \p ViewDepth. -- virtual void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) = 0; -- -- /// \brief Render a view divider at the given \p ViewDepth. -- virtual void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) = 0; -- -- /// \brief Render a source line with highlighting. -- virtual void renderLine(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) = 0; -- -- /// \brief Render the line's execution count column. -- virtual void renderLineCoverageColumn(raw_ostream &OS, -- const LineCoverageStats &Line) = 0; -- -- /// \brief Render the line number column. -- virtual void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo) = 0; -- -- /// \brief Render all the region's execution counts on a line. -- virtual void renderRegionMarkers(raw_ostream &OS, -- CoverageSegmentArray Segments, -- unsigned ViewDepth) = 0; -- -- /// \brief Render the site of an expansion. -- virtual void -- renderExpansionSite(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) = 0; -- -- /// \brief Render an expansion view and any nested views. -- virtual void renderExpansionView(raw_ostream &OS, ExpansionView &ESV, -- unsigned ViewDepth) = 0; -- -- /// \brief Render an instantiation view and any nested views. -- virtual void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV, -- unsigned ViewDepth) = 0; -- -- /// @} -- -- /// \brief Format a count using engineering notation with 3 significant -- /// digits. -- static std::string formatCount(uint64_t N); -- -- /// \brief Check if region marker output is expected for a line. -- bool shouldRenderRegionMarkers(bool LineHasMultipleRegions) const; -- -- /// \brief Check if there are any sub-views attached to this view. -- bool hasSubViews() const; -- -- SourceCoverageView(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo) -- : SourceName(SourceName), File(File), Options(Options), -- CoverageInfo(std::move(CoverageInfo)) {} -- --public: -- static std::unique_ptr -- create(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo); -- -- virtual ~SourceCoverageView() {} -- -- StringRef getSourceName() const { return SourceName; } -- -- const CoverageViewOptions &getOptions() const { return Options; } -- -- /// \brief Add an expansion subview to this view. -- void addExpansion(const coverage::CounterMappingRegion &Region, -- std::unique_ptr View); -- -- /// \brief Add a function instantiation subview to this view. -- void addInstantiation(StringRef FunctionName, unsigned Line, -- std::unique_ptr View); -- -- /// \brief Print the code coverage information for a specific portion of a -- /// source file to the output stream. -- void print(raw_ostream &OS, bool WholeFile, bool ShowSourceName, -- unsigned ViewDepth = 0); --}; -- --} // namespace llvm -- --#endif // LLVM_COV_SOURCECOVERAGEVIEW_H -diff --git a/tools/llvm-cov/SourceCoverageViewHTML.cpp b/tools/llvm-cov/SourceCoverageViewHTML.cpp -index 81963e5..8b13789 100644 ---- a/tools/llvm-cov/SourceCoverageViewHTML.cpp -+++ b/tools/llvm-cov/SourceCoverageViewHTML.cpp -@@ -1,436 +1 @@ --//===- SourceCoverageViewHTML.cpp - A html code coverage view -------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This file implements the html coverage renderer. --/// --//===----------------------------------------------------------------------===// - --#include "SourceCoverageViewHTML.h" --#include "llvm/ADT/Optional.h" --#include "llvm/ADT/SmallString.h" --#include "llvm/ADT/StringExtras.h" --#include "llvm/Support/Path.h" -- --using namespace llvm; -- --namespace { -- --const char *BeginHeader = -- "" -- "" -- ""; -- --const char *CSSForCoverage = -- ""; -- --const char *EndHeader = ""; -- --const char *BeginCenteredDiv = "
"; -- --const char *EndCenteredDiv = "
"; -- --const char *BeginSourceNameDiv = "
"; -- --const char *EndSourceNameDiv = "
"; -- --const char *BeginCodeTD = ""; -- --const char *EndCodeTD = ""; -- --const char *BeginPre = "
";
--
--const char *EndPre = "
"; -- --const char *BeginExpansionDiv = "
"; -- --const char *EndExpansionDiv = "
"; -- --const char *BeginTable = ""; -- --const char *EndTable = "
"; -- --void emitPrelude(raw_ostream &OS) { -- OS << "" -- "" -- << BeginHeader << CSSForCoverage << EndHeader << "" -- << BeginCenteredDiv; --} -- --void emitEpilog(raw_ostream &OS) { -- OS << EndCenteredDiv << "" -- ""; --} -- --// Return a string with the special characters in \p Str escaped. --std::string escape(StringRef Str) { -- std::string Result; -- for (char C : Str) { -- if (C == '&') -- Result += "&"; -- else if (C == '<') -- Result += "<"; -- else if (C == '>') -- Result += ">"; -- else if (C == '\"') -- Result += """; -- else -- Result += C; -- } -- return Result; --} -- --// Create a \p Name tag around \p Str, and optionally set its \p ClassName. --std::string tag(const std::string &Name, const std::string &Str, -- const std::string &ClassName = "") { -- std::string Tag = "<" + Name; -- if (ClassName != "") -- Tag += " class='" + ClassName + "'"; -- return Tag + ">" + Str + ""; --} -- --// Create an anchor to \p Link with the label \p Str. --std::string a(const std::string &Link, const std::string &Str) { -- return "" + Str + ""; --} -- --} // anonymous namespace -- --Expected --CoveragePrinterHTML::createViewFile(StringRef Path, bool InToplevel) { -- auto OSOrErr = createOutputStream(Path, "html", InToplevel); -- if (!OSOrErr) -- return OSOrErr; -- -- OwnedStream OS = std::move(OSOrErr.get()); -- emitPrelude(*OS.get()); -- return std::move(OS); --} -- --void CoveragePrinterHTML::closeViewFile(OwnedStream OS) { -- emitEpilog(*OS.get()); --} -- --Error CoveragePrinterHTML::createIndexFile(ArrayRef SourceFiles) { -- auto OSOrErr = createOutputStream("index", "html", /*InToplevel=*/true); -- if (Error E = OSOrErr.takeError()) -- return E; -- auto OS = std::move(OSOrErr.get()); -- raw_ostream &OSRef = *OS.get(); -- -- // Emit a table containing links to reports for each file in the covmapping. -- emitPrelude(OSRef); -- OSRef << BeginSourceNameDiv << "Index" << EndSourceNameDiv; -- OSRef << BeginTable; -- for (StringRef SF : SourceFiles) { -- std::string LinkText = escape(sys::path::relative_path(SF)); -- std::string LinkTarget = -- escape(getOutputPath(SF, "html", /*InToplevel=*/false)); -- OSRef << tag("tr", tag("td", tag("pre", a(LinkTarget, LinkText), "code"))); -- } -- OSRef << EndTable; -- emitEpilog(OSRef); -- -- return Error::success(); --} -- --void SourceCoverageViewHTML::renderViewHeader(raw_ostream &OS) { -- OS << BeginTable; --} -- --void SourceCoverageViewHTML::renderViewFooter(raw_ostream &OS) { -- OS << EndTable; --} -- --void SourceCoverageViewHTML::renderSourceName(raw_ostream &OS) { -- OS << BeginSourceNameDiv << tag("pre", escape(getSourceName())) -- << EndSourceNameDiv; --} -- --void SourceCoverageViewHTML::renderLinePrefix(raw_ostream &OS, unsigned) { -- OS << ""; --} -- --void SourceCoverageViewHTML::renderLineSuffix(raw_ostream &OS, unsigned) { -- // If this view has sub-views, renderLine() cannot close the view's cell. -- // Take care of it here, after all sub-views have been rendered. -- if (hasSubViews()) -- OS << EndCodeTD; -- OS << ""; --} -- --void SourceCoverageViewHTML::renderViewDivider(raw_ostream &, unsigned) { -- // The table-based output makes view dividers unnecessary. --} -- --void SourceCoverageViewHTML::renderLine( -- raw_ostream &OS, LineRef L, const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, unsigned) { -- StringRef Line = L.Line; -- -- // Steps for handling text-escaping, highlighting, and tooltip creation: -- // -- // 1. Split the line into N+1 snippets, where N = |Segments|. The first -- // snippet starts from Col=1 and ends at the start of the first segment. -- // The last snippet starts at the last mapped column in the line and ends -- // at the end of the line. Both are required but may be empty. -- -- SmallVector Snippets; -- -- unsigned LCol = 1; -- auto Snip = [&](unsigned Start, unsigned Len) { -- assert(Start + Len <= Line.size() && "Snippet extends past the EOL"); -- Snippets.push_back(Line.substr(Start, Len)); -- LCol += Len; -- }; -- -- Snip(LCol - 1, Segments.empty() ? 0 : (Segments.front()->Col - 1)); -- -- for (unsigned I = 1, E = Segments.size(); I < E; ++I) { -- assert(LCol == Segments[I - 1]->Col && "Snippet start position is wrong"); -- Snip(LCol - 1, Segments[I]->Col - LCol); -- } -- -- // |Line| + 1 is needed to avoid underflow when, e.g |Line| = 0 and LCol = 1. -- Snip(LCol - 1, Line.size() + 1 - LCol); -- assert(LCol == Line.size() + 1 && "Final snippet doesn't reach the EOL"); -- -- // 2. Escape all of the snippets. -- -- for (unsigned I = 0, E = Snippets.size(); I < E; ++I) -- Snippets[I] = escape(Snippets[I]); -- -- // 3. Use \p WrappedSegment to set the highlight for snippets 0 and 1. Use -- // segment 1 to set the highlight for snippet 2, segment 2 to set the -- // highlight for snippet 3, and so on. -- -- Optional Color; -- auto Highlight = [&](const std::string &Snippet) { -- return tag("span", Snippet, Color.getValue()); -- }; -- -- auto CheckIfUncovered = [](const coverage::CoverageSegment *S) { -- return S && S->HasCount && S->Count == 0; -- }; -- -- if (CheckIfUncovered(WrappedSegment) || -- CheckIfUncovered(Segments.empty() ? nullptr : Segments.front())) { -- Color = "red"; -- Snippets[0] = Highlight(Snippets[0]); -- Snippets[1] = Highlight(Snippets[1]); -- } -- -- for (unsigned I = 1, E = Segments.size(); I < E; ++I) { -- const auto *CurSeg = Segments[I]; -- if (CurSeg->Col == ExpansionCol) -- Color = "cyan"; -- else if (CheckIfUncovered(CurSeg)) -- Color = "red"; -- else -- Color = None; -- -- if (Color.hasValue()) -- Snippets[I + 1] = Highlight(Snippets[I + 1]); -- } -- -- // 4. Snippets[1:N+1] correspond to \p Segments[0:N]: use these to generate -- // sub-line region count tooltips if needed. -- -- bool HasMultipleRegions = [&] { -- unsigned RegionCount = 0; -- for (const auto *S : Segments) -- if (S->HasCount && S->IsRegionEntry) -- if (++RegionCount > 1) -- return true; -- return false; -- }(); -- -- if (shouldRenderRegionMarkers(HasMultipleRegions)) { -- for (unsigned I = 0, E = Segments.size(); I < E; ++I) { -- const auto *CurSeg = Segments[I]; -- if (!CurSeg->IsRegionEntry || !CurSeg->HasCount) -- continue; -- -- Snippets[I + 1] = -- tag("div", Snippets[I + 1] + tag("span", formatCount(CurSeg->Count), -- "tooltip-content"), -- "tooltip"); -- } -- } -- -- OS << BeginCodeTD; -- OS << BeginPre; -- for (const auto &Snippet : Snippets) -- OS << Snippet; -- OS << EndPre; -- -- // If there are no sub-views left to attach to this cell, end the cell. -- // Otherwise, end it after the sub-views are rendered (renderLineSuffix()). -- if (!hasSubViews()) -- OS << EndCodeTD; --} -- --void SourceCoverageViewHTML::renderLineCoverageColumn( -- raw_ostream &OS, const LineCoverageStats &Line) { -- std::string Count = ""; -- if (Line.isMapped()) -- Count = tag("pre", formatCount(Line.ExecutionCount)); -- std::string CoverageClass = -- (Line.ExecutionCount > 0) ? "covered-line" : "uncovered-line"; -- OS << tag("td", Count, CoverageClass); --} -- --void SourceCoverageViewHTML::renderLineNumberColumn(raw_ostream &OS, -- unsigned LineNo) { -- OS << tag("td", tag("pre", utostr(uint64_t(LineNo))), "line-number"); --} -- --void SourceCoverageViewHTML::renderRegionMarkers(raw_ostream &, -- CoverageSegmentArray, -- unsigned) { -- // Region markers are rendered in-line using tooltips. --} -- --void SourceCoverageViewHTML::renderExpansionSite( -- raw_ostream &OS, LineRef L, const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, unsigned ViewDepth) { -- // Render the line containing the expansion site. No extra formatting needed. -- renderLine(OS, L, WrappedSegment, Segments, ExpansionCol, ViewDepth); --} -- --void SourceCoverageViewHTML::renderExpansionView(raw_ostream &OS, -- ExpansionView &ESV, -- unsigned ViewDepth) { -- OS << BeginExpansionDiv; -- ESV.View->print(OS, /*WholeFile=*/false, /*ShowSourceName=*/false, -- ViewDepth + 1); -- OS << EndExpansionDiv; --} -- --void SourceCoverageViewHTML::renderInstantiationView(raw_ostream &OS, -- InstantiationView &ISV, -- unsigned ViewDepth) { -- OS << BeginExpansionDiv; -- ISV.View->print(OS, /*WholeFile=*/false, /*ShowSourceName=*/true, ViewDepth); -- OS << EndExpansionDiv; --} -diff --git a/tools/llvm-cov/SourceCoverageViewHTML.h b/tools/llvm-cov/SourceCoverageViewHTML.h -deleted file mode 100644 -index 50ecf2b..0000000 ---- a/tools/llvm-cov/SourceCoverageViewHTML.h -+++ /dev/null -@@ -1,83 +0,0 @@ --//===- SourceCoverageViewHTML.h - A html code coverage view ---------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This file defines the interface to the html coverage renderer. --/// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_SOURCECOVERAGEVIEWHTML_H --#define LLVM_COV_SOURCECOVERAGEVIEWHTML_H -- --#include "SourceCoverageView.h" -- --namespace llvm { -- --/// \brief A coverage printer for html output. --class CoveragePrinterHTML : public CoveragePrinter { --public: -- Expected createViewFile(StringRef Path, -- bool InToplevel) override; -- -- void closeViewFile(OwnedStream OS) override; -- -- Error createIndexFile(ArrayRef SourceFiles) override; -- -- CoveragePrinterHTML(const CoverageViewOptions &Opts) -- : CoveragePrinter(Opts) {} --}; -- --/// \brief A code coverage view which supports html-based rendering. --class SourceCoverageViewHTML : public SourceCoverageView { -- void renderViewHeader(raw_ostream &OS) override; -- -- void renderViewFooter(raw_ostream &OS) override; -- -- void renderSourceName(raw_ostream &OS) override; -- -- void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLine(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionSite(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionView(raw_ostream &OS, ExpansionView &ESV, -- unsigned ViewDepth) override; -- -- void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV, -- unsigned ViewDepth) override; -- -- void renderLineCoverageColumn(raw_ostream &OS, -- const LineCoverageStats &Line) override; -- -- void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo) override; -- -- void renderRegionMarkers(raw_ostream &OS, CoverageSegmentArray Segments, -- unsigned ViewDepth) override; -- --public: -- SourceCoverageViewHTML(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo) -- : SourceCoverageView(SourceName, File, Options, std::move(CoverageInfo)) { -- } --}; -- --} // namespace llvm -- --#endif // LLVM_COV_SOURCECOVERAGEVIEWHTML_H -diff --git a/tools/llvm-cov/SourceCoverageViewText.cpp b/tools/llvm-cov/SourceCoverageViewText.cpp -index ae9d6da..8b13789 100644 ---- a/tools/llvm-cov/SourceCoverageViewText.cpp -+++ b/tools/llvm-cov/SourceCoverageViewText.cpp -@@ -1,213 +1 @@ --//===- SourceCoverageViewText.cpp - A text-based code coverage view -------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This file implements the text-based coverage renderer. --/// --//===----------------------------------------------------------------------===// - --#include "SourceCoverageViewText.h" --#include "llvm/ADT/Optional.h" --#include "llvm/ADT/SmallString.h" --#include "llvm/ADT/StringExtras.h" -- --using namespace llvm; -- --Expected --CoveragePrinterText::createViewFile(StringRef Path, bool InToplevel) { -- return createOutputStream(Path, "txt", InToplevel); --} -- --void CoveragePrinterText::closeViewFile(OwnedStream OS) { -- OS->operator<<('\n'); --} -- --Error CoveragePrinterText::createIndexFile(ArrayRef SourceFiles) { -- auto OSOrErr = createOutputStream("index", "txt", /*InToplevel=*/true); -- if (Error E = OSOrErr.takeError()) -- return E; -- auto OS = std::move(OSOrErr.get()); -- raw_ostream &OSRef = *OS.get(); -- -- for (StringRef SF : SourceFiles) -- OSRef << getOutputPath(SF, "txt", /*InToplevel=*/false) << '\n'; -- -- return Error::success(); --} -- --namespace { -- --static const unsigned LineCoverageColumnWidth = 7; --static const unsigned LineNumberColumnWidth = 5; -- --/// \brief Get the width of the leading columns. --unsigned getCombinedColumnWidth(const CoverageViewOptions &Opts) { -- return (Opts.ShowLineStats ? LineCoverageColumnWidth + 1 : 0) + -- (Opts.ShowLineNumbers ? LineNumberColumnWidth + 1 : 0); --} -- --/// \brief The width of the line that is used to divide between the view and --/// the subviews. --unsigned getDividerWidth(const CoverageViewOptions &Opts) { -- return getCombinedColumnWidth(Opts) + 4; --} -- --} // anonymous namespace -- --void SourceCoverageViewText::renderViewHeader(raw_ostream &) {} -- --void SourceCoverageViewText::renderViewFooter(raw_ostream &) {} -- --void SourceCoverageViewText::renderSourceName(raw_ostream &OS) { -- getOptions().colored_ostream(OS, raw_ostream::CYAN) << getSourceName() -- << ":\n"; --} -- --void SourceCoverageViewText::renderLinePrefix(raw_ostream &OS, -- unsigned ViewDepth) { -- for (unsigned I = 0; I < ViewDepth; ++I) -- OS << " |"; --} -- --void SourceCoverageViewText::renderLineSuffix(raw_ostream &, unsigned) {} -- --void SourceCoverageViewText::renderViewDivider(raw_ostream &OS, -- unsigned ViewDepth) { -- assert(ViewDepth != 0 && "Cannot render divider at top level"); -- renderLinePrefix(OS, ViewDepth - 1); -- OS.indent(2); -- unsigned Length = getDividerWidth(getOptions()); -- for (unsigned I = 0; I < Length; ++I) -- OS << '-'; -- OS << '\n'; --} -- --void SourceCoverageViewText::renderLine( -- raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, unsigned ViewDepth) { -- StringRef Line = L.Line; -- unsigned LineNumber = L.LineNo; -- -- Optional Highlight; -- SmallVector, 2> HighlightedRanges; -- -- // The first segment overlaps from a previous line, so we treat it specially. -- if (WrappedSegment && WrappedSegment->HasCount && WrappedSegment->Count == 0) -- Highlight = raw_ostream::RED; -- -- // Output each segment of the line, possibly highlighted. -- unsigned Col = 1; -- for (const auto *S : Segments) { -- unsigned End = std::min(S->Col, static_cast(Line.size()) + 1); -- colored_ostream(OS, Highlight ? *Highlight : raw_ostream::SAVEDCOLOR, -- getOptions().Colors && Highlight, /*Bold=*/false, -- /*BG=*/true) -- << Line.substr(Col - 1, End - Col); -- if (getOptions().Debug && Highlight) -- HighlightedRanges.push_back(std::make_pair(Col, End)); -- Col = End; -- if (Col == ExpansionCol) -- Highlight = raw_ostream::CYAN; -- else if (S->HasCount && S->Count == 0) -- Highlight = raw_ostream::RED; -- else -- Highlight = None; -- } -- -- // Show the rest of the line. -- colored_ostream(OS, Highlight ? *Highlight : raw_ostream::SAVEDCOLOR, -- getOptions().Colors && Highlight, /*Bold=*/false, /*BG=*/true) -- << Line.substr(Col - 1, Line.size() - Col + 1); -- OS << '\n'; -- -- if (getOptions().Debug) { -- for (const auto &Range : HighlightedRanges) -- errs() << "Highlighted line " << LineNumber << ", " << Range.first -- << " -> " << Range.second << '\n'; -- if (Highlight) -- errs() << "Highlighted line " << LineNumber << ", " << Col << " -> ?\n"; -- } --} -- --void SourceCoverageViewText::renderLineCoverageColumn( -- raw_ostream &OS, const LineCoverageStats &Line) { -- if (!Line.isMapped()) { -- OS.indent(LineCoverageColumnWidth) << '|'; -- return; -- } -- std::string C = formatCount(Line.ExecutionCount); -- OS.indent(LineCoverageColumnWidth - C.size()); -- colored_ostream(OS, raw_ostream::MAGENTA, -- Line.hasMultipleRegions() && getOptions().Colors) -- << C; -- OS << '|'; --} -- --void SourceCoverageViewText::renderLineNumberColumn(raw_ostream &OS, -- unsigned LineNo) { -- SmallString<32> Buffer; -- raw_svector_ostream BufferOS(Buffer); -- BufferOS << LineNo; -- auto Str = BufferOS.str(); -- // Trim and align to the right. -- Str = Str.substr(0, std::min(Str.size(), (size_t)LineNumberColumnWidth)); -- OS.indent(LineNumberColumnWidth - Str.size()) << Str << '|'; --} -- --void SourceCoverageViewText::renderRegionMarkers( -- raw_ostream &OS, CoverageSegmentArray Segments, unsigned ViewDepth) { -- renderLinePrefix(OS, ViewDepth); -- OS.indent(getCombinedColumnWidth(getOptions())); -- -- unsigned PrevColumn = 1; -- for (const auto *S : Segments) { -- if (!S->IsRegionEntry) -- continue; -- // Skip to the new region. -- if (S->Col > PrevColumn) -- OS.indent(S->Col - PrevColumn); -- PrevColumn = S->Col + 1; -- std::string C = formatCount(S->Count); -- PrevColumn += C.size(); -- OS << '^' << C; -- } -- OS << '\n'; -- -- if (getOptions().Debug) -- for (const auto *S : Segments) -- errs() << "Marker at " << S->Line << ":" << S->Col << " = " -- << formatCount(S->Count) << (S->IsRegionEntry ? "\n" : " (pop)\n"); --} -- --void SourceCoverageViewText::renderExpansionSite( -- raw_ostream &OS, LineRef L, const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, unsigned ViewDepth) { -- renderLinePrefix(OS, ViewDepth); -- OS.indent(getCombinedColumnWidth(getOptions()) + (ViewDepth == 0 ? 0 : 1)); -- renderLine(OS, L, WrappedSegment, Segments, ExpansionCol, ViewDepth); --} -- --void SourceCoverageViewText::renderExpansionView(raw_ostream &OS, -- ExpansionView &ESV, -- unsigned ViewDepth) { -- // Render the child subview. -- if (getOptions().Debug) -- errs() << "Expansion at line " << ESV.getLine() << ", " << ESV.getStartCol() -- << " -> " << ESV.getEndCol() << '\n'; -- ESV.View->print(OS, /*WholeFile=*/false, /*ShowSourceName=*/false, -- ViewDepth + 1); --} -- --void SourceCoverageViewText::renderInstantiationView(raw_ostream &OS, -- InstantiationView &ISV, -- unsigned ViewDepth) { -- renderLinePrefix(OS, ViewDepth); -- OS << ' '; -- ISV.View->print(OS, /*WholeFile=*/false, /*ShowSourceName=*/true, ViewDepth); --} -diff --git a/tools/llvm-cov/SourceCoverageViewText.h b/tools/llvm-cov/SourceCoverageViewText.h -deleted file mode 100644 -index b233124..0000000 ---- a/tools/llvm-cov/SourceCoverageViewText.h -+++ /dev/null -@@ -1,83 +0,0 @@ --//===- SourceCoverageViewText.h - A text-based code coverage view ---------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This file defines the interface to the text-based coverage renderer. --/// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_SOURCECOVERAGEVIEWTEXT_H --#define LLVM_COV_SOURCECOVERAGEVIEWTEXT_H -- --#include "SourceCoverageView.h" -- --namespace llvm { -- --/// \brief A coverage printer for text output. --class CoveragePrinterText : public CoveragePrinter { --public: -- Expected createViewFile(StringRef Path, -- bool InToplevel) override; -- -- void closeViewFile(OwnedStream OS) override; -- -- Error createIndexFile(ArrayRef SourceFiles) override; -- -- CoveragePrinterText(const CoverageViewOptions &Opts) -- : CoveragePrinter(Opts) {} --}; -- --/// \brief A code coverage view which supports text-based rendering. --class SourceCoverageViewText : public SourceCoverageView { -- void renderViewHeader(raw_ostream &OS) override; -- -- void renderViewFooter(raw_ostream &OS) override; -- -- void renderSourceName(raw_ostream &OS) override; -- -- void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLine(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionSite(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionView(raw_ostream &OS, ExpansionView &ESV, -- unsigned ViewDepth) override; -- -- void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV, -- unsigned ViewDepth) override; -- -- void renderLineCoverageColumn(raw_ostream &OS, -- const LineCoverageStats &Line) override; -- -- void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo) override; -- -- void renderRegionMarkers(raw_ostream &OS, CoverageSegmentArray Segments, -- unsigned ViewDepth) override; -- --public: -- SourceCoverageViewText(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo) -- : SourceCoverageView(SourceName, File, Options, std::move(CoverageInfo)) { -- } --}; -- --} // namespace llvm -- --#endif // LLVM_COV_SOURCECOVERAGEVIEWTEXT_H -diff --git a/tools/llvm-cov/TestingSupport.cpp b/tools/llvm-cov/TestingSupport.cpp -index 72768f4..8b13789 100644 ---- a/tools/llvm-cov/TestingSupport.cpp -+++ b/tools/llvm-cov/TestingSupport.cpp -@@ -1,92 +1 @@ --//===- TestingSupport.cpp - Convert objects files into test files --------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// - --#include "llvm/Object/ObjectFile.h" --#include "llvm/ProfileData/InstrProf.h" --#include "llvm/Support/CommandLine.h" --#include "llvm/Support/LEB128.h" --#include "llvm/Support/raw_ostream.h" --#include --#include -- --using namespace llvm; --using namespace object; -- --int convertForTestingMain(int argc, const char *argv[]) { -- cl::opt InputSourceFile(cl::Positional, cl::Required, -- cl::desc("")); -- -- cl::opt OutputFilename( -- "o", cl::Required, -- cl::desc( -- "File with the profile data obtained after an instrumented run")); -- -- cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); -- -- auto ObjErr = llvm::object::ObjectFile::createObjectFile(InputSourceFile); -- if (!ObjErr) { -- std::string Buf; -- raw_string_ostream OS(Buf); -- logAllUnhandledErrors(ObjErr.takeError(), OS, ""); -- OS.flush(); -- errs() << "error: " << Buf; -- return 1; -- } -- ObjectFile *OF = ObjErr.get().getBinary(); -- auto BytesInAddress = OF->getBytesInAddress(); -- if (BytesInAddress != 8) { -- errs() << "error: 64 bit binary expected\n"; -- return 1; -- } -- -- // Look for the sections that we are interested in. -- int FoundSectionCount = 0; -- SectionRef ProfileNames, CoverageMapping; -- for (const auto &Section : OF->sections()) { -- StringRef Name; -- if (Section.getName(Name)) -- return 1; -- if (Name == llvm::getInstrProfNameSectionName(false)) { -- ProfileNames = Section; -- } else if (Name == llvm::getInstrProfCoverageSectionName(false)) { -- CoverageMapping = Section; -- } else -- continue; -- ++FoundSectionCount; -- } -- if (FoundSectionCount != 2) -- return 1; -- -- // Get the contents of the given sections. -- uint64_t ProfileNamesAddress = ProfileNames.getAddress(); -- StringRef CoverageMappingData; -- StringRef ProfileNamesData; -- if (CoverageMapping.getContents(CoverageMappingData) || -- ProfileNames.getContents(ProfileNamesData)) -- return 1; -- -- int FD; -- if (auto Err = -- sys::fs::openFileForWrite(OutputFilename, FD, sys::fs::F_None)) { -- errs() << "error: " << Err.message() << "\n"; -- return 1; -- } -- -- raw_fd_ostream OS(FD, true); -- OS << "llvmcovmtestdata"; -- encodeULEB128(ProfileNamesData.size(), OS); -- encodeULEB128(ProfileNamesAddress, OS); -- OS << ProfileNamesData; -- // Coverage mapping data is expected to have an alignment of 8. -- for (unsigned Pad = OffsetToAlignment(OS.tell(), 8); Pad; --Pad) -- OS.write(uint8_t(0)); -- OS << CoverageMappingData; -- -- return 0; --} -diff --git a/tools/llvm-cov/gcov.cpp b/tools/llvm-cov/gcov.cpp -index 4652fed..8b13789 100644 ---- a/tools/llvm-cov/gcov.cpp -+++ b/tools/llvm-cov/gcov.cpp -@@ -1,145 +1 @@ --//===- gcov.cpp - GCOV compatible LLVM coverage tool ----------------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// llvm-cov is a command line tools to analyze and report coverage information. --// --//===----------------------------------------------------------------------===// - --#include "llvm/ADT/SmallString.h" --#include "llvm/Support/CommandLine.h" --#include "llvm/Support/Errc.h" --#include "llvm/Support/FileSystem.h" --#include "llvm/Support/GCOV.h" --#include "llvm/Support/Path.h" --#include --using namespace llvm; -- --static void reportCoverage(StringRef SourceFile, StringRef ObjectDir, -- const std::string &InputGCNO, -- const std::string &InputGCDA, bool DumpGCOV, -- const GCOV::Options &Options) { -- SmallString<128> CoverageFileStem(ObjectDir); -- if (CoverageFileStem.empty()) { -- // If no directory was specified with -o, look next to the source file. -- CoverageFileStem = sys::path::parent_path(SourceFile); -- sys::path::append(CoverageFileStem, sys::path::stem(SourceFile)); -- } else if (sys::fs::is_directory(ObjectDir)) -- // A directory name was given. Use it and the source file name. -- sys::path::append(CoverageFileStem, sys::path::stem(SourceFile)); -- else -- // A file was given. Ignore the source file and look next to this file. -- sys::path::replace_extension(CoverageFileStem, ""); -- -- std::string GCNO = InputGCNO.empty() -- ? std::string(CoverageFileStem.str()) + ".gcno" -- : InputGCNO; -- std::string GCDA = InputGCDA.empty() -- ? std::string(CoverageFileStem.str()) + ".gcda" -- : InputGCDA; -- GCOVFile GF; -- -- ErrorOr> GCNO_Buff = -- MemoryBuffer::getFileOrSTDIN(GCNO); -- if (std::error_code EC = GCNO_Buff.getError()) { -- errs() << GCNO << ": " << EC.message() << "\n"; -- return; -- } -- GCOVBuffer GCNO_GB(GCNO_Buff.get().get()); -- if (!GF.readGCNO(GCNO_GB)) { -- errs() << "Invalid .gcno File!\n"; -- return; -- } -- -- ErrorOr> GCDA_Buff = -- MemoryBuffer::getFileOrSTDIN(GCDA); -- if (std::error_code EC = GCDA_Buff.getError()) { -- if (EC != errc::no_such_file_or_directory) { -- errs() << GCDA << ": " << EC.message() << "\n"; -- return; -- } -- // Clear the filename to make it clear we didn't read anything. -- GCDA = "-"; -- } else { -- GCOVBuffer GCDA_GB(GCDA_Buff.get().get()); -- if (!GF.readGCDA(GCDA_GB)) { -- errs() << "Invalid .gcda File!\n"; -- return; -- } -- } -- -- if (DumpGCOV) -- GF.dump(); -- -- FileInfo FI(Options); -- GF.collectLineCounts(FI); -- FI.print(llvm::outs(), SourceFile, GCNO, GCDA); --} -- --int gcovMain(int argc, const char *argv[]) { -- cl::list SourceFiles(cl::Positional, cl::OneOrMore, -- cl::desc("SOURCEFILE")); -- -- cl::opt AllBlocks("a", cl::Grouping, cl::init(false), -- cl::desc("Display all basic blocks")); -- cl::alias AllBlocksA("all-blocks", cl::aliasopt(AllBlocks)); -- -- cl::opt BranchProb("b", cl::Grouping, cl::init(false), -- cl::desc("Display branch probabilities")); -- cl::alias BranchProbA("branch-probabilities", cl::aliasopt(BranchProb)); -- -- cl::opt BranchCount("c", cl::Grouping, cl::init(false), -- cl::desc("Display branch counts instead " -- "of percentages (requires -b)")); -- cl::alias BranchCountA("branch-counts", cl::aliasopt(BranchCount)); -- -- cl::opt LongNames("l", cl::Grouping, cl::init(false), -- cl::desc("Prefix filenames with the main file")); -- cl::alias LongNamesA("long-file-names", cl::aliasopt(LongNames)); -- -- cl::opt FuncSummary("f", cl::Grouping, cl::init(false), -- cl::desc("Show coverage for each function")); -- cl::alias FuncSummaryA("function-summaries", cl::aliasopt(FuncSummary)); -- -- cl::opt NoOutput("n", cl::Grouping, cl::init(false), -- cl::desc("Do not output any .gcov files")); -- cl::alias NoOutputA("no-output", cl::aliasopt(NoOutput)); -- -- cl::opt ObjectDir( -- "o", cl::value_desc("DIR|FILE"), cl::init(""), -- cl::desc("Find objects in DIR or based on FILE's path")); -- cl::alias ObjectDirA("object-directory", cl::aliasopt(ObjectDir)); -- cl::alias ObjectDirB("object-file", cl::aliasopt(ObjectDir)); -- -- cl::opt PreservePaths("p", cl::Grouping, cl::init(false), -- cl::desc("Preserve path components")); -- cl::alias PreservePathsA("preserve-paths", cl::aliasopt(PreservePaths)); -- -- cl::opt UncondBranch("u", cl::Grouping, cl::init(false), -- cl::desc("Display unconditional branch info " -- "(requires -b)")); -- cl::alias UncondBranchA("unconditional-branches", cl::aliasopt(UncondBranch)); -- -- cl::OptionCategory DebugCat("Internal and debugging options"); -- cl::opt DumpGCOV("dump", cl::init(false), cl::cat(DebugCat), -- cl::desc("Dump the gcov file to stderr")); -- cl::opt InputGCNO("gcno", cl::cat(DebugCat), cl::init(""), -- cl::desc("Override inferred gcno file")); -- cl::opt InputGCDA("gcda", cl::cat(DebugCat), cl::init(""), -- cl::desc("Override inferred gcda file")); -- -- cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); -- -- GCOV::Options Options(AllBlocks, BranchProb, BranchCount, FuncSummary, -- PreservePaths, UncondBranch, LongNames, NoOutput); -- -- for (const auto &SourceFile : SourceFiles) -- reportCoverage(SourceFile, ObjectDir, InputGCNO, InputGCDA, DumpGCOV, -- Options); -- return 0; --} -diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp -index ba60cd9..aa1f228 100644 ---- a/tools/llvm-cov/llvm-cov.cpp -+++ b/tools/llvm-cov/llvm-cov.cpp -@@ -10,85 +10,6 @@ - // llvm-cov is a command line tools to analyze and report coverage information. - // - //===----------------------------------------------------------------------===// -- --#include "llvm/ADT/StringRef.h" --#include "llvm/ADT/StringSwitch.h" --#include "llvm/Support/CommandLine.h" --#include "llvm/Support/ManagedStatic.h" --#include "llvm/Support/Path.h" --#include "llvm/Support/PrettyStackTrace.h" --#include "llvm/Support/Process.h" --#include "llvm/Support/Signals.h" --#include "llvm/Support/raw_ostream.h" --#include -- --using namespace llvm; -- --/// \brief The main entry point for the 'show' subcommand. --int showMain(int argc, const char *argv[]); -- --/// \brief The main entry point for the 'report' subcommand. --int reportMain(int argc, const char *argv[]); -- --/// \brief The main entry point for the 'convert-for-testing' subcommand. --int convertForTestingMain(int argc, const char *argv[]); -- --/// \brief The main entry point for the gcov compatible coverage tool. --int gcovMain(int argc, const char *argv[]); -- --/// \brief Top level help. --static int helpMain(int argc, const char *argv[]) { -- errs() << "Usage: llvm-cov {gcov|report|show} [OPTION]...\n\n" -- << "Shows code coverage information.\n\n" -- << "Subcommands:\n" -- << " gcov: Work with the gcov format.\n" -- << " show: Annotate source files using instrprof style coverage.\n" -- << " report: Summarize instrprof style coverage information.\n"; -- return 0; --} -- --/// \brief Top level version information. --static int versionMain(int argc, const char *argv[]) { -- cl::PrintVersionMessage(); -- return 0; --} -- - int main(int argc, const char **argv) { -- // Print a stack trace if we signal out. -- sys::PrintStackTraceOnErrorSignal(argv[0]); -- PrettyStackTraceProgram X(argc, argv); -- llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. -- -- // If argv[0] is or ends with 'gcov', always be gcov compatible -- if (sys::path::stem(argv[0]).endswith_lower("gcov")) -- return gcovMain(argc, argv); -- -- // Check if we are invoking a specific tool command. -- if (argc > 1) { -- typedef int (*MainFunction)(int, const char *[]); -- MainFunction Func = StringSwitch(argv[1]) -- .Case("convert-for-testing", convertForTestingMain) -- .Case("gcov", gcovMain) -- .Case("report", reportMain) -- .Case("show", showMain) -- .Cases("-h", "-help", "--help", helpMain) -- .Cases("-version", "--version", versionMain) -- .Default(nullptr); -- -- if (Func) { -- std::string Invocation = std::string(argv[0]) + " " + argv[1]; -- argv[1] = Invocation.c_str(); -- return Func(argc - 1, argv + 1); -- } -- } -- -- if (argc > 1) { -- if (sys::Process::StandardErrHasColors()) -- errs().changeColor(raw_ostream::RED); -- errs() << "Unrecognized command: " << argv[1] << ".\n\n"; -- if (sys::Process::StandardErrHasColors()) -- errs().resetColor(); -- } -- helpMain(argc, argv); - return 1; - } -diff --git a/tools/sancov/sancov.cc b/tools/sancov/sancov.cc -index 55b0370..c869a73 100644 ---- a/tools/sancov/sancov.cc -+++ b/tools/sancov/sancov.cc -@@ -10,1249 +10,7 @@ - // This file is a command-line tool for reading and analyzing sanitizer - // coverage. - //===----------------------------------------------------------------------===// --#include "llvm/ADT/STLExtras.h" --#include "llvm/ADT/Twine.h" --#include "llvm/DebugInfo/Symbolize/Symbolize.h" --#include "llvm/MC/MCAsmInfo.h" --#include "llvm/MC/MCContext.h" --#include "llvm/MC/MCDisassembler/MCDisassembler.h" --#include "llvm/MC/MCInst.h" --#include "llvm/MC/MCInstPrinter.h" --#include "llvm/MC/MCInstrAnalysis.h" --#include "llvm/MC/MCInstrInfo.h" --#include "llvm/MC/MCObjectFileInfo.h" --#include "llvm/MC/MCRegisterInfo.h" --#include "llvm/MC/MCSubtargetInfo.h" --#include "llvm/Object/Archive.h" --#include "llvm/Object/Binary.h" --#include "llvm/Object/ELFObjectFile.h" --#include "llvm/Object/ObjectFile.h" --#include "llvm/Support/Casting.h" --#include "llvm/Support/CommandLine.h" --#include "llvm/Support/Errc.h" --#include "llvm/Support/ErrorOr.h" --#include "llvm/Support/FileSystem.h" --#include "llvm/Support/LineIterator.h" --#include "llvm/Support/MD5.h" --#include "llvm/Support/ManagedStatic.h" --#include "llvm/Support/MemoryBuffer.h" --#include "llvm/Support/Path.h" --#include "llvm/Support/PrettyStackTrace.h" --#include "llvm/Support/Regex.h" --#include "llvm/Support/Signals.h" --#include "llvm/Support/SpecialCaseList.h" --#include "llvm/Support/TargetRegistry.h" --#include "llvm/Support/TargetSelect.h" --#include "llvm/Support/ToolOutputFile.h" --#include "llvm/Support/raw_ostream.h" -- --#include --#include --#include --#include --#include --#include -- --using namespace llvm; -- --namespace { -- --// --------- COMMAND LINE FLAGS --------- -- --enum ActionType { -- PrintAction, -- PrintCovPointsAction, -- CoveredFunctionsAction, -- NotCoveredFunctionsAction, -- HtmlReportAction, -- StatsAction --}; -- --cl::opt Action( -- cl::desc("Action (required)"), cl::Required, -- cl::values(clEnumValN(PrintAction, "print", "Print coverage addresses"), -- clEnumValN(PrintCovPointsAction, "print-coverage-pcs", -- "Print coverage instrumentation points addresses."), -- clEnumValN(CoveredFunctionsAction, "covered-functions", -- "Print all covered funcions."), -- clEnumValN(NotCoveredFunctionsAction, "not-covered-functions", -- "Print all not covered funcions."), -- clEnumValN(HtmlReportAction, "html-report", -- "Print HTML coverage report."), -- clEnumValN(StatsAction, "print-coverage-stats", -- "Print coverage statistics."), -- clEnumValEnd)); -- --static cl::list -- ClInputFiles(cl::Positional, cl::OneOrMore, -- cl::desc("(|<.sancov file>)...")); -- --static cl::opt ClDemangle("demangle", cl::init(true), -- cl::desc("Print demangled function name.")); -- --static cl::opt ClStripPathPrefix( -- "strip_path_prefix", cl::init(""), -- cl::desc("Strip this prefix from file paths in reports.")); -- --static cl::opt -- ClBlacklist("blacklist", cl::init(""), -- cl::desc("Blacklist file (sanitizer blacklist format).")); -- --static cl::opt ClUseDefaultBlacklist( -- "use_default_blacklist", cl::init(true), cl::Hidden, -- cl::desc("Controls if default blacklist should be used.")); -- --static const char *const DefaultBlacklistStr = "fun:__sanitizer_.*\n" -- "src:/usr/include/.*\n" -- "src:.*/libc\\+\\+/.*\n"; -- --// --------- FORMAT SPECIFICATION --------- -- --struct FileHeader { -- uint32_t Bitness; -- uint32_t Magic; --}; -- --static const uint32_t BinCoverageMagic = 0xC0BFFFFF; --static const uint32_t Bitness32 = 0xFFFFFF32; --static const uint32_t Bitness64 = 0xFFFFFF64; -- --// --------- ERROR HANDLING --------- -- --static void Fail(const llvm::Twine &E) { -- errs() << "Error: " << E << "\n"; -- exit(1); --} -- --static void FailIfError(std::error_code Error) { -- if (!Error) -- return; -- errs() << "Error: " << Error.message() << "(" << Error.value() << ")\n"; -- exit(1); --} -- --template static void FailIfError(const ErrorOr &E) { -- FailIfError(E.getError()); --} -- --static void FailIfError(Error Err) { -- if (Err) { -- logAllUnhandledErrors(std::move(Err), errs(), "Error: "); -- exit(1); -- } --} -- --template static void FailIfError(Expected &E) { -- FailIfError(E.takeError()); --} -- --static void FailIfNotEmpty(const llvm::Twine &E) { -- if (E.str().empty()) -- return; -- Fail(E); --} -- --template --static void FailIfEmpty(const std::unique_ptr &Ptr, -- const std::string &Message) { -- if (Ptr.get()) -- return; -- Fail(Message); --} -- --// --------- -- --// Produces std::map> grouping input --// elements by FuncTy result. --template --static inline auto group_by(const RangeTy &R, FuncTy F) -- -> std::map::type, -- std::vector::type>> { -- std::map::type, -- std::vector::type>> -- Result; -- for (const auto &E : R) { -- Result[F(E)].push_back(E); -- } -- return Result; --} -- --template --static void readInts(const char *Start, const char *End, -- std::set *Ints) { -- const T *S = reinterpret_cast(Start); -- const T *E = reinterpret_cast(End); -- std::copy(S, E, std::inserter(*Ints, Ints->end())); --} -- --struct FileLoc { -- bool operator<(const FileLoc &RHS) const { -- return std::tie(FileName, Line) < std::tie(RHS.FileName, RHS.Line); -- } -- -- std::string FileName; -- uint32_t Line; --}; -- --struct FileFn { -- bool operator<(const FileFn &RHS) const { -- return std::tie(FileName, FunctionName) < -- std::tie(RHS.FileName, RHS.FunctionName); -- } -- -- std::string FileName; -- std::string FunctionName; --}; -- --struct FnLoc { -- bool operator<(const FnLoc &RHS) const { -- return std::tie(Loc, FunctionName) < std::tie(RHS.Loc, RHS.FunctionName); -- } -- -- FileLoc Loc; -- std::string FunctionName; --}; -- --std::string stripPathPrefix(std::string Path) { -- if (ClStripPathPrefix.empty()) -- return Path; -- size_t Pos = Path.find(ClStripPathPrefix); -- if (Pos == std::string::npos) -- return Path; -- return Path.substr(Pos + ClStripPathPrefix.size()); --} -- --static std::unique_ptr createSymbolizer() { -- symbolize::LLVMSymbolizer::Options SymbolizerOptions; -- SymbolizerOptions.Demangle = ClDemangle; -- SymbolizerOptions.UseSymbolTable = true; -- return std::unique_ptr( -- new symbolize::LLVMSymbolizer(SymbolizerOptions)); --} -- --// A DILineInfo with address. --struct AddrInfo : public DILineInfo { -- uint64_t Addr; -- -- AddrInfo(const DILineInfo &DI, uint64_t Addr) : DILineInfo(DI), Addr(Addr) { -- FileName = normalizeFilename(FileName); -- } -- --private: -- static std::string normalizeFilename(const std::string &FileName) { -- SmallString<256> S(FileName); -- sys::path::remove_dots(S, /* remove_dot_dot */ true); -- return S.str().str(); -- } --}; -- --class Blacklists { --public: -- Blacklists() -- : DefaultBlacklist(createDefaultBlacklist()), -- UserBlacklist(createUserBlacklist()) {} -- -- // AddrInfo contains normalized filename. It is important to check it rather -- // than DILineInfo. -- bool isBlacklisted(const AddrInfo &AI) { -- if (DefaultBlacklist && DefaultBlacklist->inSection("fun", AI.FunctionName)) -- return true; -- if (DefaultBlacklist && DefaultBlacklist->inSection("src", AI.FileName)) -- return true; -- if (UserBlacklist && UserBlacklist->inSection("fun", AI.FunctionName)) -- return true; -- if (UserBlacklist && UserBlacklist->inSection("src", AI.FileName)) -- return true; -- return false; -- } -- --private: -- static std::unique_ptr createDefaultBlacklist() { -- if (!ClUseDefaultBlacklist) -- return std::unique_ptr(); -- std::unique_ptr MB = -- MemoryBuffer::getMemBuffer(DefaultBlacklistStr); -- std::string Error; -- auto Blacklist = SpecialCaseList::create(MB.get(), Error); -- FailIfNotEmpty(Error); -- return Blacklist; -- } -- -- static std::unique_ptr createUserBlacklist() { -- if (ClBlacklist.empty()) -- return std::unique_ptr(); -- -- return SpecialCaseList::createOrDie({{ClBlacklist}}); -- } -- std::unique_ptr DefaultBlacklist; -- std::unique_ptr UserBlacklist; --}; -- --// Collect all debug info for given addresses. --static std::vector getAddrInfo(const std::string &ObjectFile, -- const std::set &Addrs, -- bool InlinedCode) { -- std::vector Result; -- auto Symbolizer(createSymbolizer()); -- Blacklists B; -- -- for (auto Addr : Addrs) { -- auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, Addr); -- FailIfError(LineInfo); -- auto LineAddrInfo = AddrInfo(*LineInfo, Addr); -- if (B.isBlacklisted(LineAddrInfo)) -- continue; -- Result.push_back(LineAddrInfo); -- if (InlinedCode) { -- auto InliningInfo = Symbolizer->symbolizeInlinedCode(ObjectFile, Addr); -- FailIfError(InliningInfo); -- for (uint32_t I = 0; I < InliningInfo->getNumberOfFrames(); ++I) { -- auto FrameInfo = InliningInfo->getFrame(I); -- auto FrameAddrInfo = AddrInfo(FrameInfo, Addr); -- if (B.isBlacklisted(FrameAddrInfo)) -- continue; -- Result.push_back(FrameAddrInfo); -- } -- } -- } -- -- return Result; --} -- --// Locate __sanitizer_cov* function addresses that are used for coverage --// reporting. --static std::set --findSanitizerCovFunctions(const object::ObjectFile &O) { -- std::set Result; -- -- for (const object::SymbolRef &Symbol : O.symbols()) { -- Expected AddressOrErr = Symbol.getAddress(); -- FailIfError(errorToErrorCode(AddressOrErr.takeError())); -- -- Expected NameOrErr = Symbol.getName(); -- FailIfError(errorToErrorCode(NameOrErr.takeError())); -- StringRef Name = NameOrErr.get(); -- -- if (Name == "__sanitizer_cov" || Name == "__sanitizer_cov_with_check" || -- Name == "__sanitizer_cov_trace_func_enter") { -- if (!(Symbol.getFlags() & object::BasicSymbolRef::SF_Undefined)) -- Result.insert(AddressOrErr.get()); -- } -- } -- -- return Result; --} -- --// Locate addresses of all coverage points in a file. Coverage point --// is defined as the 'address of instruction following __sanitizer_cov --// call - 1'. --static void getObjectCoveragePoints(const object::ObjectFile &O, -- std::set *Addrs) { -- Triple TheTriple("unknown-unknown-unknown"); -- TheTriple.setArch(Triple::ArchType(O.getArch())); -- auto TripleName = TheTriple.getTriple(); -- -- std::string Error; -- const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); -- FailIfNotEmpty(Error); -- -- std::unique_ptr STI( -- TheTarget->createMCSubtargetInfo(TripleName, "", "")); -- FailIfEmpty(STI, "no subtarget info for target " + TripleName); -- -- std::unique_ptr MRI( -- TheTarget->createMCRegInfo(TripleName)); -- FailIfEmpty(MRI, "no register info for target " + TripleName); -- -- std::unique_ptr AsmInfo( -- TheTarget->createMCAsmInfo(*MRI, TripleName)); -- FailIfEmpty(AsmInfo, "no asm info for target " + TripleName); -- -- std::unique_ptr MOFI(new MCObjectFileInfo); -- MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get()); -- std::unique_ptr DisAsm( -- TheTarget->createMCDisassembler(*STI, Ctx)); -- FailIfEmpty(DisAsm, "no disassembler info for target " + TripleName); -- -- std::unique_ptr MII(TheTarget->createMCInstrInfo()); -- FailIfEmpty(MII, "no instruction info for target " + TripleName); -- -- std::unique_ptr MIA( -- TheTarget->createMCInstrAnalysis(MII.get())); -- FailIfEmpty(MIA, "no instruction analysis info for target " + TripleName); -- -- auto SanCovAddrs = findSanitizerCovFunctions(O); -- if (SanCovAddrs.empty()) -- Fail("__sanitizer_cov* functions not found"); -- -- for (object::SectionRef Section : O.sections()) { -- if (Section.isVirtual() || !Section.isText()) // llvm-objdump does the same. -- continue; -- uint64_t SectionAddr = Section.getAddress(); -- uint64_t SectSize = Section.getSize(); -- if (!SectSize) -- continue; -- -- StringRef BytesStr; -- FailIfError(Section.getContents(BytesStr)); -- ArrayRef Bytes(reinterpret_cast(BytesStr.data()), -- BytesStr.size()); -- -- for (uint64_t Index = 0, Size = 0; Index < Section.getSize(); -- Index += Size) { -- MCInst Inst; -- if (!DisAsm->getInstruction(Inst, Size, Bytes.slice(Index), -- SectionAddr + Index, nulls(), nulls())) { -- if (Size == 0) -- Size = 1; -- continue; -- } -- uint64_t Addr = Index + SectionAddr; -- // Sanitizer coverage uses the address of the next instruction - 1. -- uint64_t CovPoint = Addr + Size - 1; -- uint64_t Target; -- if (MIA->isCall(Inst) && -- MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target) && -- SanCovAddrs.find(Target) != SanCovAddrs.end()) -- Addrs->insert(CovPoint); -- } -- } --} -- --static void --visitObjectFiles(const object::Archive &A, -- function_ref Fn) { -- Error Err; -- for (auto &C : A.children(Err)) { -- Expected> ChildOrErr = C.getAsBinary(); -- FailIfError(errorToErrorCode(ChildOrErr.takeError())); -- if (auto *O = dyn_cast(&*ChildOrErr.get())) -- Fn(*O); -- else -- FailIfError(object::object_error::invalid_file_type); -- } -- FailIfError(std::move(Err)); --} -- --static void --visitObjectFiles(const std::string &FileName, -- function_ref Fn) { -- Expected> BinaryOrErr = -- object::createBinary(FileName); -- if (!BinaryOrErr) -- FailIfError(errorToErrorCode(BinaryOrErr.takeError())); -- -- object::Binary &Binary = *BinaryOrErr.get().getBinary(); -- if (object::Archive *A = dyn_cast(&Binary)) -- visitObjectFiles(*A, Fn); -- else if (object::ObjectFile *O = dyn_cast(&Binary)) -- Fn(*O); -- else -- FailIfError(object::object_error::invalid_file_type); --} -- --std::set findSanitizerCovFunctions(const std::string &FileName) { -- std::set Result; -- visitObjectFiles(FileName, [&](const object::ObjectFile &O) { -- auto Addrs = findSanitizerCovFunctions(O); -- Result.insert(Addrs.begin(), Addrs.end()); -- }); -- return Result; --} -- --// Locate addresses of all coverage points in a file. Coverage point --// is defined as the 'address of instruction following __sanitizer_cov --// call - 1'. --std::set getCoveragePoints(const std::string &FileName) { -- std::set Result; -- visitObjectFiles(FileName, [&](const object::ObjectFile &O) { -- getObjectCoveragePoints(O, &Result); -- }); -- return Result; --} -- --static void printCovPoints(const std::string &ObjFile, raw_ostream &OS) { -- for (uint64_t Addr : getCoveragePoints(ObjFile)) { -- OS << "0x"; -- OS.write_hex(Addr); -- OS << "\n"; -- } --} -- --static std::string escapeHtml(const std::string &S) { -- std::string Result; -- Result.reserve(S.size()); -- for (char Ch : S) { -- switch (Ch) { -- case '&': -- Result.append("&"); -- break; -- case '\'': -- Result.append("'"); -- break; -- case '"': -- Result.append("""); -- break; -- case '<': -- Result.append("<"); -- break; -- case '>': -- Result.append(">"); -- break; -- default: -- Result.push_back(Ch); -- break; -- } -- } -- return Result; --} -- --// Adds leading zeroes wrapped in 'lz' style. --// Leading zeroes help locate 000% coverage. --static std::string formatHtmlPct(size_t Pct) { -- Pct = std::max(std::size_t{0}, std::min(std::size_t{100}, Pct)); -- -- std::string Num = std::to_string(Pct); -- std::string Zeroes(3 - Num.size(), '0'); -- if (!Zeroes.empty()) -- Zeroes = "" + Zeroes + ""; -- -- return Zeroes + Num; --} -- --static std::string anchorName(const std::string &Anchor) { -- llvm::MD5 Hasher; -- llvm::MD5::MD5Result Hash; -- Hasher.update(Anchor); -- Hasher.final(Hash); -- -- SmallString<32> HexString; -- llvm::MD5::stringifyResult(Hash, HexString); -- return HexString.str().str(); --} -- --static ErrorOr isCoverageFile(const std::string &FileName) { -- ErrorOr> BufOrErr = -- MemoryBuffer::getFile(FileName); -- if (!BufOrErr) { -- errs() << "Warning: " << BufOrErr.getError().message() << "(" -- << BufOrErr.getError().value() -- << "), filename: " << llvm::sys::path::filename(FileName) << "\n"; -- return BufOrErr.getError(); -- } -- std::unique_ptr Buf = std::move(BufOrErr.get()); -- if (Buf->getBufferSize() < 8) { -- return false; -- } -- const FileHeader *Header = -- reinterpret_cast(Buf->getBufferStart()); -- return Header->Magic == BinCoverageMagic; --} -- --struct CoverageStats { -- CoverageStats() : AllPoints(0), CovPoints(0), AllFns(0), CovFns(0) {} -- -- size_t AllPoints; -- size_t CovPoints; -- size_t AllFns; -- size_t CovFns; --}; -- --static raw_ostream &operator<<(raw_ostream &OS, const CoverageStats &Stats) { -- OS << "all-edges: " << Stats.AllPoints << "\n"; -- OS << "cov-edges: " << Stats.CovPoints << "\n"; -- OS << "all-functions: " << Stats.AllFns << "\n"; -- OS << "cov-functions: " << Stats.CovFns << "\n"; -- return OS; --} -- --class CoverageData { --public: -- // Read single file coverage data. -- static ErrorOr> -- read(const std::string &FileName) { -- ErrorOr> BufOrErr = -- MemoryBuffer::getFile(FileName); -- if (!BufOrErr) -- return BufOrErr.getError(); -- std::unique_ptr Buf = std::move(BufOrErr.get()); -- if (Buf->getBufferSize() < 8) { -- errs() << "File too small (<8): " << Buf->getBufferSize(); -- return make_error_code(errc::illegal_byte_sequence); -- } -- const FileHeader *Header = -- reinterpret_cast(Buf->getBufferStart()); -- -- if (Header->Magic != BinCoverageMagic) { -- errs() << "Wrong magic: " << Header->Magic; -- return make_error_code(errc::illegal_byte_sequence); -- } -- -- auto Addrs = llvm::make_unique>(); -- -- switch (Header->Bitness) { -- case Bitness64: -- readInts(Buf->getBufferStart() + 8, Buf->getBufferEnd(), -- Addrs.get()); -- break; -- case Bitness32: -- readInts(Buf->getBufferStart() + 8, Buf->getBufferEnd(), -- Addrs.get()); -- break; -- default: -- errs() << "Unsupported bitness: " << Header->Bitness; -- return make_error_code(errc::illegal_byte_sequence); -- } -- -- return std::unique_ptr(new CoverageData(std::move(Addrs))); -- } -- -- // Merge multiple coverage data together. -- static std::unique_ptr -- merge(const std::vector> &Covs) { -- auto Addrs = llvm::make_unique>(); -- -- for (const auto &Cov : Covs) -- Addrs->insert(Cov->Addrs->begin(), Cov->Addrs->end()); -- -- return std::unique_ptr(new CoverageData(std::move(Addrs))); -- } -- -- // Read list of files and merges their coverage info. -- static ErrorOr> -- readAndMerge(const std::vector &FileNames) { -- std::vector> Covs; -- for (const auto &FileName : FileNames) { -- auto Cov = read(FileName); -- if (!Cov) -- return Cov.getError(); -- Covs.push_back(std::move(Cov.get())); -- } -- return merge(Covs); -- } -- -- // Print coverage addresses. -- void printAddrs(raw_ostream &OS) { -- for (auto Addr : *Addrs) { -- OS << "0x"; -- OS.write_hex(Addr); -- OS << "\n"; -- } -- } -- --protected: -- explicit CoverageData(std::unique_ptr> Addrs) -- : Addrs(std::move(Addrs)) {} -- -- friend class CoverageDataWithObjectFile; -- -- std::unique_ptr> Addrs; --}; -- --// Coverage data translated into source code line-level information. --// Fetches debug info in constructor and calculates various information per --// request. --class SourceCoverageData { --public: -- enum LineStatus { -- // coverage information for the line is not available. -- // default value in maps. -- UNKNOWN = 0, -- // the line is fully covered. -- COVERED = 1, -- // the line is fully uncovered. -- NOT_COVERED = 2, -- // some points in the line a covered, some are not. -- MIXED = 3 -- }; -- -- SourceCoverageData(std::string ObjectFile, const std::set &Addrs) -- : AllCovPoints(getCoveragePoints(ObjectFile)) { -- if (!std::includes(AllCovPoints.begin(), AllCovPoints.end(), Addrs.begin(), -- Addrs.end())) { -- Fail("Coverage points in binary and .sancov file do not match."); -- } -- -- AllAddrInfo = getAddrInfo(ObjectFile, AllCovPoints, true); -- CovAddrInfo = getAddrInfo(ObjectFile, Addrs, true); -- } -- -- // Compute number of coverage points hit/total in a file. -- // file_name -> -- std::map> computeFileCoverage() { -- std::map> FileCoverage; -- auto AllCovPointsByFile = -- group_by(AllAddrInfo, [](const AddrInfo &AI) { return AI.FileName; }); -- auto CovPointsByFile = -- group_by(CovAddrInfo, [](const AddrInfo &AI) { return AI.FileName; }); -- -- for (const auto &P : AllCovPointsByFile) { -- const std::string &FileName = P.first; -- -- FileCoverage[FileName] = -- std::make_pair(CovPointsByFile[FileName].size(), -- AllCovPointsByFile[FileName].size()); -- } -- return FileCoverage; -- } -- -- // line_number -> line_status. -- typedef std::map LineStatusMap; -- // file_name -> LineStatusMap -- typedef std::map FileLineStatusMap; -- -- // fills in the {file_name -> {line_no -> status}} map. -- FileLineStatusMap computeLineStatusMap() { -- FileLineStatusMap StatusMap; -- -- auto AllLocs = group_by(AllAddrInfo, [](const AddrInfo &AI) { -- return FileLoc{AI.FileName, AI.Line}; -- }); -- auto CovLocs = group_by(CovAddrInfo, [](const AddrInfo &AI) { -- return FileLoc{AI.FileName, AI.Line}; -- }); -- -- for (const auto &P : AllLocs) { -- const FileLoc &Loc = P.first; -- auto I = CovLocs.find(Loc); -- -- if (I == CovLocs.end()) { -- StatusMap[Loc.FileName][Loc.Line] = NOT_COVERED; -- } else { -- StatusMap[Loc.FileName][Loc.Line] = -- (I->second.size() == P.second.size()) ? COVERED : MIXED; -- } -- } -- return StatusMap; -- } -- -- std::set computeAllFunctions() const { -- std::set Fns; -- for (const auto &AI : AllAddrInfo) { -- Fns.insert(FileFn{AI.FileName, AI.FunctionName}); -- } -- return Fns; -- } -- -- std::set computeCoveredFunctions() const { -- std::set Fns; -- auto CovFns = group_by(CovAddrInfo, [](const AddrInfo &AI) { -- return FileFn{AI.FileName, AI.FunctionName}; -- }); -- -- for (const auto &P : CovFns) { -- Fns.insert(P.first); -- } -- return Fns; -- } -- -- std::set computeNotCoveredFunctions() const { -- std::set Fns; -- -- auto AllFns = group_by(AllAddrInfo, [](const AddrInfo &AI) { -- return FileFn{AI.FileName, AI.FunctionName}; -- }); -- auto CovFns = group_by(CovAddrInfo, [](const AddrInfo &AI) { -- return FileFn{AI.FileName, AI.FunctionName}; -- }); -- -- for (const auto &P : AllFns) { -- if (CovFns.find(P.first) == CovFns.end()) { -- Fns.insert(P.first); -- } -- } -- return Fns; -- } -- -- // Compute % coverage for each function. -- std::map computeFunctionsCoverage() const { -- std::map FnCoverage; -- auto AllFns = group_by(AllAddrInfo, [](const AddrInfo &AI) { -- return FileFn{AI.FileName, AI.FunctionName}; -- }); -- -- auto CovFns = group_by(CovAddrInfo, [](const AddrInfo &AI) { -- return FileFn{AI.FileName, AI.FunctionName}; -- }); -- -- for (const auto &P : AllFns) { -- FileFn F = P.first; -- FnCoverage[F] = CovFns[F].size() * 100 / P.second.size(); -- } -- -- return FnCoverage; -- } -- -- typedef std::map> FunctionLocs; -- // finds first line number in a file for each function. -- FunctionLocs resolveFunctions(const std::set &Fns) const { -- std::vector FnAddrs; -- for (const auto &AI : AllAddrInfo) { -- if (Fns.find(FileFn{AI.FileName, AI.FunctionName}) != Fns.end()) -- FnAddrs.push_back(AI); -- } -- -- auto GroupedAddrs = group_by(FnAddrs, [](const AddrInfo &AI) { -- return FnLoc{FileLoc{AI.FileName, AI.Line}, AI.FunctionName}; -- }); -- -- FunctionLocs Result; -- std::string LastFileName; -- std::set ProcessedFunctions; -- -- for (const auto &P : GroupedAddrs) { -- const FnLoc &Loc = P.first; -- std::string FileName = Loc.Loc.FileName; -- std::string FunctionName = Loc.FunctionName; -- -- if (LastFileName != FileName) -- ProcessedFunctions.clear(); -- LastFileName = FileName; -- -- if (!ProcessedFunctions.insert(FunctionName).second) -- continue; -- -- auto FLoc = FileLoc{FileName, Loc.Loc.Line}; -- Result[FLoc].insert(FunctionName); -- } -- return Result; -- } -- -- std::set files() const { -- std::set Files; -- for (const auto &AI : AllAddrInfo) { -- Files.insert(AI.FileName); -- } -- return Files; -- } -- -- void collectStats(CoverageStats *Stats) const { -- Stats->AllPoints += AllCovPoints.size(); -- Stats->AllFns += computeAllFunctions().size(); -- Stats->CovFns += computeCoveredFunctions().size(); -- } -- --private: -- const std::set AllCovPoints; -- -- std::vector AllAddrInfo; -- std::vector CovAddrInfo; --}; -- --static void printFunctionLocs(const SourceCoverageData::FunctionLocs &FnLocs, -- raw_ostream &OS) { -- for (const auto &Fns : FnLocs) { -- for (const auto &Fn : Fns.second) { -- OS << stripPathPrefix(Fns.first.FileName) << ":" << Fns.first.Line << " " -- << Fn << "\n"; -- } -- } --} -- --// Holder for coverage data + filename of corresponding object file. --class CoverageDataWithObjectFile : public CoverageData { --public: -- static ErrorOr> -- readAndMerge(const std::string &ObjectFile, -- const std::vector &FileNames) { -- auto MergedDataOrError = CoverageData::readAndMerge(FileNames); -- if (!MergedDataOrError) -- return MergedDataOrError.getError(); -- return std::unique_ptr( -- new CoverageDataWithObjectFile(ObjectFile, -- std::move(MergedDataOrError.get()))); -- } -- -- std::string object_file() const { return ObjectFile; } -- -- // Print list of covered functions. -- // Line format: : -- void printCoveredFunctions(raw_ostream &OS) const { -- SourceCoverageData SCovData(ObjectFile, *Addrs); -- auto CoveredFns = SCovData.computeCoveredFunctions(); -- printFunctionLocs(SCovData.resolveFunctions(CoveredFns), OS); -- } -- -- // Print list of not covered functions. -- // Line format: : -- void printNotCoveredFunctions(raw_ostream &OS) const { -- SourceCoverageData SCovData(ObjectFile, *Addrs); -- auto NotCoveredFns = SCovData.computeNotCoveredFunctions(); -- printFunctionLocs(SCovData.resolveFunctions(NotCoveredFns), OS); -- } -- -- void printReport(raw_ostream &OS) const { -- SourceCoverageData SCovData(ObjectFile, *Addrs); -- auto LineStatusMap = SCovData.computeLineStatusMap(); -- -- std::set AllFns = SCovData.computeAllFunctions(); -- // file_loc -> set[function_name] -- auto AllFnsByLoc = SCovData.resolveFunctions(AllFns); -- auto FileCoverage = SCovData.computeFileCoverage(); -- -- auto FnCoverage = SCovData.computeFunctionsCoverage(); -- auto FnCoverageByFile = -- group_by(FnCoverage, [](const std::pair &FileFn) { -- return FileFn.first.FileName; -- }); -- -- // TOC -- -- size_t NotCoveredFilesCount = 0; -- std::set Files = SCovData.files(); -- -- // Covered Files. -- OS << "
Touched Files\n"; -- OS << "\n"; -- OS << ""; -- OS << "\n"; -- for (const auto &FileName : Files) { -- std::pair FC = FileCoverage[FileName]; -- if (FC.first == 0) { -- NotCoveredFilesCount++; -- continue; -- } -- size_t CovPct = FC.second == 0 ? 100 : 100 * FC.first / FC.second; -- -- OS << "" -- << "" -- << "\n"; -- } -- OS << "
FileCoverage %Hit (Total) Fns
" -- << stripPathPrefix(FileName) << "" << formatHtmlPct(CovPct) << "%" << FC.first << " (" << FC.second << ")" -- << "
\n"; -- OS << "
\n"; -- -- // Not covered files. -- if (NotCoveredFilesCount) { -- OS << "
Not Touched Files\n"; -- OS << "\n"; -- for (const auto &FileName : Files) { -- std::pair FC = FileCoverage[FileName]; -- if (FC.first == 0) -- OS << "\n"; -- } -- OS << "
" << stripPathPrefix(FileName) << "
\n"; -- OS << "
\n"; -- } else { -- OS << "

Congratulations! All source files are touched.

\n"; -- } -- -- // Source -- for (const auto &FileName : Files) { -- std::pair FC = FileCoverage[FileName]; -- if (FC.first == 0) -- continue; -- OS << "\n"; -- OS << "

" << stripPathPrefix(FileName) << "

\n"; -- OS << "
Function Coverage"; -- OS << "
\n"; -- -- auto &FileFnCoverage = FnCoverageByFile[FileName]; -- -- for (const auto &P : FileFnCoverage) { -- std::string FunctionName = P.first.FunctionName; -- -- OS << "
"; -- OS << "" << formatHtmlPct(P.second) -- << "% "; -- OS << ""; -- OS << escapeHtml(FunctionName) << ""; -- OS << "
\n"; -- } -- OS << "
\n"; -- -- ErrorOr> BufOrErr = -- MemoryBuffer::getFile(FileName); -- if (!BufOrErr) { -- OS << "Error reading file: " << FileName << " : " -- << BufOrErr.getError().message() << "(" -- << BufOrErr.getError().value() << ")\n"; -- continue; -- } -- -- OS << "
\n";
--      const auto &LineStatuses = LineStatusMap[FileName];
--      for (line_iterator I = line_iterator(*BufOrErr.get(), false);
--           !I.is_at_eof(); ++I) {
--        uint32_t Line = I.line_number();
--        { // generate anchors (if any);
--          FileLoc Loc = FileLoc{FileName, Line};
--          auto It = AllFnsByLoc.find(Loc);
--          if (It != AllFnsByLoc.end()) {
--            for (const std::string &Fn : It->second) {
--              OS << "";
--            };
--          }
--        }
--
--        OS << "second
--                                                  : SourceCoverageData::UNKNOWN;
--        switch (Status) {
--        case SourceCoverageData::UNKNOWN:
--          OS << "class=unknown";
--          break;
--        case SourceCoverageData::COVERED:
--          OS << "class=covered";
--          break;
--        case SourceCoverageData::NOT_COVERED:
--          OS << "class=notcovered";
--          break;
--        case SourceCoverageData::MIXED:
--          OS << "class=mixed";
--          break;
--        }
--        OS << ">";
--        OS << escapeHtml(*I) << "\n";
--      }
--      OS << "
\n"; -- } -- } -- -- void collectStats(CoverageStats *Stats) const { -- Stats->CovPoints += Addrs->size(); -- -- SourceCoverageData SCovData(ObjectFile, *Addrs); -- SCovData.collectStats(Stats); -- } -- --private: -- CoverageDataWithObjectFile(std::string ObjectFile, -- std::unique_ptr Coverage) -- : CoverageData(std::move(Coverage->Addrs)), -- ObjectFile(std::move(ObjectFile)) {} -- const std::string ObjectFile; --}; -- --// Multiple coverage files data organized by object file. --class CoverageDataSet { --public: -- static ErrorOr> -- readCmdArguments(std::vector FileNames) { -- // Short name => file name. -- std::map ObjFiles; -- std::string FirstObjFile; -- std::set CovFiles; -- -- // Partition input values into coverage/object files. -- for (const auto &FileName : FileNames) { -- auto ErrorOrIsCoverage = isCoverageFile(FileName); -- if (!ErrorOrIsCoverage) -- continue; -- if (ErrorOrIsCoverage.get()) { -- CovFiles.insert(FileName); -- } else { -- auto ShortFileName = llvm::sys::path::filename(FileName); -- if (ObjFiles.find(ShortFileName) != ObjFiles.end()) { -- Fail("Duplicate binary file with a short name: " + ShortFileName); -- } -- -- ObjFiles[ShortFileName] = FileName; -- if (FirstObjFile.empty()) -- FirstObjFile = FileName; -- } -- } -- -- Regex SancovRegex("(.*)\\.[0-9]+\\.sancov"); -- SmallVector Components; -- -- // Object file => list of corresponding coverage file names. -- auto CoverageByObjFile = group_by(CovFiles, [&](std::string FileName) { -- auto ShortFileName = llvm::sys::path::filename(FileName); -- auto Ok = SancovRegex.match(ShortFileName, &Components); -- if (!Ok) { -- Fail("Can't match coverage file name against " -- "..sancov pattern: " + -- FileName); -- } -- -- auto Iter = ObjFiles.find(Components[1]); -- if (Iter == ObjFiles.end()) { -- Fail("Object file for coverage not found: " + FileName); -- } -- return Iter->second; -- }); -- -- // Read coverage. -- std::vector> MergedCoverage; -- for (const auto &Pair : CoverageByObjFile) { -- if (findSanitizerCovFunctions(Pair.first).empty()) { -- for (const auto &FileName : Pair.second) { -- CovFiles.erase(FileName); -- } -- -- errs() -- << "Ignoring " << Pair.first -- << " and its coverage because __sanitizer_cov* functions were not " -- "found.\n"; -- continue; -- } -- -- auto DataOrError = -- CoverageDataWithObjectFile::readAndMerge(Pair.first, Pair.second); -- FailIfError(DataOrError); -- MergedCoverage.push_back(std::move(DataOrError.get())); -- } -- -- return std::unique_ptr( -- new CoverageDataSet(FirstObjFile, &MergedCoverage, CovFiles)); -- } -- -- void printCoveredFunctions(raw_ostream &OS) const { -- for (const auto &Cov : Coverage) { -- Cov->printCoveredFunctions(OS); -- } -- } -- -- void printNotCoveredFunctions(raw_ostream &OS) const { -- for (const auto &Cov : Coverage) { -- Cov->printNotCoveredFunctions(OS); -- } -- } -- -- void printStats(raw_ostream &OS) const { -- CoverageStats Stats; -- for (const auto &Cov : Coverage) { -- Cov->collectStats(&Stats); -- } -- OS << Stats; -- } -- -- void printReport(raw_ostream &OS) const { -- auto Title = -- (llvm::sys::path::filename(MainObjFile) + " Coverage Report").str(); -- -- OS << "\n"; -- OS << "\n"; -- -- // Stylesheet -- OS << "\n"; -- OS << "" << Title << "\n"; -- OS << "\n"; -- OS << "\n"; -- -- // Title -- OS << "

" << Title << "

\n"; -- -- // Modules TOC. -- if (Coverage.size() > 1) { -- for (const auto &CovData : Coverage) { -- OS << "
  • object_file()) -- << "\">" << llvm::sys::path::filename(CovData->object_file()) -- << "
  • \n"; -- } -- } -- -- for (const auto &CovData : Coverage) { -- if (Coverage.size() > 1) { -- OS << "

    " << llvm::sys::path::filename(CovData->object_file()) -- << "

    \n"; -- } -- OS << "object_file()) -- << "\">\n"; -- CovData->printReport(OS); -- } -- -- // About -- OS << "
    About\n"; -- OS << "Coverage files:
      "; -- for (const auto &InputFile : CoverageFiles) { -- llvm::sys::fs::file_status Status; -- llvm::sys::fs::status(InputFile, Status); -- OS << "
    • " << stripPathPrefix(InputFile) << " (" -- << Status.getLastModificationTime().str() << ")
    • \n"; -- } -- OS << "
    \n"; -- -- OS << "\n"; -- OS << "\n"; -- } -- -- bool empty() const { return Coverage.empty(); } -- --private: -- explicit CoverageDataSet( -- const std::string &MainObjFile, -- std::vector> *Data, -- const std::set &CoverageFiles) -- : MainObjFile(MainObjFile), CoverageFiles(CoverageFiles) { -- Data->swap(this->Coverage); -- } -- -- const std::string MainObjFile; -- std::vector> Coverage; -- const std::set CoverageFiles; --}; -- --} // namespace - - int main(int argc, char **argv) { -- // Print stack trace if we signal out. -- sys::PrintStackTraceOnErrorSignal(argv[0]); -- PrettyStackTraceProgram X(argc, argv); -- llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. -- -- llvm::InitializeAllTargetInfos(); -- llvm::InitializeAllTargetMCs(); -- llvm::InitializeAllDisassemblers(); -- -- cl::ParseCommandLineOptions(argc, argv, "Sanitizer Coverage Processing Tool"); -- -- // -print doesn't need object files. -- if (Action == PrintAction) { -- auto CovData = CoverageData::readAndMerge(ClInputFiles); -- FailIfError(CovData); -- CovData.get()->printAddrs(outs()); -- return 0; -- } else if (Action == PrintCovPointsAction) { -- // -print-coverage-points doesn't need coverage files. -- for (const std::string &ObjFile : ClInputFiles) { -- printCovPoints(ObjFile, outs()); -- } -- return 0; -- } -- -- auto CovDataSet = CoverageDataSet::readCmdArguments(ClInputFiles); -- FailIfError(CovDataSet); -- -- if (CovDataSet.get()->empty()) { -- Fail("No coverage files specified."); -- } -- -- switch (Action) { -- case CoveredFunctionsAction: { -- CovDataSet.get()->printCoveredFunctions(outs()); -- return 0; -- } -- case NotCoveredFunctionsAction: { -- CovDataSet.get()->printNotCoveredFunctions(outs()); -- return 0; -- } -- case HtmlReportAction: { -- CovDataSet.get()->printReport(outs()); -- return 0; -- } -- case StatsAction: { -- CovDataSet.get()->printStats(outs()); -- return 0; -- } -- case PrintAction: -- case PrintCovPointsAction: -- llvm_unreachable("unsupported action"); -- } -+ return 0; - } -diff --git a/unittests/Support/ThreadPool.cpp b/unittests/Support/ThreadPool.cpp -index 69a24bc..b185859 100644 ---- a/unittests/Support/ThreadPool.cpp -+++ b/unittests/Support/ThreadPool.cpp -@@ -7,6 +7,8 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 -+ - #include "llvm/Support/ThreadPool.h" - - #include "llvm/ADT/STLExtras.h" -@@ -166,3 +168,5 @@ TEST_F(ThreadPoolTest, PoolDestruction) { - } - ASSERT_EQ(5, checked_in); - } -+ -+#endif diff --git a/deps/patches/llvm-3.9.0_win64-reloc-dwarf.patch b/deps/patches/llvm-3.9.0_win64-reloc-dwarf.patch deleted file mode 100644 index e7908c31a4e78..0000000000000 --- a/deps/patches/llvm-3.9.0_win64-reloc-dwarf.patch +++ /dev/null @@ -1,183 +0,0 @@ -diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h -index cd710ee..7cae156 100644 ---- a/include/llvm/MC/MCStreamer.h -+++ b/include/llvm/MC/MCStreamer.h -@@ -470,7 +470,7 @@ public: - /// \brief Emits a COFF section relative relocation. - /// - /// \param Symbol - Symbol the section relative relocation should point to. -- virtual void EmitCOFFSecRel32(MCSymbol const *Symbol); -+ virtual void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset); - - /// \brief Emit an ELF .size directive. - /// -diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h -index fe1ada9..63e44f2 100644 ---- a/include/llvm/MC/MCWinCOFFStreamer.h -+++ b/include/llvm/MC/MCWinCOFFStreamer.h -@@ -52,7 +52,7 @@ public: - void EndCOFFSymbolDef() override; - void EmitCOFFSafeSEH(MCSymbol const *Symbol) override; - void EmitCOFFSectionIndex(MCSymbol const *Symbol) override; -- void EmitCOFFSecRel32(MCSymbol const *Symbol) override; -+ void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override; - void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) override; - void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, -diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp -index 272bace..9df876f 100644 ---- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp -+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp -@@ -1699,7 +1699,7 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, - unsigned Size, - bool IsSectionRelative) const { - if (MAI->needsDwarfSectionOffsetDirective() && IsSectionRelative) { -- OutStreamer->EmitCOFFSecRel32(Label); -+ OutStreamer->EmitCOFFSecRel32(Label, Offset); - return; - } - -diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp -index 60f40d0..1ff4e6e 100644 ---- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp -+++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp -@@ -150,7 +150,7 @@ void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label, - if (!ForceOffset) { - // On COFF targets, we have to emit the special .secrel32 directive. - if (MAI->needsDwarfSectionOffsetDirective()) { -- OutStreamer->EmitCOFFSecRel32(Label); -+ OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0); - return; - } - -diff --git a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp -index ebf80de..13cba28 100644 ---- a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp -+++ b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp -@@ -667,7 +667,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, - OS.AddComment("Function type index"); - OS.EmitIntValue(getFuncIdForSubprogram(GV->getSubprogram()).getIndex(), 4); - OS.AddComment("Function section relative address"); -- OS.EmitCOFFSecRel32(Fn); -+ OS.EmitCOFFSecRel32(Fn, /*Offset=*/0); - OS.AddComment("Function section index"); - OS.EmitCOFFSectionIndex(Fn); - OS.AddComment("Flags"); -@@ -2066,7 +2066,7 @@ void CodeViewDebug::emitDebugInfoForGlobal(const DIGlobalVariable *DIGV, - OS.AddComment("Type"); - OS.EmitIntValue(getCompleteTypeIndex(DIGV->getType()).getIndex(), 4); - OS.AddComment("DataOffset"); -- OS.EmitCOFFSecRel32(GVSym); -+ OS.EmitCOFFSecRel32(GVSym, /*Offset=*/0); - OS.AddComment("Segment"); - OS.EmitCOFFSectionIndex(GVSym); - OS.AddComment("Name"); -diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp -index 2aaa85a..6b625ca 100644 ---- a/lib/CodeGen/AsmPrinter/DIE.cpp -+++ b/lib/CodeGen/AsmPrinter/DIE.cpp -@@ -454,7 +454,7 @@ void DIEEntry::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { - Addr += CU->getDebugInfoOffset(); - if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) - AP->EmitLabelPlusOffset(CU->getSectionSym(), Addr, -- DIEEntry::getRefAddrSize(AP)); -+ DIEEntry::getRefAddrSize(AP), true); - else - AP->OutStreamer->EmitIntValue(Addr, DIEEntry::getRefAddrSize(AP)); - } else -diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp -index ef2f781..00419ac 100644 ---- a/lib/MC/MCAsmStreamer.cpp -+++ b/lib/MC/MCAsmStreamer.cpp -@@ -149,7 +149,7 @@ public: - void EndCOFFSymbolDef() override; - void EmitCOFFSafeSEH(MCSymbol const *Symbol) override; - void EmitCOFFSectionIndex(MCSymbol const *Symbol) override; -- void EmitCOFFSecRel32(MCSymbol const *Symbol) override; -+ void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override; - void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) override; - void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) override; -@@ -602,7 +602,7 @@ void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { - EmitEOL(); - } - --void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { -+void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) { - OS << "\t.secrel32\t"; - Symbol->print(OS, MAI); - EmitEOL(); -diff --git a/lib/MC/MCCodeView.cpp b/lib/MC/MCCodeView.cpp -index 65cff41..5dab392 100644 ---- a/lib/MC/MCCodeView.cpp -+++ b/lib/MC/MCCodeView.cpp -@@ -156,7 +156,7 @@ void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS, - OS.EmitIntValue(unsigned(ModuleSubstreamKind::Lines), 4); - OS.emitAbsoluteSymbolDiff(LineEnd, LineBegin, 4); - OS.EmitLabel(LineBegin); -- OS.EmitCOFFSecRel32(FuncBegin); -+ OS.EmitCOFFSecRel32(FuncBegin, /*Offset=*/0); - OS.EmitCOFFSectionIndex(FuncBegin); - - // Actual line info. -diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp -index 653627a..f717f05 100644 ---- a/lib/MC/MCParser/COFFAsmParser.cpp -+++ b/lib/MC/MCParser/COFFAsmParser.cpp -@@ -450,7 +450,7 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) { - MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID); - - Lex(); -- getStreamer().EmitCOFFSecRel32(Symbol); -+ getStreamer().EmitCOFFSecRel32(Symbol, /*Offset=*/0); - return false; - } - -diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp -index 6c8828f..9927473 100644 ---- a/lib/MC/MCStreamer.cpp -+++ b/lib/MC/MCStreamer.cpp -@@ -124,7 +124,7 @@ void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, - if (!IsSectionRelative) - EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size); - else -- EmitCOFFSecRel32(Sym); -+ EmitCOFFSecRel32(Sym, /*Offset=*/0); - } - - void MCStreamer::EmitGPRel64Value(const MCExpr *Value) { -@@ -647,7 +647,7 @@ void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) { - void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { - } - --void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { -+void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) { - } - - /// EmitRawText - If this file is backed by an assembly streamer, this dumps -diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp -index 5c6407e..1444394 100644 ---- a/lib/MC/WinCOFFStreamer.cpp -+++ b/lib/MC/WinCOFFStreamer.cpp -@@ -195,11 +195,18 @@ void MCWinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { - DF->getContents().resize(DF->getContents().size() + 2, 0); - } - --void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { -+void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) { - MCDataFragment *DF = getOrCreateDataFragment(); -- const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext()); -- MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_4); -+ // Create Symbol A for the relocation relative reference. -+ const MCExpr *MCE = MCSymbolRefExpr::create(Symbol, getContext()); -+ // Add the constant offset, if given -+ if (Offset) -+ MCE = MCBinaryExpr::createAdd(MCE, MCConstantExpr::create(Offset, getContext()), getContext()); -+ // Build the secrel32 relocation. -+ MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_SecRel_4); -+ // Record the relocation. - DF->getFixups().push_back(Fixup); -+ // Emit 4 bytes (zeros) to the object file. - DF->getContents().resize(DF->getContents().size() + 4, 0); - } - diff --git a/deps/patches/llvm-4.0.0-D37576-NVPTX-sm_70.patch b/deps/patches/llvm-4.0.0-D37576-NVPTX-sm_70.patch deleted file mode 100644 index 9fee1f36e2a95..0000000000000 --- a/deps/patches/llvm-4.0.0-D37576-NVPTX-sm_70.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 4059d374ce981827223ab6b1dae7af4ec5f8e74a Mon Sep 17 00:00:00 2001 -From: Artem Belevich -Date: Thu, 7 Sep 2017 18:14:32 +0000 -Subject: [PATCH] [CUDA] Added rudimentary support for CUDA-9 and sm_70. - -For now CUDA-9 is not included in the list of CUDA versions clang -searches for, so the path to CUDA-9 must be explicitly passed -via --cuda-path=. - -On LLVM side NVPTX added sm_70 GPU type which bumps required -PTX version to 6.0, but otherwise is equivalent to sm_62 at the moment. - -Differential Revision: https://reviews.llvm.org/D37576 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312734 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Target/NVPTX/NVPTX.td | 5 +++++ - test/CodeGen/NVPTX/sm-version-70.ll | 5 +++++ - 2 files changed, 10 insertions(+) - create mode 100644 test/CodeGen/NVPTX/sm-version-70.ll - -diff --git a/lib/Target/NVPTX/NVPTX.td b/lib/Target/NVPTX/NVPTX.td -index c77ddbc9978..aba37d36359 100644 ---- a/lib/Target/NVPTX/NVPTX.td -+++ b/lib/Target/NVPTX/NVPTX.td -@@ -50,6 +50,8 @@ def SM61 : SubtargetFeature<"sm_61", "SmVersion", "61", - "Target SM 6.1">; - def SM62 : SubtargetFeature<"sm_62", "SmVersion", "62", - "Target SM 6.2">; -+def SM70 : SubtargetFeature<"sm_70", "SmVersion", "70", -+ "Target SM 7.0">; - - def SATOM : SubtargetFeature<"satom", "HasAtomScope", "true", - "Atomic operations with scope">; -@@ -67,6 +69,8 @@ def PTX43 : SubtargetFeature<"ptx43", "PTXVersion", "43", - "Use PTX version 4.3">; - def PTX50 : SubtargetFeature<"ptx50", "PTXVersion", "50", - "Use PTX version 5.0">; -+def PTX60 : SubtargetFeature<"ptx60", "PTXVersion", "60", -+ "Use PTX version 6.0">; - - //===----------------------------------------------------------------------===// - // NVPTX supported processors. -@@ -87,6 +91,7 @@ def : Proc<"sm_53", [SM53, PTX42]>; - def : Proc<"sm_60", [SM60, PTX50, SATOM]>; - def : Proc<"sm_61", [SM61, PTX50, SATOM]>; - def : Proc<"sm_62", [SM62, PTX50, SATOM]>; -+def : Proc<"sm_70", [SM70, PTX60, SATOM]>; - - def NVPTXInstrInfo : InstrInfo { - } -diff --git a/test/CodeGen/NVPTX/sm-version-70.ll b/test/CodeGen/NVPTX/sm-version-70.ll -new file mode 100644 -index 00000000000..8b72d50747a ---- /dev/null -+++ b/test/CodeGen/NVPTX/sm-version-70.ll -@@ -0,0 +1,5 @@ -+; RUN: llc < %s -march=nvptx -mcpu=sm_70 | FileCheck %s -+; RUN: llc < %s -march=nvptx64 -mcpu=sm_70 | FileCheck %s -+ -+; CHECK: .version 6.0 -+; CHECK: .target sm_70 diff --git a/deps/patches/llvm-4.0.0_threads.patch b/deps/patches/llvm-4.0.0_threads.patch deleted file mode 100644 index d3ed7ee7931b9..0000000000000 --- a/deps/patches/llvm-4.0.0_threads.patch +++ /dev/null @@ -1,2032 +0,0 @@ -From dfead72dc82a76a62433c4f0ed2262407ef51bf0 Mon Sep 17 00:00:00 2001 -From: Alex Crichton -Date: Thu, 28 Jan 2016 20:44:50 -0800 -Subject: [PATCH] Don't compile usage of std::thread - -As of the time of this writing it's not actually used anywhere meaningfullly -throughout the LLVM repo that we need, and it unfortunately uses `std::thread` -which isn't available in mingw-w64 toolchains with the win32 threading model -(the one that we use). - -The change made to achive this was to just always use the single-threaded -support in `include/llvm/Support/thread.h`, and hopefuly that'll be enough... - -For reference, the upstream LLVM bug has been reported [1] - -[1]: https://llvm.org/bugs/show_bug.cgi?id=26365 ---- - include/llvm/Support/ThreadPool.h | 4 + - include/llvm/Support/thread.h | 2 +- - lib/CodeGen/ParallelCG.cpp | 2 + - lib/LTO/LTO.cpp | 6 +- - lib/LTO/LTOBackend.cpp | 2 + - lib/LTO/ThinLTOCodeGenerator.cpp | 6 +- - lib/Support/ThreadPool.cpp | 6 +- - test/CMakeLists.txt | 1 - - tools/lli/CMakeLists.txt | 4 - - tools/lli/ChildTarget/CMakeLists.txt | 13 -- - tools/lli/ChildTarget/ChildTarget.cpp | 67 ------- - tools/lli/ChildTarget/LLVMBuild.txt | 21 --- - tools/lli/LLVMBuild.txt | 3 - - tools/lli/OrcLazyJIT.cpp | 3 +- - tools/lli/OrcLazyJIT.h | 175 ------------------ - tools/lli/RemoteJITUtils.h | 153 ---------------- - tools/lli/lli.cpp | 7 + - tools/llvm-cov/CodeCoverage.cpp | 4 + - tools/llvm-cov/CoverageExporterJson.cpp | 2 + - tools/llvm-cov/CoverageFilters.cpp | 2 + - tools/llvm-cov/CoverageFilters.h | 127 ------------- - tools/llvm-cov/CoverageReport.cpp | 2 + - tools/llvm-cov/CoverageReport.h | 51 ------ - tools/llvm-cov/CoverageSummaryInfo.cpp | 2 + - tools/llvm-cov/CoverageSummaryInfo.h | 165 ----------------- - tools/llvm-cov/CoverageViewOptions.h | 68 ------- - tools/llvm-cov/RenderingSupport.h | 61 ------- - tools/llvm-cov/SourceCoverageView.cpp | 2 + - tools/llvm-cov/SourceCoverageView.h | 289 ------------------------------ - tools/llvm-cov/SourceCoverageViewHTML.cpp | 3 + - tools/llvm-cov/SourceCoverageViewHTML.h | 96 ---------- - tools/llvm-cov/SourceCoverageViewText.cpp | 3 + - tools/llvm-cov/SourceCoverageViewText.h | 89 --------- - tools/llvm-cov/TestingSupport.cpp | 2 + - tools/llvm-cov/gcov.cpp | 2 + - tools/llvm-cov/llvm-cov.cpp | 4 + - tools/llvm-profdata/llvm-profdata.cpp | 5 + - tools/sancov/sancov.cc | 5 + - unittests/Support/ThreadPool.cpp | 4 + - 39 files changed, 73 insertions(+), 1390 deletions(-) - delete mode 100644 tools/lli/ChildTarget/CMakeLists.txt - delete mode 100644 tools/lli/ChildTarget/ChildTarget.cpp - delete mode 100644 tools/lli/ChildTarget/LLVMBuild.txt - delete mode 100644 tools/lli/OrcLazyJIT.h - delete mode 100644 tools/lli/RemoteJITUtils.h - delete mode 100644 tools/llvm-cov/CoverageFilters.h - delete mode 100644 tools/llvm-cov/CoverageReport.h - delete mode 100644 tools/llvm-cov/CoverageSummaryInfo.h - delete mode 100644 tools/llvm-cov/CoverageViewOptions.h - delete mode 100644 tools/llvm-cov/RenderingSupport.h - delete mode 100644 tools/llvm-cov/SourceCoverageView.h - delete mode 100644 tools/llvm-cov/SourceCoverageViewHTML.h - delete mode 100644 tools/llvm-cov/SourceCoverageViewText.h - -diff --git a/include/llvm/Support/ThreadPool.h b/include/llvm/Support/ThreadPool.h -index 665cec2465b..c3aa64de8cc 100644 ---- a/include/llvm/Support/ThreadPool.h -+++ b/include/llvm/Support/ThreadPool.h -@@ -16,6 +16,8 @@ - - #include "llvm/Support/thread.h" - -+# if 0 -+ - #ifdef _MSC_VER - // concrt.h depends on eh.h for __uncaught_exception declaration - // even if we disable exceptions. -@@ -134,4 +136,6 @@ private: - }; - } - -+# endif -+ - #endif // LLVM_SUPPORT_THREAD_POOL_H -diff --git a/include/llvm/Support/thread.h b/include/llvm/Support/thread.h -index 9c45418df55..27d42d23f61 100644 ---- a/include/llvm/Support/thread.h -+++ b/include/llvm/Support/thread.h -@@ -19,7 +19,7 @@ - - #include "llvm/Config/llvm-config.h" - --#if LLVM_ENABLE_THREADS -+#if LLVM_ENABLE_THREADS && 0 - - #ifdef _MSC_VER - // concrt.h depends on eh.h for __uncaught_exception declaration -diff --git a/lib/CodeGen/ParallelCG.cpp b/lib/CodeGen/ParallelCG.cpp -index 50dd44fa659..e91898e0fa7 100644 ---- a/lib/CodeGen/ParallelCG.cpp -+++ b/lib/CodeGen/ParallelCG.cpp -@@ -50,6 +50,7 @@ std::unique_ptr llvm::splitCodeGen( - return M; - } - -+#if 0 - // Create ThreadPool in nested scope so that threads will be joined - // on destruction. - { -@@ -96,5 +97,6 @@ std::unique_ptr llvm::splitCodeGen( - PreserveLocals); - } - -+#endif - return {}; - } -diff --git a/lib/LTO/LTO.cpp b/lib/LTO/LTO.cpp -index e3e2f9f806c..530946c03bb 100644 ---- a/lib/LTO/LTO.cpp -+++ b/lib/LTO/LTO.cpp -@@ -630,7 +630,6 @@ public: - - namespace { - class InProcessThinBackend : public ThinBackendProc { -- ThreadPool BackendThreadPool; - AddStreamFn AddStream; - NativeObjectCache Cache; - -@@ -644,7 +643,6 @@ public: - const StringMap &ModuleToDefinedGVSummaries, - AddStreamFn AddStream, NativeObjectCache Cache) - : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries), -- BackendThreadPool(ThinLTOParallelismLevel), - AddStream(std::move(AddStream)), Cache(std::move(Cache)) {} - - Error runThinLTOBackendThread( -@@ -690,6 +688,7 @@ public: - const FunctionImporter::ExportSetTy &ExportList, - const std::map &ResolvedODR, - MapVector &ModuleMap) override { -+#if 0 - StringRef ModulePath = BM.getModuleIdentifier(); - assert(ModuleToDefinedGVSummaries.count(ModulePath)); - const GVSummaryMapTy &DefinedGlobals = -@@ -716,11 +715,14 @@ public: - BM, std::ref(CombinedIndex), std::ref(ImportList), - std::ref(ExportList), std::ref(ResolvedODR), std::ref(DefinedGlobals), - std::ref(ModuleMap)); -+#endif - return Error::success(); - } - - Error wait() override { -+#if 0 - BackendThreadPool.wait(); -+#endif - if (Err) - return std::move(*Err); - else -diff --git a/lib/LTO/LTOBackend.cpp b/lib/LTO/LTOBackend.cpp -index 809db80bc91..73a355ecf1a 100644 ---- a/lib/LTO/LTOBackend.cpp -+++ b/lib/LTO/LTOBackend.cpp -@@ -216,6 +216,7 @@ void codegen(Config &Conf, TargetMachine *TM, AddStreamFn AddStream, - void splitCodeGen(Config &C, TargetMachine *TM, AddStreamFn AddStream, - unsigned ParallelCodeGenParallelismLevel, - std::unique_ptr Mod) { -+#if 0 - ThreadPool CodegenThreadPool(ParallelCodeGenParallelismLevel); - unsigned ThreadCount = 0; - const Target *T = &TM->getTarget(); -@@ -259,6 +260,7 @@ void splitCodeGen(Config &C, TargetMachine *TM, AddStreamFn AddStream, - // variables, we need to wait for the worker threads to terminate before we - // can leave the function scope. - CodegenThreadPool.wait(); -+#endif - } - - Expected initAndLookupTarget(Config &C, Module &Mod) { -diff --git a/lib/LTO/ThinLTOCodeGenerator.cpp b/lib/LTO/ThinLTOCodeGenerator.cpp -index 40537e4fa78..470e9e57df5 100644 ---- a/lib/LTO/ThinLTOCodeGenerator.cpp -+++ b/lib/LTO/ThinLTOCodeGenerator.cpp -@@ -70,8 +70,8 @@ extern cl::opt LTOPassRemarksWithHotness; - - namespace { - --static cl::opt -- ThreadCount("threads", cl::init(llvm::heavyweight_hardware_concurrency())); -+static cl::opt ThreadCount("threads", -+ cl::init(1)); - - Expected> - setupOptimizationRemarks(LLVMContext &Ctx, int Count) { -@@ -830,6 +830,7 @@ static std::string writeGeneratedObject(int count, StringRef CacheEntryPath, - - // Main entry point for the ThinLTO processing - void ThinLTOCodeGenerator::run() { -+#if 0 - // Prepare the resulting object vector - assert(ProducedBinaries.empty() && "The generator should not be reused"); - if (SavedObjectsDirectoryPath.empty()) -@@ -1052,4 +1053,5 @@ void ThinLTOCodeGenerator::run() { - // If statistics were requested, print them out now. - if (llvm::AreStatisticsEnabled()) - llvm::PrintStatistics(); -+#endif - } -diff --git a/lib/Support/ThreadPool.cpp b/lib/Support/ThreadPool.cpp -index db03a4d6240..71f49330f91 100644 ---- a/lib/Support/ThreadPool.cpp -+++ b/lib/Support/ThreadPool.cpp -@@ -11,6 +11,8 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 -+ - #include "llvm/Support/ThreadPool.h" - - #include "llvm/Config/llvm-config.h" -@@ -18,7 +20,7 @@ - - using namespace llvm; - --#if LLVM_ENABLE_THREADS -+#if LLVM_ENABLE_THREADS && 0 - - // Default to std::thread::hardware_concurrency - ThreadPool::ThreadPool() : ThreadPool(std::thread::hardware_concurrency()) {} -@@ -156,3 +158,5 @@ ThreadPool::~ThreadPool() { - } - - #endif -+ -+#endif -diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt -index c1667049f80..aa7d7f105b2 100644 ---- a/test/CMakeLists.txt -+++ b/test/CMakeLists.txt -@@ -35,7 +35,6 @@ set(LLVM_TEST_DEPENDS - count - llc - lli -- lli-child-target - llvm-ar - llvm-as - llvm-bcanalyzer -diff --git a/tools/lli/CMakeLists.txt b/tools/lli/CMakeLists.txt -index f02e19313b7..ca2e82abcd0 100644 ---- a/tools/lli/CMakeLists.txt -+++ b/tools/lli/CMakeLists.txt -@@ -1,7 +1,3 @@ --if ( LLVM_INCLUDE_UTILS ) -- add_subdirectory(ChildTarget) --endif() -- - set(LLVM_LINK_COMPONENTS - CodeGen - Core -diff --git a/tools/lli/ChildTarget/CMakeLists.txt b/tools/lli/ChildTarget/CMakeLists.txt -deleted file mode 100644 -index f08ce57c295..00000000000 ---- a/tools/lli/ChildTarget/CMakeLists.txt -+++ /dev/null -@@ -1,13 +0,0 @@ --set(LLVM_LINK_COMPONENTS -- OrcJIT -- RuntimeDyld -- Support -- ) -- --add_llvm_utility(lli-child-target -- ChildTarget.cpp -- -- DEPENDS -- intrinsics_gen --) -- -diff --git a/tools/lli/ChildTarget/ChildTarget.cpp b/tools/lli/ChildTarget/ChildTarget.cpp -deleted file mode 100644 -index 77b1d47a946..00000000000 ---- a/tools/lli/ChildTarget/ChildTarget.cpp -+++ /dev/null -@@ -1,67 +0,0 @@ --#include "llvm/ExecutionEngine/Orc/OrcABISupport.h" --#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h" --#include "llvm/Support/Debug.h" --#include "llvm/Support/DynamicLibrary.h" --#include "llvm/Support/Process.h" --#include -- --#include "../RemoteJITUtils.h" -- --using namespace llvm; --using namespace llvm::orc; --using namespace llvm::sys; -- --#ifdef __x86_64__ --typedef OrcX86_64_SysV HostOrcArch; --#else --typedef OrcGenericABI HostOrcArch; --#endif -- --ExitOnError ExitOnErr; -- --int main(int argc, char *argv[]) { -- -- if (argc != 3) { -- errs() << "Usage: " << argv[0] << " \n"; -- return 1; -- } -- -- ExitOnErr.setBanner(std::string(argv[0]) + ":"); -- -- int InFD; -- int OutFD; -- { -- std::istringstream InFDStream(argv[1]), OutFDStream(argv[2]); -- InFDStream >> InFD; -- OutFDStream >> OutFD; -- } -- -- if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) { -- errs() << "Error loading program symbols.\n"; -- return 1; -- } -- -- auto SymbolLookup = [](const std::string &Name) { -- return RTDyldMemoryManager::getSymbolAddressInProcess(Name); -- }; -- -- auto RegisterEHFrames = [](uint8_t *Addr, uint32_t Size) { -- RTDyldMemoryManager::registerEHFramesInProcess(Addr, Size); -- }; -- -- auto DeregisterEHFrames = [](uint8_t *Addr, uint32_t Size) { -- RTDyldMemoryManager::deregisterEHFramesInProcess(Addr, Size); -- }; -- -- FDRawChannel Channel(InFD, OutFD); -- typedef remote::OrcRemoteTargetServer JITServer; -- JITServer Server(Channel, SymbolLookup, RegisterEHFrames, DeregisterEHFrames); -- -- while (!Server.receivedTerminate()) -- ExitOnErr(Server.handleOne()); -- -- close(InFD); -- close(OutFD); -- -- return 0; --} -diff --git a/tools/lli/ChildTarget/LLVMBuild.txt b/tools/lli/ChildTarget/LLVMBuild.txt -deleted file mode 100644 -index daf6df11324..00000000000 ---- a/tools/lli/ChildTarget/LLVMBuild.txt -+++ /dev/null -@@ -1,21 +0,0 @@ --;===- ./tools/lli/ChildTarget/LLVMBuild.txt --------------------*- Conf -*--===; --; --; The LLVM Compiler Infrastructure --; --; This file is distributed under the University of Illinois Open Source --; License. See LICENSE.TXT for details. --; --;===------------------------------------------------------------------------===; --; --; This is an LLVMBuild description file for the components in this subdirectory. --; --; For more information on the LLVMBuild system, please see: --; --; http://llvm.org/docs/LLVMBuild.html --; --;===------------------------------------------------------------------------===; -- --[component_0] --type = Tool --name = lli-child-target --parent = lli -diff --git a/tools/lli/LLVMBuild.txt b/tools/lli/LLVMBuild.txt -index 9d889bf4c2e..47385048e08 100644 ---- a/tools/lli/LLVMBuild.txt -+++ b/tools/lli/LLVMBuild.txt -@@ -15,9 +15,6 @@ - ; - ;===------------------------------------------------------------------------===; - --[common] --subdirectories = ChildTarget -- - [component_0] - type = Tool - name = lli -diff --git a/tools/lli/OrcLazyJIT.cpp b/tools/lli/OrcLazyJIT.cpp -index ec61ce5e154..640cfd9b6ef 100644 ---- a/tools/lli/OrcLazyJIT.cpp -+++ b/tools/lli/OrcLazyJIT.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===------ OrcLazyJIT.cpp - Basic Orc-based JIT for lazy execution -------===// - // - // The LLVM Compiler Infrastructure -@@ -158,4 +159,4 @@ int llvm::runOrcLazyJIT(std::vector> Ms, - auto Main = fromTargetAddress(MainSym.getAddress()); - return Main(ArgV.size(), (const char**)ArgV.data()); - } -- -+#endif -diff --git a/tools/lli/OrcLazyJIT.h b/tools/lli/OrcLazyJIT.h -deleted file mode 100644 -index 05319c34548..00000000000 ---- a/tools/lli/OrcLazyJIT.h -+++ /dev/null -@@ -1,175 +0,0 @@ --//===--- OrcLazyJIT.h - Basic Orc-based JIT for lazy execution --*- C++ -*-===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// Simple Orc-based JIT. Uses the compile-on-demand layer to break up and --// lazily compile modules. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_TOOLS_LLI_ORCLAZYJIT_H --#define LLVM_TOOLS_LLI_ORCLAZYJIT_H -- --#include "llvm/ADT/Triple.h" --#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" --#include "llvm/ExecutionEngine/Orc/CompileUtils.h" --#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" --#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" --#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" --#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" --#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" -- --namespace llvm { -- --class OrcLazyJIT { --public: -- -- typedef orc::JITCompileCallbackManager CompileCallbackMgr; -- typedef orc::ObjectLinkingLayer<> ObjLayerT; -- typedef orc::IRCompileLayer CompileLayerT; -- typedef std::function(std::unique_ptr)> -- TransformFtor; -- typedef orc::IRTransformLayer IRDumpLayerT; -- typedef orc::CompileOnDemandLayer CODLayerT; -- typedef CODLayerT::IndirectStubsManagerBuilderT -- IndirectStubsManagerBuilder; -- typedef CODLayerT::ModuleSetHandleT ModuleSetHandleT; -- -- OrcLazyJIT(std::unique_ptr TM, -- std::unique_ptr CCMgr, -- IndirectStubsManagerBuilder IndirectStubsMgrBuilder, -- bool InlineStubs) -- : TM(std::move(TM)), DL(this->TM->createDataLayout()), -- CCMgr(std::move(CCMgr)), -- ObjectLayer(), -- CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)), -- IRDumpLayer(CompileLayer, createDebugDumper()), -- CODLayer(IRDumpLayer, extractSingleFunction, *this->CCMgr, -- std::move(IndirectStubsMgrBuilder), InlineStubs), -- CXXRuntimeOverrides( -- [this](const std::string &S) { return mangle(S); }) {} -- -- ~OrcLazyJIT() { -- // Run any destructors registered with __cxa_atexit. -- CXXRuntimeOverrides.runDestructors(); -- // Run any IR destructors. -- for (auto &DtorRunner : IRStaticDestructorRunners) -- DtorRunner.runViaLayer(CODLayer); -- } -- -- ModuleSetHandleT addModuleSet(std::vector> Ms) { -- // Attach a data-layouts if they aren't already present. -- for (auto &M : Ms) -- if (M->getDataLayout().isDefault()) -- M->setDataLayout(DL); -- -- // Rename, bump linkage and record static constructors and destructors. -- // We have to do this before we hand over ownership of the module to the -- // JIT. -- std::vector CtorNames, DtorNames; -- { -- unsigned CtorId = 0, DtorId = 0; -- for (auto &M : Ms) { -- for (auto Ctor : orc::getConstructors(*M)) { -- std::string NewCtorName = ("$static_ctor." + Twine(CtorId++)).str(); -- Ctor.Func->setName(NewCtorName); -- Ctor.Func->setLinkage(GlobalValue::ExternalLinkage); -- Ctor.Func->setVisibility(GlobalValue::HiddenVisibility); -- CtorNames.push_back(mangle(NewCtorName)); -- } -- for (auto Dtor : orc::getDestructors(*M)) { -- std::string NewDtorName = ("$static_dtor." + Twine(DtorId++)).str(); -- Dtor.Func->setLinkage(GlobalValue::ExternalLinkage); -- Dtor.Func->setVisibility(GlobalValue::HiddenVisibility); -- DtorNames.push_back(mangle(Dtor.Func->getName())); -- Dtor.Func->setName(NewDtorName); -- } -- } -- } -- -- // Symbol resolution order: -- // 1) Search the JIT symbols. -- // 2) Check for C++ runtime overrides. -- // 3) Search the host process (LLI)'s symbol table. -- auto Resolver = -- orc::createLambdaResolver( -- [this](const std::string &Name) -> JITSymbol { -- if (auto Sym = CODLayer.findSymbol(Name, true)) -- return Sym; -- return CXXRuntimeOverrides.searchOverrides(Name); -- }, -- [](const std::string &Name) { -- if (auto Addr = -- RTDyldMemoryManager::getSymbolAddressInProcess(Name)) -- return JITSymbol(Addr, JITSymbolFlags::Exported); -- return JITSymbol(nullptr); -- } -- ); -- -- // Add the module to the JIT. -- auto H = CODLayer.addModuleSet(std::move(Ms), -- llvm::make_unique(), -- std::move(Resolver)); -- -- // Run the static constructors, and save the static destructor runner for -- // execution when the JIT is torn down. -- orc::CtorDtorRunner CtorRunner(std::move(CtorNames), H); -- CtorRunner.runViaLayer(CODLayer); -- -- IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H); -- -- return H; -- } -- -- JITSymbol findSymbol(const std::string &Name) { -- return CODLayer.findSymbol(mangle(Name), true); -- } -- -- JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name) { -- return CODLayer.findSymbolIn(H, mangle(Name), true); -- } -- --private: -- -- std::string mangle(const std::string &Name) { -- std::string MangledName; -- { -- raw_string_ostream MangledNameStream(MangledName); -- Mangler::getNameWithPrefix(MangledNameStream, Name, DL); -- } -- return MangledName; -- } -- -- static std::set extractSingleFunction(Function &F) { -- std::set Partition; -- Partition.insert(&F); -- return Partition; -- } -- -- static TransformFtor createDebugDumper(); -- -- std::unique_ptr TM; -- DataLayout DL; -- SectionMemoryManager CCMgrMemMgr; -- -- std::unique_ptr CCMgr; -- ObjLayerT ObjectLayer; -- CompileLayerT CompileLayer; -- IRDumpLayerT IRDumpLayer; -- CODLayerT CODLayer; -- -- orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides; -- std::vector> IRStaticDestructorRunners; --}; -- --int runOrcLazyJIT(std::vector> Ms, -- const std::vector &Args); -- --} // end namespace llvm -- --#endif -diff --git a/tools/lli/RemoteJITUtils.h b/tools/lli/RemoteJITUtils.h -deleted file mode 100644 -index 89a51420256..00000000000 ---- a/tools/lli/RemoteJITUtils.h -+++ /dev/null -@@ -1,153 +0,0 @@ --//===-- RemoteJITUtils.h - Utilities for remote-JITing with LLI -*- C++ -*-===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// Utilities for remote-JITing with LLI. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_TOOLS_LLI_REMOTEJITUTILS_H --#define LLVM_TOOLS_LLI_REMOTEJITUTILS_H -- --#include "llvm/ExecutionEngine/Orc/RawByteChannel.h" --#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" --#include -- --#if !defined(_MSC_VER) && !defined(__MINGW32__) --#include --#else --#include --#endif -- --/// RPC channel that reads from and writes from file descriptors. --class FDRawChannel final : public llvm::orc::rpc::RawByteChannel { --public: -- FDRawChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {} -- -- llvm::Error readBytes(char *Dst, unsigned Size) override { -- assert(Dst && "Attempt to read into null."); -- ssize_t Completed = 0; -- while (Completed < static_cast(Size)) { -- ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed); -- if (Read <= 0) { -- auto ErrNo = errno; -- if (ErrNo == EAGAIN || ErrNo == EINTR) -- continue; -- else -- return llvm::errorCodeToError( -- std::error_code(errno, std::generic_category())); -- } -- Completed += Read; -- } -- return llvm::Error::success(); -- } -- -- llvm::Error appendBytes(const char *Src, unsigned Size) override { -- assert(Src && "Attempt to append from null."); -- ssize_t Completed = 0; -- while (Completed < static_cast(Size)) { -- ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed); -- if (Written < 0) { -- auto ErrNo = errno; -- if (ErrNo == EAGAIN || ErrNo == EINTR) -- continue; -- else -- return llvm::errorCodeToError( -- std::error_code(errno, std::generic_category())); -- } -- Completed += Written; -- } -- return llvm::Error::success(); -- } -- -- llvm::Error send() override { return llvm::Error::success(); } -- --private: -- int InFD, OutFD; --}; -- --// launch the remote process (see lli.cpp) and return a channel to it. --std::unique_ptr launchRemote(); -- --namespace llvm { -- --// ForwardingMM - Adapter to connect MCJIT to Orc's Remote8 --// memory manager. --class ForwardingMemoryManager : public llvm::RTDyldMemoryManager { --public: -- void setMemMgr(std::unique_ptr MemMgr) { -- this->MemMgr = std::move(MemMgr); -- } -- -- void setResolver(std::unique_ptr Resolver) { -- this->Resolver = std::move(Resolver); -- } -- -- uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, -- unsigned SectionID, -- StringRef SectionName) override { -- return MemMgr->allocateCodeSection(Size, Alignment, SectionID, SectionName); -- } -- -- uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, -- unsigned SectionID, StringRef SectionName, -- bool IsReadOnly) override { -- return MemMgr->allocateDataSection(Size, Alignment, SectionID, SectionName, -- IsReadOnly); -- } -- -- void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, -- uintptr_t RODataSize, uint32_t RODataAlign, -- uintptr_t RWDataSize, -- uint32_t RWDataAlign) override { -- MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign, -- RWDataSize, RWDataAlign); -- } -- -- bool needsToReserveAllocationSpace() override { -- return MemMgr->needsToReserveAllocationSpace(); -- } -- -- void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, -- size_t Size) override { -- MemMgr->registerEHFrames(Addr, LoadAddr, Size); -- } -- -- void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, -- size_t Size) override { -- MemMgr->deregisterEHFrames(Addr, LoadAddr, Size); -- } -- -- bool finalizeMemory(std::string *ErrMsg = nullptr) override { -- return MemMgr->finalizeMemory(ErrMsg); -- } -- -- void notifyObjectLoaded(RuntimeDyld &RTDyld, -- const object::ObjectFile &Obj) override { -- MemMgr->notifyObjectLoaded(RTDyld, Obj); -- } -- -- // Don't hide the sibling notifyObjectLoaded from RTDyldMemoryManager. -- using RTDyldMemoryManager::notifyObjectLoaded; -- -- JITSymbol findSymbol(const std::string &Name) override { -- return Resolver->findSymbol(Name); -- } -- -- JITSymbol -- findSymbolInLogicalDylib(const std::string &Name) override { -- return Resolver->findSymbolInLogicalDylib(Name); -- } -- --private: -- std::unique_ptr MemMgr; -- std::unique_ptr Resolver; --}; --} -- --#endif -diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp -index 0823ff469de..8e9b9f87577 100644 ---- a/tools/lli/lli.cpp -+++ b/tools/lli/lli.cpp -@@ -13,6 +13,8 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 -+ - #include "OrcLazyJIT.h" - #include "RemoteJITUtils.h" - #include "llvm/IR/LLVMContext.h" -@@ -758,3 +760,8 @@ std::unique_ptr launchRemote() { - return llvm::make_unique(PipeFD[1][0], PipeFD[0][1]); - #endif - } -+#endif -+ -+int main(int argc, char **argv, char * const *envp) { -+ return 0; -+} -diff --git a/tools/llvm-cov/CodeCoverage.cpp b/tools/llvm-cov/CodeCoverage.cpp -index 0a9807ab003..0b7ffd366b9 100644 ---- a/tools/llvm-cov/CodeCoverage.cpp -+++ b/tools/llvm-cov/CodeCoverage.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- CodeCoverage.cpp - Coverage tool based on profiling instrumentation-===// - // - // The LLVM Compiler Infrastructure -@@ -864,7 +865,10 @@ int reportMain(int argc, const char *argv[]) { - return Tool.run(CodeCoverageTool::Report, argc, argv); - } - -+ - int exportMain(int argc, const char *argv[]) { - CodeCoverageTool Tool; - return Tool.run(CodeCoverageTool::Export, argc, argv); - } -+ -+#endif -diff --git a/tools/llvm-cov/CoverageExporterJson.cpp b/tools/llvm-cov/CoverageExporterJson.cpp -index ef50bba2123..d3d0a8f5f01 100644 ---- a/tools/llvm-cov/CoverageExporterJson.cpp -+++ b/tools/llvm-cov/CoverageExporterJson.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- CoverageExporterJson.cpp - Code coverage export --------------------===// - // - // The LLVM Compiler Infrastructure -@@ -419,3 +420,4 @@ void exportCoverageDataToJson(const CoverageMapping &CoverageMapping, - - Exporter.print(); - } -+#endif -diff --git a/tools/llvm-cov/CoverageFilters.cpp b/tools/llvm-cov/CoverageFilters.cpp -index 325dd723578..8a41ba8c1d8 100644 ---- a/tools/llvm-cov/CoverageFilters.cpp -+++ b/tools/llvm-cov/CoverageFilters.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- CoverageFilters.cpp - Function coverage mapping filters ------------===// - // - // The LLVM Compiler Infrastructure -@@ -57,3 +58,4 @@ CoverageFiltersMatchAll::matches(const coverage::FunctionRecord &Function) { - } - return true; - } -+#endif -diff --git a/tools/llvm-cov/CoverageFilters.h b/tools/llvm-cov/CoverageFilters.h -deleted file mode 100644 -index 756c4b47872..00000000000 ---- a/tools/llvm-cov/CoverageFilters.h -+++ /dev/null -@@ -1,127 +0,0 @@ --//===- CoverageFilters.h - Function coverage mapping filters --------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// These classes provide filtering for function coverage mapping records. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGEFILTERS_H --#define LLVM_COV_COVERAGEFILTERS_H -- --#include "llvm/ProfileData/Coverage/CoverageMapping.h" --#include --#include -- --namespace llvm { -- --/// \brief Matches specific functions that pass the requirement of this filter. --class CoverageFilter { --public: -- virtual ~CoverageFilter() {} -- -- /// \brief Return true if the function passes the requirements of this filter. -- virtual bool matches(const coverage::FunctionRecord &Function) { -- return true; -- } --}; -- --/// \brief Matches functions that contain a specific string in their name. --class NameCoverageFilter : public CoverageFilter { -- StringRef Name; -- --public: -- NameCoverageFilter(StringRef Name) : Name(Name) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief Matches functions whose name matches a certain regular expression. --class NameRegexCoverageFilter : public CoverageFilter { -- StringRef Regex; -- --public: -- NameRegexCoverageFilter(StringRef Regex) : Regex(Regex) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief Matches numbers that pass a certain threshold. --template class StatisticThresholdFilter { --public: -- enum Operation { LessThan, GreaterThan }; -- --protected: -- Operation Op; -- T Threshold; -- -- StatisticThresholdFilter(Operation Op, T Threshold) -- : Op(Op), Threshold(Threshold) {} -- -- /// \brief Return true if the given number is less than -- /// or greater than the certain threshold. -- bool PassesThreshold(T Value) const { -- switch (Op) { -- case LessThan: -- return Value < Threshold; -- case GreaterThan: -- return Value > Threshold; -- } -- return false; -- } --}; -- --/// \brief Matches functions whose region coverage percentage --/// is above/below a certain percentage. --class RegionCoverageFilter : public CoverageFilter, -- public StatisticThresholdFilter { --public: -- RegionCoverageFilter(Operation Op, double Threshold) -- : StatisticThresholdFilter(Op, Threshold) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief Matches functions whose line coverage percentage --/// is above/below a certain percentage. --class LineCoverageFilter : public CoverageFilter, -- public StatisticThresholdFilter { --public: -- LineCoverageFilter(Operation Op, double Threshold) -- : StatisticThresholdFilter(Op, Threshold) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief A collection of filters. --/// Matches functions that match any filters contained --/// in an instance of this class. --class CoverageFilters : public CoverageFilter { --protected: -- std::vector> Filters; -- --public: -- /// \brief Append a filter to this collection. -- void push_back(std::unique_ptr Filter); -- -- bool empty() const { return Filters.empty(); } -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief A collection of filters. --/// Matches functions that match all of the filters contained --/// in an instance of this class. --class CoverageFiltersMatchAll : public CoverageFilters { --public: -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --} // namespace llvm -- --#endif // LLVM_COV_COVERAGEFILTERS_H -diff --git a/tools/llvm-cov/CoverageReport.cpp b/tools/llvm-cov/CoverageReport.cpp -index e88cb186acd..67fdaa6f57e 100644 ---- a/tools/llvm-cov/CoverageReport.cpp -+++ b/tools/llvm-cov/CoverageReport.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- CoverageReport.cpp - Code coverage report -------------------------===// - // - // The LLVM Compiler Infrastructure -@@ -353,3 +354,4 @@ void CoverageReport::renderFileReports(raw_ostream &OS, - } - - } // end namespace llvm -+#endif -diff --git a/tools/llvm-cov/CoverageReport.h b/tools/llvm-cov/CoverageReport.h -deleted file mode 100644 -index 7a416497e25..00000000000 ---- a/tools/llvm-cov/CoverageReport.h -+++ /dev/null -@@ -1,51 +0,0 @@ --//===- CoverageReport.h - Code coverage report ---------------------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// This class implements rendering of a code coverage report. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGEREPORT_H --#define LLVM_COV_COVERAGEREPORT_H -- --#include "CoverageSummaryInfo.h" --#include "CoverageViewOptions.h" -- --namespace llvm { -- --/// \brief Displays the code coverage report. --class CoverageReport { -- const CoverageViewOptions &Options; -- const coverage::CoverageMapping &Coverage; -- -- void render(const FileCoverageSummary &File, raw_ostream &OS) const; -- void render(const FunctionCoverageSummary &Function, raw_ostream &OS) const; -- --public: -- CoverageReport(const CoverageViewOptions &Options, -- const coverage::CoverageMapping &Coverage) -- : Options(Options), Coverage(Coverage) {} -- -- void renderFunctionReports(ArrayRef Files, raw_ostream &OS); -- -- /// Prepare file reports for the files specified in \p Files. -- static std::vector -- prepareFileReports(const coverage::CoverageMapping &Coverage, -- FileCoverageSummary &Totals, ArrayRef Files); -- -- /// Render file reports for every unique file in the coverage mapping. -- void renderFileReports(raw_ostream &OS) const; -- -- /// Render file reports for the files specified in \p Files. -- void renderFileReports(raw_ostream &OS, ArrayRef Files) const; --}; -- --} // end namespace llvm -- --#endif // LLVM_COV_COVERAGEREPORT_H -diff --git a/tools/llvm-cov/CoverageSummaryInfo.cpp b/tools/llvm-cov/CoverageSummaryInfo.cpp -index 21aa7ff73a0..5a325b40cf8 100644 ---- a/tools/llvm-cov/CoverageSummaryInfo.cpp -+++ b/tools/llvm-cov/CoverageSummaryInfo.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- CoverageSummaryInfo.cpp - Coverage summary for function/file -------===// - // - // The LLVM Compiler Infrastructure -@@ -81,3 +82,4 @@ void FunctionCoverageSummary::update(const FunctionCoverageSummary &Summary) { - LineCoverage.NotCovered = - std::min(LineCoverage.NotCovered, Summary.LineCoverage.NotCovered); - } -+#endif -diff --git a/tools/llvm-cov/CoverageSummaryInfo.h b/tools/llvm-cov/CoverageSummaryInfo.h -deleted file mode 100644 -index c04a4d42ccd..00000000000 ---- a/tools/llvm-cov/CoverageSummaryInfo.h -+++ /dev/null -@@ -1,165 +0,0 @@ --//===- CoverageSummaryInfo.h - Coverage summary for function/file ---------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// These structures are used to represent code coverage metrics --// for functions/files. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGESUMMARYINFO_H --#define LLVM_COV_COVERAGESUMMARYINFO_H -- --#include "llvm/ProfileData/Coverage/CoverageMapping.h" --#include "llvm/Support/raw_ostream.h" -- --namespace llvm { -- --/// \brief Provides information about region coverage for a function/file. --struct RegionCoverageInfo { -- /// \brief The number of regions that were executed at least once. -- size_t Covered; -- -- /// \brief The number of regions that weren't executed. -- size_t NotCovered; -- -- /// \brief The total number of regions in a function/file. -- size_t NumRegions; -- -- RegionCoverageInfo() : Covered(0), NotCovered(0), NumRegions(0) {} -- -- RegionCoverageInfo(size_t Covered, size_t NumRegions) -- : Covered(Covered), NotCovered(NumRegions - Covered), -- NumRegions(NumRegions) {} -- -- RegionCoverageInfo &operator+=(const RegionCoverageInfo &RHS) { -- Covered += RHS.Covered; -- NotCovered += RHS.NotCovered; -- NumRegions += RHS.NumRegions; -- return *this; -- } -- -- bool isFullyCovered() const { return Covered == NumRegions; } -- -- double getPercentCovered() const { -- if (NumRegions == 0) -- return 0.0; -- return double(Covered) / double(NumRegions) * 100.0; -- } --}; -- --/// \brief Provides information about line coverage for a function/file. --struct LineCoverageInfo { -- /// \brief The number of lines that were executed at least once. -- size_t Covered; -- -- /// \brief The number of lines that weren't executed. -- size_t NotCovered; -- -- /// \brief The total number of lines in a function/file. -- size_t NumLines; -- -- LineCoverageInfo() : Covered(0), NotCovered(0), NumLines(0) {} -- -- LineCoverageInfo(size_t Covered, size_t NumLines) -- : Covered(Covered), NotCovered(NumLines - Covered), NumLines(NumLines) {} -- -- LineCoverageInfo &operator+=(const LineCoverageInfo &RHS) { -- Covered += RHS.Covered; -- NotCovered += RHS.NotCovered; -- NumLines += RHS.NumLines; -- return *this; -- } -- -- bool isFullyCovered() const { return Covered == NumLines; } -- -- double getPercentCovered() const { -- if (NumLines == 0) -- return 0.0; -- return double(Covered) / double(NumLines) * 100.0; -- } --}; -- --/// \brief Provides information about function coverage for a file. --struct FunctionCoverageInfo { -- /// \brief The number of functions that were executed. -- size_t Executed; -- -- /// \brief The total number of functions in this file. -- size_t NumFunctions; -- -- FunctionCoverageInfo() : Executed(0), NumFunctions(0) {} -- -- FunctionCoverageInfo(size_t Executed, size_t NumFunctions) -- : Executed(Executed), NumFunctions(NumFunctions) {} -- -- void addFunction(bool Covered) { -- if (Covered) -- ++Executed; -- ++NumFunctions; -- } -- -- bool isFullyCovered() const { return Executed == NumFunctions; } -- -- double getPercentCovered() const { -- if (NumFunctions == 0) -- return 0.0; -- return double(Executed) / double(NumFunctions) * 100.0; -- } --}; -- --/// \brief A summary of function's code coverage. --struct FunctionCoverageSummary { -- StringRef Name; -- uint64_t ExecutionCount; -- RegionCoverageInfo RegionCoverage; -- LineCoverageInfo LineCoverage; -- -- FunctionCoverageSummary(StringRef Name) : Name(Name), ExecutionCount(0) {} -- -- FunctionCoverageSummary(StringRef Name, uint64_t ExecutionCount, -- const RegionCoverageInfo &RegionCoverage, -- const LineCoverageInfo &LineCoverage) -- : Name(Name), ExecutionCount(ExecutionCount), -- RegionCoverage(RegionCoverage), LineCoverage(LineCoverage) { -- } -- -- /// \brief Compute the code coverage summary for the given function coverage -- /// mapping record. -- static FunctionCoverageSummary -- get(const coverage::FunctionRecord &Function); -- -- /// \brief Update the summary with information from another instantiation -- /// of this function. -- void update(const FunctionCoverageSummary &Summary); --}; -- --/// \brief A summary of file's code coverage. --struct FileCoverageSummary { -- StringRef Name; -- RegionCoverageInfo RegionCoverage; -- LineCoverageInfo LineCoverage; -- FunctionCoverageInfo FunctionCoverage; -- FunctionCoverageInfo InstantiationCoverage; -- -- FileCoverageSummary(StringRef Name) : Name(Name) {} -- -- void addFunction(const FunctionCoverageSummary &Function) { -- RegionCoverage += Function.RegionCoverage; -- LineCoverage += Function.LineCoverage; -- FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); -- } -- -- void addInstantiation(const FunctionCoverageSummary &Function) { -- InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); -- } --}; -- --} // namespace llvm -- --#endif // LLVM_COV_COVERAGESUMMARYINFO_H -diff --git a/tools/llvm-cov/CoverageViewOptions.h b/tools/llvm-cov/CoverageViewOptions.h -deleted file mode 100644 -index 266b380b7d3..00000000000 ---- a/tools/llvm-cov/CoverageViewOptions.h -+++ /dev/null -@@ -1,68 +0,0 @@ --//===- CoverageViewOptions.h - Code coverage display options -------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGEVIEWOPTIONS_H --#define LLVM_COV_COVERAGEVIEWOPTIONS_H -- --#include "RenderingSupport.h" --#include -- --namespace llvm { -- --/// \brief The options for displaying the code coverage information. --struct CoverageViewOptions { -- enum class OutputFormat { -- Text, -- HTML -- }; -- -- bool Debug; -- bool Colors; -- bool ShowLineNumbers; -- bool ShowLineStats; -- bool ShowRegionMarkers; -- bool ShowLineStatsOrRegionMarkers; -- bool ShowExpandedRegions; -- bool ShowFunctionInstantiations; -- bool ShowFullFilenames; -- OutputFormat Format; -- std::string ShowOutputDirectory; -- std::vector DemanglerOpts; -- uint32_t TabSize; -- std::string ProjectTitle; -- std::string CreatedTimeStr; -- -- /// \brief Change the output's stream color if the colors are enabled. -- ColoredRawOstream colored_ostream(raw_ostream &OS, -- raw_ostream::Colors Color) const { -- return llvm::colored_ostream(OS, Color, Colors); -- } -- -- /// \brief Check if an output directory has been specified. -- bool hasOutputDirectory() const { return !ShowOutputDirectory.empty(); } -- -- /// \brief Check if a demangler has been specified. -- bool hasDemangler() const { return !DemanglerOpts.empty(); } -- -- /// \brief Check if a project title has been specified. -- bool hasProjectTitle() const { return !ProjectTitle.empty(); } -- -- /// \brief Check if the created time of the profile data file is available. -- bool hasCreatedTime() const { return !CreatedTimeStr.empty(); } -- -- /// \brief Get the LLVM version string. -- std::string getLLVMVersionString() const { -- std::string VersionString = "Generated by llvm-cov -- llvm version "; -- VersionString += LLVM_VERSION_STRING; -- return VersionString; -- } --}; --} -- --#endif // LLVM_COV_COVERAGEVIEWOPTIONS_H -diff --git a/tools/llvm-cov/RenderingSupport.h b/tools/llvm-cov/RenderingSupport.h -deleted file mode 100644 -index aa70fbc23e3..00000000000 ---- a/tools/llvm-cov/RenderingSupport.h -+++ /dev/null -@@ -1,61 +0,0 @@ --//===- RenderingSupport.h - output stream rendering support functions ----===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_RENDERINGSUPPORT_H --#define LLVM_COV_RENDERINGSUPPORT_H -- --#include "llvm/Support/raw_ostream.h" --#include -- --namespace llvm { -- --/// \brief A helper class that resets the output stream's color if needed --/// when destroyed. --class ColoredRawOstream { -- ColoredRawOstream(const ColoredRawOstream &OS) = delete; -- --public: -- raw_ostream &OS; -- bool IsColorUsed; -- -- ColoredRawOstream(raw_ostream &OS, bool IsColorUsed) -- : OS(OS), IsColorUsed(IsColorUsed) {} -- -- ColoredRawOstream(ColoredRawOstream &&Other) -- : OS(Other.OS), IsColorUsed(Other.IsColorUsed) { -- // Reset the other IsColorUsed so that the other object won't reset the -- // color when destroyed. -- Other.IsColorUsed = false; -- } -- -- ~ColoredRawOstream() { -- if (IsColorUsed) -- OS.resetColor(); -- } --}; -- --template --inline raw_ostream &operator<<(const ColoredRawOstream &OS, T &&Value) { -- return OS.OS << std::forward(Value); --} -- --/// \brief Change the color of the output stream if the `IsColorUsed` flag --/// is true. Returns an object that resets the color when destroyed. --inline ColoredRawOstream colored_ostream(raw_ostream &OS, -- raw_ostream::Colors Color, -- bool IsColorUsed = true, -- bool Bold = false, bool BG = false) { -- if (IsColorUsed) -- OS.changeColor(Color, Bold, BG); -- return ColoredRawOstream(OS, IsColorUsed); --} -- --} // namespace llvm -- --#endif // LLVM_COV_RENDERINGSUPPORT_H -diff --git a/tools/llvm-cov/SourceCoverageView.cpp b/tools/llvm-cov/SourceCoverageView.cpp -index 52b8ff1747f..84c2cb7e8d6 100644 ---- a/tools/llvm-cov/SourceCoverageView.cpp -+++ b/tools/llvm-cov/SourceCoverageView.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- SourceCoverageView.cpp - Code coverage view for source code --------===// - // - // The LLVM Compiler Infrastructure -@@ -265,3 +266,4 @@ void SourceCoverageView::print(raw_ostream &OS, bool WholeFile, - - renderViewFooter(OS); - } -+#endif -diff --git a/tools/llvm-cov/SourceCoverageView.h b/tools/llvm-cov/SourceCoverageView.h -deleted file mode 100644 -index 9cb608fed60..00000000000 ---- a/tools/llvm-cov/SourceCoverageView.h -+++ /dev/null -@@ -1,289 +0,0 @@ --//===- SourceCoverageView.h - Code coverage view for source code ----------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This class implements rendering for code coverage of source code. --/// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_SOURCECOVERAGEVIEW_H --#define LLVM_COV_SOURCECOVERAGEVIEW_H -- --#include "CoverageViewOptions.h" --#include "llvm/ProfileData/Coverage/CoverageMapping.h" --#include "llvm/Support/MemoryBuffer.h" --#include -- --namespace llvm { -- --class SourceCoverageView; -- --/// \brief A view that represents a macro or include expansion. --struct ExpansionView { -- coverage::CounterMappingRegion Region; -- std::unique_ptr View; -- -- ExpansionView(const coverage::CounterMappingRegion &Region, -- std::unique_ptr View) -- : Region(Region), View(std::move(View)) {} -- ExpansionView(ExpansionView &&RHS) -- : Region(std::move(RHS.Region)), View(std::move(RHS.View)) {} -- ExpansionView &operator=(ExpansionView &&RHS) { -- Region = std::move(RHS.Region); -- View = std::move(RHS.View); -- return *this; -- } -- -- unsigned getLine() const { return Region.LineStart; } -- unsigned getStartCol() const { return Region.ColumnStart; } -- unsigned getEndCol() const { return Region.ColumnEnd; } -- -- friend bool operator<(const ExpansionView &LHS, const ExpansionView &RHS) { -- return LHS.Region.startLoc() < RHS.Region.startLoc(); -- } --}; -- --/// \brief A view that represents a function instantiation. --struct InstantiationView { -- StringRef FunctionName; -- unsigned Line; -- std::unique_ptr View; -- -- InstantiationView(StringRef FunctionName, unsigned Line, -- std::unique_ptr View) -- : FunctionName(FunctionName), Line(Line), View(std::move(View)) {} -- -- friend bool operator<(const InstantiationView &LHS, -- const InstantiationView &RHS) { -- return LHS.Line < RHS.Line; -- } --}; -- --/// \brief Coverage statistics for a single line. --struct LineCoverageStats { -- uint64_t ExecutionCount; -- unsigned RegionCount; -- bool Mapped; -- -- LineCoverageStats() : ExecutionCount(0), RegionCount(0), Mapped(false) {} -- -- bool isMapped() const { return Mapped; } -- -- bool hasMultipleRegions() const { return RegionCount > 1; } -- -- void addRegionStartCount(uint64_t Count) { -- // The max of all region starts is the most interesting value. -- addRegionCount(RegionCount ? std::max(ExecutionCount, Count) : Count); -- ++RegionCount; -- } -- -- void addRegionCount(uint64_t Count) { -- Mapped = true; -- ExecutionCount = Count; -- } --}; -- --/// \brief A file manager that handles format-aware file creation. --class CoveragePrinter { --public: -- struct StreamDestructor { -- void operator()(raw_ostream *OS) const; -- }; -- -- using OwnedStream = std::unique_ptr; -- --protected: -- const CoverageViewOptions &Opts; -- -- CoveragePrinter(const CoverageViewOptions &Opts) : Opts(Opts) {} -- -- /// \brief Return `OutputDir/ToplevelDir/Path.Extension`. If \p InToplevel is -- /// false, skip the ToplevelDir component. If \p Relative is false, skip the -- /// OutputDir component. -- std::string getOutputPath(StringRef Path, StringRef Extension, -- bool InToplevel, bool Relative = true) const; -- -- /// \brief If directory output is enabled, create a file in that directory -- /// at the path given by getOutputPath(). Otherwise, return stdout. -- Expected createOutputStream(StringRef Path, StringRef Extension, -- bool InToplevel) const; -- -- /// \brief Return the sub-directory name for file coverage reports. -- static StringRef getCoverageDir() { return "coverage"; } -- --public: -- static std::unique_ptr -- create(const CoverageViewOptions &Opts); -- -- virtual ~CoveragePrinter() {} -- -- /// @name File Creation Interface -- /// @{ -- -- /// \brief Create a file to print a coverage view into. -- virtual Expected createViewFile(StringRef Path, -- bool InToplevel) = 0; -- -- /// \brief Close a file which has been used to print a coverage view. -- virtual void closeViewFile(OwnedStream OS) = 0; -- -- /// \brief Create an index which lists reports for the given source files. -- virtual Error createIndexFile(ArrayRef SourceFiles, -- const coverage::CoverageMapping &Coverage) = 0; -- -- /// @} --}; -- --/// \brief A code coverage view of a source file or function. --/// --/// A source coverage view and its nested sub-views form a file-oriented --/// representation of code coverage data. This view can be printed out by a --/// renderer which implements the Rendering Interface. --class SourceCoverageView { -- /// A function or file name. -- StringRef SourceName; -- -- /// A memory buffer backing the source on display. -- const MemoryBuffer &File; -- -- /// Various options to guide the coverage renderer. -- const CoverageViewOptions &Options; -- -- /// Complete coverage information about the source on display. -- coverage::CoverageData CoverageInfo; -- -- /// A container for all expansions (e.g macros) in the source on display. -- std::vector ExpansionSubViews; -- -- /// A container for all instantiations (e.g template functions) in the source -- /// on display. -- std::vector InstantiationSubViews; -- -- /// Get the first uncovered line number for the source file. -- unsigned getFirstUncoveredLineNo(); -- --protected: -- struct LineRef { -- StringRef Line; -- int64_t LineNo; -- -- LineRef(StringRef Line, int64_t LineNo) : Line(Line), LineNo(LineNo) {} -- }; -- -- using CoverageSegmentArray = ArrayRef; -- -- /// @name Rendering Interface -- /// @{ -- -- /// \brief Render a header for the view. -- virtual void renderViewHeader(raw_ostream &OS) = 0; -- -- /// \brief Render a footer for the view. -- virtual void renderViewFooter(raw_ostream &OS) = 0; -- -- /// \brief Render the source name for the view. -- virtual void renderSourceName(raw_ostream &OS, bool WholeFile) = 0; -- -- /// \brief Render the line prefix at the given \p ViewDepth. -- virtual void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) = 0; -- -- /// \brief Render the line suffix at the given \p ViewDepth. -- virtual void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) = 0; -- -- /// \brief Render a view divider at the given \p ViewDepth. -- virtual void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) = 0; -- -- /// \brief Render a source line with highlighting. -- virtual void renderLine(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) = 0; -- -- /// \brief Render the line's execution count column. -- virtual void renderLineCoverageColumn(raw_ostream &OS, -- const LineCoverageStats &Line) = 0; -- -- /// \brief Render the line number column. -- virtual void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo) = 0; -- -- /// \brief Render all the region's execution counts on a line. -- virtual void renderRegionMarkers(raw_ostream &OS, -- CoverageSegmentArray Segments, -- unsigned ViewDepth) = 0; -- -- /// \brief Render the site of an expansion. -- virtual void -- renderExpansionSite(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) = 0; -- -- /// \brief Render an expansion view and any nested views. -- virtual void renderExpansionView(raw_ostream &OS, ExpansionView &ESV, -- unsigned ViewDepth) = 0; -- -- /// \brief Render an instantiation view and any nested views. -- virtual void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV, -- unsigned ViewDepth) = 0; -- -- /// \brief Render \p Title, a project title if one is available, and the -- /// created time. -- virtual void renderTitle(raw_ostream &OS, StringRef CellText) = 0; -- -- /// \brief Render the table header for a given source file. -- virtual void renderTableHeader(raw_ostream &OS, unsigned FirstUncoveredLineNo, -- unsigned IndentLevel) = 0; -- -- /// @} -- -- /// \brief Format a count using engineering notation with 3 significant -- /// digits. -- static std::string formatCount(uint64_t N); -- -- /// \brief Check if region marker output is expected for a line. -- bool shouldRenderRegionMarkers(bool LineHasMultipleRegions) const; -- -- /// \brief Check if there are any sub-views attached to this view. -- bool hasSubViews() const; -- -- SourceCoverageView(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo) -- : SourceName(SourceName), File(File), Options(Options), -- CoverageInfo(std::move(CoverageInfo)) {} -- --public: -- static std::unique_ptr -- create(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo); -- -- virtual ~SourceCoverageView() {} -- -- /// \brief Return the source name formatted for the host OS. -- std::string getSourceName() const; -- -- const CoverageViewOptions &getOptions() const { return Options; } -- -- /// \brief Add an expansion subview to this view. -- void addExpansion(const coverage::CounterMappingRegion &Region, -- std::unique_ptr View); -- -- /// \brief Add a function instantiation subview to this view. -- void addInstantiation(StringRef FunctionName, unsigned Line, -- std::unique_ptr View); -- -- /// \brief Print the code coverage information for a specific portion of a -- /// source file to the output stream. -- void print(raw_ostream &OS, bool WholeFile, bool ShowSourceName, -- unsigned ViewDepth = 0); --}; -- --} // namespace llvm -- --#endif // LLVM_COV_SOURCECOVERAGEVIEW_H -diff --git a/tools/llvm-cov/SourceCoverageViewHTML.cpp b/tools/llvm-cov/SourceCoverageViewHTML.cpp -index 64b888e89d7..929b224b66b 100644 ---- a/tools/llvm-cov/SourceCoverageViewHTML.cpp -+++ b/tools/llvm-cov/SourceCoverageViewHTML.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- SourceCoverageViewHTML.cpp - A html code coverage view -------------===// - // - // The LLVM Compiler Infrastructure -@@ -636,3 +637,5 @@ void SourceCoverageViewHTML::renderTableHeader(raw_ostream &OS, - << SourceLabel; - renderLineSuffix(OS, ViewDepth); - } -+ -+#endif -diff --git a/tools/llvm-cov/SourceCoverageViewHTML.h b/tools/llvm-cov/SourceCoverageViewHTML.h -deleted file mode 100644 -index 94b08a5e7fc..00000000000 ---- a/tools/llvm-cov/SourceCoverageViewHTML.h -+++ /dev/null -@@ -1,96 +0,0 @@ --//===- SourceCoverageViewHTML.h - A html code coverage view ---------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This file defines the interface to the html coverage renderer. --/// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_SOURCECOVERAGEVIEWHTML_H --#define LLVM_COV_SOURCECOVERAGEVIEWHTML_H -- --#include "SourceCoverageView.h" -- --namespace llvm { -- --struct FileCoverageSummary; -- --/// \brief A coverage printer for html output. --class CoveragePrinterHTML : public CoveragePrinter { --public: -- Expected createViewFile(StringRef Path, -- bool InToplevel) override; -- -- void closeViewFile(OwnedStream OS) override; -- -- Error createIndexFile(ArrayRef SourceFiles, -- const coverage::CoverageMapping &Coverage) override; -- -- CoveragePrinterHTML(const CoverageViewOptions &Opts) -- : CoveragePrinter(Opts) {} -- --private: -- void emitFileSummary(raw_ostream &OS, StringRef SF, -- const FileCoverageSummary &FCS, -- bool IsTotals = false) const; --}; -- --/// \brief A code coverage view which supports html-based rendering. --class SourceCoverageViewHTML : public SourceCoverageView { -- void renderViewHeader(raw_ostream &OS) override; -- -- void renderViewFooter(raw_ostream &OS) override; -- -- void renderSourceName(raw_ostream &OS, bool WholeFile) override; -- -- void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLine(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionSite(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionView(raw_ostream &OS, ExpansionView &ESV, -- unsigned ViewDepth) override; -- -- void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV, -- unsigned ViewDepth) override; -- -- void renderLineCoverageColumn(raw_ostream &OS, -- const LineCoverageStats &Line) override; -- -- void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo) override; -- -- void renderRegionMarkers(raw_ostream &OS, CoverageSegmentArray Segments, -- unsigned ViewDepth) override; -- -- void renderTitle(raw_ostream &OS, StringRef Title) override; -- -- void renderTableHeader(raw_ostream &OS, unsigned FirstUncoveredLineNo, -- unsigned IndentLevel) override; -- --public: -- SourceCoverageViewHTML(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo) -- : SourceCoverageView(SourceName, File, Options, std::move(CoverageInfo)) { -- } --}; -- --} // namespace llvm -- --#endif // LLVM_COV_SOURCECOVERAGEVIEWHTML_H -diff --git a/tools/llvm-cov/SourceCoverageViewText.cpp b/tools/llvm-cov/SourceCoverageViewText.cpp -index 4ad120f642e..03422a36a37 100644 ---- a/tools/llvm-cov/SourceCoverageViewText.cpp -+++ b/tools/llvm-cov/SourceCoverageViewText.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- SourceCoverageViewText.cpp - A text-based code coverage view -------===// - // - // The LLVM Compiler Infrastructure -@@ -237,3 +238,5 @@ void SourceCoverageViewText::renderTitle(raw_ostream &OS, StringRef Title) { - - void SourceCoverageViewText::renderTableHeader(raw_ostream &, unsigned, - unsigned) {} -+ -+#endif -diff --git a/tools/llvm-cov/SourceCoverageViewText.h b/tools/llvm-cov/SourceCoverageViewText.h -deleted file mode 100644 -index c3f20de9297..00000000000 ---- a/tools/llvm-cov/SourceCoverageViewText.h -+++ /dev/null -@@ -1,89 +0,0 @@ --//===- SourceCoverageViewText.h - A text-based code coverage view ---------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This file defines the interface to the text-based coverage renderer. --/// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_SOURCECOVERAGEVIEWTEXT_H --#define LLVM_COV_SOURCECOVERAGEVIEWTEXT_H -- --#include "SourceCoverageView.h" -- --namespace llvm { -- --/// \brief A coverage printer for text output. --class CoveragePrinterText : public CoveragePrinter { --public: -- Expected createViewFile(StringRef Path, -- bool InToplevel) override; -- -- void closeViewFile(OwnedStream OS) override; -- -- Error createIndexFile(ArrayRef SourceFiles, -- const coverage::CoverageMapping &Coverage) override; -- -- CoveragePrinterText(const CoverageViewOptions &Opts) -- : CoveragePrinter(Opts) {} --}; -- --/// \brief A code coverage view which supports text-based rendering. --class SourceCoverageViewText : public SourceCoverageView { -- void renderViewHeader(raw_ostream &OS) override; -- -- void renderViewFooter(raw_ostream &OS) override; -- -- void renderSourceName(raw_ostream &OS, bool WholeFile) override; -- -- void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLine(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionSite(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionView(raw_ostream &OS, ExpansionView &ESV, -- unsigned ViewDepth) override; -- -- void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV, -- unsigned ViewDepth) override; -- -- void renderLineCoverageColumn(raw_ostream &OS, -- const LineCoverageStats &Line) override; -- -- void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo) override; -- -- void renderRegionMarkers(raw_ostream &OS, CoverageSegmentArray Segments, -- unsigned ViewDepth) override; -- -- void renderTitle(raw_ostream &OS, StringRef Title) override; -- -- void renderTableHeader(raw_ostream &OS, unsigned FirstUncoveredLineNo, -- unsigned IndentLevel) override; -- --public: -- SourceCoverageViewText(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo) -- : SourceCoverageView(SourceName, File, Options, std::move(CoverageInfo)) { -- } --}; -- --} // namespace llvm -- --#endif // LLVM_COV_SOURCECOVERAGEVIEWTEXT_H -diff --git a/tools/llvm-cov/TestingSupport.cpp b/tools/llvm-cov/TestingSupport.cpp -index 72768f4fd58..89111d87b6e 100644 ---- a/tools/llvm-cov/TestingSupport.cpp -+++ b/tools/llvm-cov/TestingSupport.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- TestingSupport.cpp - Convert objects files into test files --------===// - // - // The LLVM Compiler Infrastructure -@@ -90,3 +91,4 @@ int convertForTestingMain(int argc, const char *argv[]) { - - return 0; - } -+#endif -diff --git a/tools/llvm-cov/gcov.cpp b/tools/llvm-cov/gcov.cpp -index 4652fed2a38..ee742efdc15 100644 ---- a/tools/llvm-cov/gcov.cpp -+++ b/tools/llvm-cov/gcov.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- gcov.cpp - GCOV compatible LLVM coverage tool ----------------------===// - // - // The LLVM Compiler Infrastructure -@@ -143,3 +144,4 @@ int gcovMain(int argc, const char *argv[]) { - Options); - return 0; - } -+#endif -diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp -index 15841587025..5103688cd7c 100644 ---- a/tools/llvm-cov/llvm-cov.cpp -+++ b/tools/llvm-cov/llvm-cov.cpp -@@ -11,6 +11,7 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 - #include "llvm/ADT/StringRef.h" - #include "llvm/ADT/StringSwitch.h" - #include "llvm/Support/CommandLine.h" -@@ -57,8 +58,10 @@ static int versionMain(int argc, const char *argv[]) { - cl::PrintVersionMessage(); - return 0; - } -+#endif - - int main(int argc, const char **argv) { -+#if 0 - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(argv[0]); - PrettyStackTraceProgram X(argc, argv); -@@ -96,5 +99,6 @@ int main(int argc, const char **argv) { - errs().resetColor(); - } - helpMain(argc, argv); -+#endif - return 1; - } -diff --git a/tools/llvm-profdata/llvm-profdata.cpp b/tools/llvm-profdata/llvm-profdata.cpp -index 6715566a166..cfcebbbb082 100644 ---- a/tools/llvm-profdata/llvm-profdata.cpp -+++ b/tools/llvm-profdata/llvm-profdata.cpp -@@ -11,6 +11,8 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 -+ - #include "llvm/ADT/SmallSet.h" - #include "llvm/ADT/SmallVector.h" - #include "llvm/ADT/StringRef.h" -@@ -652,8 +654,10 @@ static int show_main(int argc, const char *argv[]) { - return showSampleProfile(Filename, ShowCounts, ShowAllFunctions, - ShowFunction, OS); - } -+#endif - - int main(int argc, const char *argv[]) { -+#if 0 - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(argv[0]); - PrettyStackTraceProgram X(argc, argv); -@@ -692,5 +696,6 @@ int main(int argc, const char *argv[]) { - errs() << ProgName << ": Unknown command!\n"; - - errs() << "USAGE: " << ProgName << " [args...]\n"; -+#endif - return 1; - } -diff --git a/tools/sancov/sancov.cc b/tools/sancov/sancov.cc -index ff2039de35e..abb924c3644 100644 ---- a/tools/sancov/sancov.cc -+++ b/tools/sancov/sancov.cc -@@ -10,6 +10,7 @@ - // This file is a command-line tool for reading and analyzing sanitizer - // coverage. - //===----------------------------------------------------------------------===// -+#if 0 - #include "llvm/ADT/STLExtras.h" - #include "llvm/ADT/StringExtras.h" - #include "llvm/ADT/Twine.h" -@@ -1181,8 +1182,10 @@ readSymbolizeAndMergeCmdArguments(std::vector FileNames) { - } - - } // namespace -+#endif - - int main(int Argc, char **Argv) { -+#if 0 - // Print stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(Argv[0]); - PrettyStackTraceProgram X(Argc, Argv); -@@ -1236,4 +1239,6 @@ int main(int Argc, char **Argv) { - case PrintCovPointsAction: - llvm_unreachable("unsupported action"); - } -+#endif -+ return 1; - } -diff --git a/unittests/Support/ThreadPool.cpp b/unittests/Support/ThreadPool.cpp -index 8e03aacfb1e..6ee0055c1ff 100644 ---- a/unittests/Support/ThreadPool.cpp -+++ b/unittests/Support/ThreadPool.cpp -@@ -7,6 +7,8 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 -+ - #include "llvm/Support/ThreadPool.h" - - #include "llvm/ADT/STLExtras.h" -@@ -164,3 +166,5 @@ TEST_F(ThreadPoolTest, PoolDestruction) { - } - ASSERT_EQ(5, checked_in); - } -+ -+#endif --- -2.13.1 - diff --git a/deps/patches/llvm-5.0-NVPTX-addrspaces.patch b/deps/patches/llvm-5.0-NVPTX-addrspaces.patch deleted file mode 100644 index 0b04631242ccf..0000000000000 --- a/deps/patches/llvm-5.0-NVPTX-addrspaces.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff -ru llvm-5.0.0.orig/lib/Target/NVPTX/NVPTXISelLowering.cpp llvm-5.0.0/lib/Target/NVPTX/NVPTXISelLowering.cpp ---- llvm-5.0.0.orig/lib/Target/NVPTX/NVPTXISelLowering.cpp 2017-07-12 22:49:21.000000000 +0200 -+++ llvm-5.0.0/lib/Target/NVPTX/NVPTXISelLowering.cpp 2018-01-13 09:08:17.275987874 +0100 -@@ -1235,6 +1235,14 @@ - } - } - -+bool NVPTXTargetLowering::isNoopAddrSpaceCast(unsigned SrcAS, -+ unsigned DestAS) const { -+ assert(SrcAS != DestAS && "Expected different address spaces!"); -+ -+ return (SrcAS == ADDRESS_SPACE_GENERIC || SrcAS > ADDRESS_SPACE_LOCAL) && -+ (DestAS == ADDRESS_SPACE_GENERIC || DestAS > ADDRESS_SPACE_LOCAL); -+} -+ - SDValue - NVPTXTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { - SDLoc dl(Op); -diff -ru llvm-5.0.0.orig/lib/Target/NVPTX/NVPTXISelLowering.h llvm-5.0.0/lib/Target/NVPTX/NVPTXISelLowering.h ---- llvm-5.0.0.orig/lib/Target/NVPTX/NVPTXISelLowering.h 2018-01-13 09:07:48.839643576 +0100 -+++ llvm-5.0.0/lib/Target/NVPTX/NVPTXISelLowering.h 2018-01-13 09:06:18.658551692 +0100 -@@ -443,6 +443,8 @@ - const NVPTXSubtarget &STI); - SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; - -+ bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override; -+ - SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; - - const char *getTargetNodeName(unsigned Opcode) const override; diff --git a/deps/patches/llvm-5.0.0_threads.patch b/deps/patches/llvm-5.0.0_threads.patch deleted file mode 100644 index ec94a1b17e7df..0000000000000 --- a/deps/patches/llvm-5.0.0_threads.patch +++ /dev/null @@ -1,2072 +0,0 @@ -From 069fcb1fd3871ea14c8567763226464d605a90f3 Mon Sep 17 00:00:00 2001 -From: Alex Crichton -Date: Thu, 28 Jan 2016 20:44:50 -0800 -Subject: [PATCH] Don't compile usage of std::thread - -As of the time of this writing it's not actually used anywhere meaningfullly -throughout the LLVM repo that we need, and it unfortunately uses `std::thread` -which isn't available in mingw-w64 toolchains with the win32 threading model -(the one that we use). - -The change made to achive this was to just always use the single-threaded -support in `include/llvm/Support/thread.h`, and hopefuly that'll be enough... - -For reference, the upstream LLVM bug has been reported [1] - -[1]: https://llvm.org/bugs/show_bug.cgi?id=26365 ---- - include/llvm/Support/ThreadPool.h | 4 + - include/llvm/Support/thread.h | 2 +- - lib/CodeGen/ParallelCG.cpp | 2 + - lib/LTO/LTO.cpp | 6 +- - lib/LTO/LTOBackend.cpp | 2 + - lib/LTO/ThinLTOCodeGenerator.cpp | 6 +- - lib/Support/ThreadPool.cpp | 6 +- - test/CMakeLists.txt | 1 - - tools/lli/CMakeLists.txt | 4 - - tools/lli/ChildTarget/CMakeLists.txt | 13 -- - tools/lli/ChildTarget/ChildTarget.cpp | 67 ------- - tools/lli/ChildTarget/LLVMBuild.txt | 21 --- - tools/lli/LLVMBuild.txt | 3 - - tools/lli/OrcLazyJIT.cpp | 2 + - tools/lli/OrcLazyJIT.h | 201 --------------------- - tools/lli/RemoteJITUtils.h | 152 ---------------- - tools/lli/lli.cpp | 7 + - tools/llvm-cov/CodeCoverage.cpp | 4 + - tools/llvm-cov/CoverageExporterJson.cpp | 2 + - tools/llvm-cov/CoverageFilters.cpp | 2 + - tools/llvm-cov/CoverageFilters.h | 127 ------------- - tools/llvm-cov/CoverageReport.cpp | 2 + - tools/llvm-cov/CoverageReport.h | 53 ------ - tools/llvm-cov/CoverageSummaryInfo.cpp | 2 + - tools/llvm-cov/CoverageSummaryInfo.h | 178 ------------------ - tools/llvm-cov/CoverageViewOptions.h | 68 ------- - tools/llvm-cov/RenderingSupport.h | 61 ------- - tools/llvm-cov/SourceCoverageView.cpp | 2 + - tools/llvm-cov/SourceCoverageView.h | 289 ------------------------------ - tools/llvm-cov/SourceCoverageViewHTML.cpp | 3 + - tools/llvm-cov/SourceCoverageViewHTML.h | 96 ---------- - tools/llvm-cov/SourceCoverageViewText.cpp | 3 + - tools/llvm-cov/SourceCoverageViewText.h | 89 --------- - tools/llvm-cov/TestingSupport.cpp | 2 + - tools/llvm-cov/gcov.cpp | 2 + - tools/llvm-cov/llvm-cov.cpp | 4 + - tools/llvm-profdata/llvm-profdata.cpp | 5 + - tools/sancov/sancov.cc | 5 + - unittests/Support/ThreadPool.cpp | 4 + - 39 files changed, 73 insertions(+), 1429 deletions(-) - delete mode 100644 tools/lli/ChildTarget/CMakeLists.txt - delete mode 100644 tools/lli/ChildTarget/ChildTarget.cpp - delete mode 100644 tools/lli/ChildTarget/LLVMBuild.txt - delete mode 100644 tools/lli/OrcLazyJIT.h - delete mode 100644 tools/lli/RemoteJITUtils.h - delete mode 100644 tools/llvm-cov/CoverageFilters.h - delete mode 100644 tools/llvm-cov/CoverageReport.h - delete mode 100644 tools/llvm-cov/CoverageSummaryInfo.h - delete mode 100644 tools/llvm-cov/CoverageViewOptions.h - delete mode 100644 tools/llvm-cov/RenderingSupport.h - delete mode 100644 tools/llvm-cov/SourceCoverageView.h - delete mode 100644 tools/llvm-cov/SourceCoverageViewHTML.h - delete mode 100644 tools/llvm-cov/SourceCoverageViewText.h - -diff --git a/include/llvm/Support/ThreadPool.h b/include/llvm/Support/ThreadPool.h -index 9ada946c6da..c62e5917a2a 100644 ---- a/include/llvm/Support/ThreadPool.h -+++ b/include/llvm/Support/ThreadPool.h -@@ -16,6 +16,8 @@ - - #include "llvm/Support/thread.h" - -+# if 0 -+ - #include - - #include -@@ -97,4 +99,6 @@ private: - }; - } - -+# endif -+ - #endif // LLVM_SUPPORT_THREAD_POOL_H -diff --git a/include/llvm/Support/thread.h b/include/llvm/Support/thread.h -index 787a513d601..6668edb1887 100644 ---- a/include/llvm/Support/thread.h -+++ b/include/llvm/Support/thread.h -@@ -19,7 +19,7 @@ - - #include "llvm/Config/llvm-config.h" - --#if LLVM_ENABLE_THREADS -+#if LLVM_ENABLE_THREADS && 0 - - #include - -diff --git a/lib/CodeGen/ParallelCG.cpp b/lib/CodeGen/ParallelCG.cpp -index 50dd44fa659..e91898e0fa7 100644 ---- a/lib/CodeGen/ParallelCG.cpp -+++ b/lib/CodeGen/ParallelCG.cpp -@@ -50,6 +50,7 @@ std::unique_ptr llvm::splitCodeGen( - return M; - } - -+#if 0 - // Create ThreadPool in nested scope so that threads will be joined - // on destruction. - { -@@ -96,5 +97,6 @@ std::unique_ptr llvm::splitCodeGen( - PreserveLocals); - } - -+#endif - return {}; - } -diff --git a/lib/LTO/LTO.cpp b/lib/LTO/LTO.cpp -index 19973946ac5..fbb899c88f7 100644 ---- a/lib/LTO/LTO.cpp -+++ b/lib/LTO/LTO.cpp -@@ -808,7 +808,6 @@ public: - - namespace { - class InProcessThinBackend : public ThinBackendProc { -- ThreadPool BackendThreadPool; - AddStreamFn AddStream; - NativeObjectCache Cache; - TypeIdSummariesByGuidTy TypeIdSummariesByGuid; -@@ -823,7 +822,6 @@ public: - const StringMap &ModuleToDefinedGVSummaries, - AddStreamFn AddStream, NativeObjectCache Cache) - : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries), -- BackendThreadPool(ThinLTOParallelismLevel), - AddStream(std::move(AddStream)), Cache(std::move(Cache)) { - // Create a mapping from type identifier GUIDs to type identifier summaries. - // This allows backends to use the type identifier GUIDs stored in the -@@ -877,6 +875,7 @@ public: - const FunctionImporter::ExportSetTy &ExportList, - const std::map &ResolvedODR, - MapVector &ModuleMap) override { -+#if 0 - StringRef ModulePath = BM.getModuleIdentifier(); - assert(ModuleToDefinedGVSummaries.count(ModulePath)); - const GVSummaryMapTy &DefinedGlobals = -@@ -904,11 +903,14 @@ public: - BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList), - std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap), - std::ref(TypeIdSummariesByGuid)); -+#endif - return Error::success(); - } - - Error wait() override { -+#if 0 - BackendThreadPool.wait(); -+#endif - if (Err) - return std::move(*Err); - else -diff --git a/lib/LTO/LTOBackend.cpp b/lib/LTO/LTOBackend.cpp -index 3f72e446cdf..fad7c163959 100644 ---- a/lib/LTO/LTOBackend.cpp -+++ b/lib/LTO/LTOBackend.cpp -@@ -283,6 +283,7 @@ void codegen(Config &Conf, TargetMachine *TM, AddStreamFn AddStream, - void splitCodeGen(Config &C, TargetMachine *TM, AddStreamFn AddStream, - unsigned ParallelCodeGenParallelismLevel, - std::unique_ptr Mod) { -+#if 0 - ThreadPool CodegenThreadPool(ParallelCodeGenParallelismLevel); - unsigned ThreadCount = 0; - const Target *T = &TM->getTarget(); -@@ -326,6 +327,7 @@ void splitCodeGen(Config &C, TargetMachine *TM, AddStreamFn AddStream, - // variables, we need to wait for the worker threads to terminate before we - // can leave the function scope. - CodegenThreadPool.wait(); -+#endif - } - - Expected initAndLookupTarget(Config &C, Module &Mod) { -diff --git a/lib/LTO/ThinLTOCodeGenerator.cpp b/lib/LTO/ThinLTOCodeGenerator.cpp -index 1efd481b246..6b7b525f010 100644 ---- a/lib/LTO/ThinLTOCodeGenerator.cpp -+++ b/lib/LTO/ThinLTOCodeGenerator.cpp -@@ -68,8 +68,8 @@ extern cl::opt LTOStripInvalidDebugInfo; - - namespace { - --static cl::opt -- ThreadCount("threads", cl::init(llvm::heavyweight_hardware_concurrency())); -+static cl::opt ThreadCount("threads", -+ cl::init(1)); - - // Simple helper to save temporary files for debug. - static void saveTempBitcode(const Module &TheModule, StringRef TempDir, -@@ -832,6 +832,7 @@ static std::string writeGeneratedObject(int count, StringRef CacheEntryPath, - - // Main entry point for the ThinLTO processing - void ThinLTOCodeGenerator::run() { -+#if 0 - // Prepare the resulting object vector - assert(ProducedBinaries.empty() && "The generator should not be reused"); - if (SavedObjectsDirectoryPath.empty()) -@@ -1052,4 +1053,5 @@ void ThinLTOCodeGenerator::run() { - if (llvm::AreStatisticsEnabled()) - llvm::PrintStatistics(); - reportAndResetTimings(); -+#endif - } -diff --git a/lib/Support/ThreadPool.cpp b/lib/Support/ThreadPool.cpp -index 22b7550d497..985403442e4 100644 ---- a/lib/Support/ThreadPool.cpp -+++ b/lib/Support/ThreadPool.cpp -@@ -11,6 +11,8 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 -+ - #include "llvm/Support/ThreadPool.h" - - #include "llvm/Config/llvm-config.h" -@@ -18,7 +20,7 @@ - - using namespace llvm; - --#if LLVM_ENABLE_THREADS -+#if LLVM_ENABLE_THREADS && 0 - - // Default to std::thread::hardware_concurrency - ThreadPool::ThreadPool() : ThreadPool(std::thread::hardware_concurrency()) {} -@@ -143,3 +145,5 @@ ThreadPool::~ThreadPool() { - } - - #endif -+ -+#endif -diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt -index 124f0c72fd7..853adf6cf8a 100644 ---- a/test/CMakeLists.txt -+++ b/test/CMakeLists.txt -@@ -35,7 +35,6 @@ set(LLVM_TEST_DEPENDS - count - llc - lli -- lli-child-target - llvm-ar - llvm-as - llvm-bcanalyzer -diff --git a/tools/lli/CMakeLists.txt b/tools/lli/CMakeLists.txt -index f02e19313b7..ca2e82abcd0 100644 ---- a/tools/lli/CMakeLists.txt -+++ b/tools/lli/CMakeLists.txt -@@ -1,7 +1,3 @@ --if ( LLVM_INCLUDE_UTILS ) -- add_subdirectory(ChildTarget) --endif() -- - set(LLVM_LINK_COMPONENTS - CodeGen - Core -diff --git a/tools/lli/ChildTarget/CMakeLists.txt b/tools/lli/ChildTarget/CMakeLists.txt -deleted file mode 100644 -index f08ce57c295..00000000000 ---- a/tools/lli/ChildTarget/CMakeLists.txt -+++ /dev/null -@@ -1,13 +0,0 @@ --set(LLVM_LINK_COMPONENTS -- OrcJIT -- RuntimeDyld -- Support -- ) -- --add_llvm_utility(lli-child-target -- ChildTarget.cpp -- -- DEPENDS -- intrinsics_gen --) -- -diff --git a/tools/lli/ChildTarget/ChildTarget.cpp b/tools/lli/ChildTarget/ChildTarget.cpp -deleted file mode 100644 -index 77b1d47a946..00000000000 ---- a/tools/lli/ChildTarget/ChildTarget.cpp -+++ /dev/null -@@ -1,67 +0,0 @@ --#include "llvm/ExecutionEngine/Orc/OrcABISupport.h" --#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h" --#include "llvm/Support/Debug.h" --#include "llvm/Support/DynamicLibrary.h" --#include "llvm/Support/Process.h" --#include -- --#include "../RemoteJITUtils.h" -- --using namespace llvm; --using namespace llvm::orc; --using namespace llvm::sys; -- --#ifdef __x86_64__ --typedef OrcX86_64_SysV HostOrcArch; --#else --typedef OrcGenericABI HostOrcArch; --#endif -- --ExitOnError ExitOnErr; -- --int main(int argc, char *argv[]) { -- -- if (argc != 3) { -- errs() << "Usage: " << argv[0] << " \n"; -- return 1; -- } -- -- ExitOnErr.setBanner(std::string(argv[0]) + ":"); -- -- int InFD; -- int OutFD; -- { -- std::istringstream InFDStream(argv[1]), OutFDStream(argv[2]); -- InFDStream >> InFD; -- OutFDStream >> OutFD; -- } -- -- if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) { -- errs() << "Error loading program symbols.\n"; -- return 1; -- } -- -- auto SymbolLookup = [](const std::string &Name) { -- return RTDyldMemoryManager::getSymbolAddressInProcess(Name); -- }; -- -- auto RegisterEHFrames = [](uint8_t *Addr, uint32_t Size) { -- RTDyldMemoryManager::registerEHFramesInProcess(Addr, Size); -- }; -- -- auto DeregisterEHFrames = [](uint8_t *Addr, uint32_t Size) { -- RTDyldMemoryManager::deregisterEHFramesInProcess(Addr, Size); -- }; -- -- FDRawChannel Channel(InFD, OutFD); -- typedef remote::OrcRemoteTargetServer JITServer; -- JITServer Server(Channel, SymbolLookup, RegisterEHFrames, DeregisterEHFrames); -- -- while (!Server.receivedTerminate()) -- ExitOnErr(Server.handleOne()); -- -- close(InFD); -- close(OutFD); -- -- return 0; --} -diff --git a/tools/lli/ChildTarget/LLVMBuild.txt b/tools/lli/ChildTarget/LLVMBuild.txt -deleted file mode 100644 -index daf6df11324..00000000000 ---- a/tools/lli/ChildTarget/LLVMBuild.txt -+++ /dev/null -@@ -1,21 +0,0 @@ --;===- ./tools/lli/ChildTarget/LLVMBuild.txt --------------------*- Conf -*--===; --; --; The LLVM Compiler Infrastructure --; --; This file is distributed under the University of Illinois Open Source --; License. See LICENSE.TXT for details. --; --;===------------------------------------------------------------------------===; --; --; This is an LLVMBuild description file for the components in this subdirectory. --; --; For more information on the LLVMBuild system, please see: --; --; http://llvm.org/docs/LLVMBuild.html --; --;===------------------------------------------------------------------------===; -- --[component_0] --type = Tool --name = lli-child-target --parent = lli -diff --git a/tools/lli/LLVMBuild.txt b/tools/lli/LLVMBuild.txt -index 9d889bf4c2e..47385048e08 100644 ---- a/tools/lli/LLVMBuild.txt -+++ b/tools/lli/LLVMBuild.txt -@@ -15,9 +15,6 @@ - ; - ;===------------------------------------------------------------------------===; - --[common] --subdirectories = ChildTarget -- - [component_0] - type = Tool - name = lli -diff --git a/tools/lli/OrcLazyJIT.cpp b/tools/lli/OrcLazyJIT.cpp -index f1a752e0790..adc0e0db3f8 100644 ---- a/tools/lli/OrcLazyJIT.cpp -+++ b/tools/lli/OrcLazyJIT.cpp -@@ -1,4 +1,5 @@ - //===- OrcLazyJIT.cpp - Basic Orc-based JIT for lazy execution ------------===// -+#if 0 - // - // The LLVM Compiler Infrastructure - // -@@ -164,3 +165,4 @@ int llvm::runOrcLazyJIT(std::vector> Ms, - - return 1; - } -+#endif -diff --git a/tools/lli/OrcLazyJIT.h b/tools/lli/OrcLazyJIT.h -deleted file mode 100644 -index 47a2acc4d7e..00000000000 ---- a/tools/lli/OrcLazyJIT.h -+++ /dev/null -@@ -1,201 +0,0 @@ --//===- OrcLazyJIT.h - Basic Orc-based JIT for lazy execution ----*- C++ -*-===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// Simple Orc-based JIT. Uses the compile-on-demand layer to break up and --// lazily compile modules. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_TOOLS_LLI_ORCLAZYJIT_H --#define LLVM_TOOLS_LLI_ORCLAZYJIT_H -- --#include "llvm/ADT/STLExtras.h" --#include "llvm/ADT/Twine.h" --#include "llvm/ExecutionEngine/JITSymbol.h" --#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" --#include "llvm/ExecutionEngine/Orc/CompileUtils.h" --#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" --#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" --#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" --#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" --#include "llvm/ExecutionEngine/Orc/LambdaResolver.h" --#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" --#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" --#include "llvm/ExecutionEngine/SectionMemoryManager.h" --#include "llvm/IR/DataLayout.h" --#include "llvm/IR/GlobalValue.h" --#include "llvm/IR/Mangler.h" --#include "llvm/IR/Module.h" --#include "llvm/Support/raw_ostream.h" --#include "llvm/Target/TargetMachine.h" --#include --#include --#include --#include --#include --#include -- --namespace llvm { -- --class OrcLazyJIT { --public: -- -- using CompileCallbackMgr = orc::JITCompileCallbackManager; -- using ObjLayerT = orc::RTDyldObjectLinkingLayer; -- using CompileLayerT = orc::IRCompileLayer; -- using TransformFtor = -- std::function(std::shared_ptr)>; -- using IRDumpLayerT = orc::IRTransformLayer; -- using CODLayerT = orc::CompileOnDemandLayer; -- using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT; -- using ModuleHandleT = CODLayerT::ModuleHandleT; -- -- OrcLazyJIT(std::unique_ptr TM, -- std::unique_ptr CCMgr, -- IndirectStubsManagerBuilder IndirectStubsMgrBuilder, -- bool InlineStubs) -- : TM(std::move(TM)), DL(this->TM->createDataLayout()), -- CCMgr(std::move(CCMgr)), -- ObjectLayer([]() { return std::make_shared(); }), -- CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)), -- IRDumpLayer(CompileLayer, createDebugDumper()), -- CODLayer(IRDumpLayer, extractSingleFunction, *this->CCMgr, -- std::move(IndirectStubsMgrBuilder), InlineStubs), -- CXXRuntimeOverrides( -- [this](const std::string &S) { return mangle(S); }) {} -- -- ~OrcLazyJIT() { -- // Run any destructors registered with __cxa_atexit. -- CXXRuntimeOverrides.runDestructors(); -- // Run any IR destructors. -- for (auto &DtorRunner : IRStaticDestructorRunners) -- if (auto Err = DtorRunner.runViaLayer(CODLayer)) { -- // FIXME: OrcLazyJIT should probably take a "shutdownError" callback to -- // report these errors on. -- report_fatal_error(std::move(Err)); -- } -- } -- -- Error addModule(std::shared_ptr M) { -- if (M->getDataLayout().isDefault()) -- M->setDataLayout(DL); -- -- // Rename, bump linkage and record static constructors and destructors. -- // We have to do this before we hand over ownership of the module to the -- // JIT. -- std::vector CtorNames, DtorNames; -- { -- unsigned CtorId = 0, DtorId = 0; -- for (auto Ctor : orc::getConstructors(*M)) { -- std::string NewCtorName = ("$static_ctor." + Twine(CtorId++)).str(); -- Ctor.Func->setName(NewCtorName); -- Ctor.Func->setLinkage(GlobalValue::ExternalLinkage); -- Ctor.Func->setVisibility(GlobalValue::HiddenVisibility); -- CtorNames.push_back(mangle(NewCtorName)); -- } -- for (auto Dtor : orc::getDestructors(*M)) { -- std::string NewDtorName = ("$static_dtor." + Twine(DtorId++)).str(); -- Dtor.Func->setLinkage(GlobalValue::ExternalLinkage); -- Dtor.Func->setVisibility(GlobalValue::HiddenVisibility); -- DtorNames.push_back(mangle(Dtor.Func->getName())); -- Dtor.Func->setName(NewDtorName); -- } -- } -- -- // Symbol resolution order: -- // 1) Search the JIT symbols. -- // 2) Check for C++ runtime overrides. -- // 3) Search the host process (LLI)'s symbol table. -- if (ModulesHandle == CODLayerT::ModuleHandleT()) { -- auto Resolver = -- orc::createLambdaResolver( -- [this](const std::string &Name) -> JITSymbol { -- if (auto Sym = CODLayer.findSymbol(Name, true)) -- return Sym; -- return CXXRuntimeOverrides.searchOverrides(Name); -- }, -- [](const std::string &Name) { -- if (auto Addr = -- RTDyldMemoryManager::getSymbolAddressInProcess(Name)) -- return JITSymbol(Addr, JITSymbolFlags::Exported); -- return JITSymbol(nullptr); -- } -- ); -- -- // Add the module to the JIT. -- if (auto ModulesHandleOrErr = -- CODLayer.addModule(std::move(M), std::move(Resolver))) -- ModulesHandle = std::move(*ModulesHandleOrErr); -- else -- return ModulesHandleOrErr.takeError(); -- -- } else -- if (auto Err = CODLayer.addExtraModule(ModulesHandle, std::move(M))) -- return Err; -- -- // Run the static constructors, and save the static destructor runner for -- // execution when the JIT is torn down. -- orc::CtorDtorRunner CtorRunner(std::move(CtorNames), -- ModulesHandle); -- if (auto Err = CtorRunner.runViaLayer(CODLayer)) -- return Err; -- -- IRStaticDestructorRunners.emplace_back(std::move(DtorNames), -- ModulesHandle); -- -- return Error::success(); -- } -- -- JITSymbol findSymbol(const std::string &Name) { -- return CODLayer.findSymbol(mangle(Name), true); -- } -- -- JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) { -- return CODLayer.findSymbolIn(H, mangle(Name), true); -- } -- --private: -- std::string mangle(const std::string &Name) { -- std::string MangledName; -- { -- raw_string_ostream MangledNameStream(MangledName); -- Mangler::getNameWithPrefix(MangledNameStream, Name, DL); -- } -- return MangledName; -- } -- -- static std::set extractSingleFunction(Function &F) { -- std::set Partition; -- Partition.insert(&F); -- return Partition; -- } -- -- static TransformFtor createDebugDumper(); -- -- std::unique_ptr TM; -- DataLayout DL; -- SectionMemoryManager CCMgrMemMgr; -- -- std::unique_ptr CCMgr; -- ObjLayerT ObjectLayer; -- CompileLayerT CompileLayer; -- IRDumpLayerT IRDumpLayer; -- CODLayerT CODLayer; -- -- orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides; -- std::vector> IRStaticDestructorRunners; -- CODLayerT::ModuleHandleT ModulesHandle; --}; -- --int runOrcLazyJIT(std::vector> Ms, -- const std::vector &Args); -- --} // end namespace llvm -- --#endif // LLVM_TOOLS_LLI_ORCLAZYJIT_H -diff --git a/tools/lli/RemoteJITUtils.h b/tools/lli/RemoteJITUtils.h -deleted file mode 100644 -index 4e948413865..00000000000 ---- a/tools/lli/RemoteJITUtils.h -+++ /dev/null -@@ -1,152 +0,0 @@ --//===-- RemoteJITUtils.h - Utilities for remote-JITing with LLI -*- C++ -*-===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// Utilities for remote-JITing with LLI. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_TOOLS_LLI_REMOTEJITUTILS_H --#define LLVM_TOOLS_LLI_REMOTEJITUTILS_H -- --#include "llvm/ExecutionEngine/Orc/RawByteChannel.h" --#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" --#include -- --#if !defined(_MSC_VER) && !defined(__MINGW32__) --#include --#else --#include --#endif -- --/// RPC channel that reads from and writes from file descriptors. --class FDRawChannel final : public llvm::orc::rpc::RawByteChannel { --public: -- FDRawChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {} -- -- llvm::Error readBytes(char *Dst, unsigned Size) override { -- assert(Dst && "Attempt to read into null."); -- ssize_t Completed = 0; -- while (Completed < static_cast(Size)) { -- ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed); -- if (Read <= 0) { -- auto ErrNo = errno; -- if (ErrNo == EAGAIN || ErrNo == EINTR) -- continue; -- else -- return llvm::errorCodeToError( -- std::error_code(errno, std::generic_category())); -- } -- Completed += Read; -- } -- return llvm::Error::success(); -- } -- -- llvm::Error appendBytes(const char *Src, unsigned Size) override { -- assert(Src && "Attempt to append from null."); -- ssize_t Completed = 0; -- while (Completed < static_cast(Size)) { -- ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed); -- if (Written < 0) { -- auto ErrNo = errno; -- if (ErrNo == EAGAIN || ErrNo == EINTR) -- continue; -- else -- return llvm::errorCodeToError( -- std::error_code(errno, std::generic_category())); -- } -- Completed += Written; -- } -- return llvm::Error::success(); -- } -- -- llvm::Error send() override { return llvm::Error::success(); } -- --private: -- int InFD, OutFD; --}; -- --// launch the remote process (see lli.cpp) and return a channel to it. --std::unique_ptr launchRemote(); -- --namespace llvm { -- --// ForwardingMM - Adapter to connect MCJIT to Orc's Remote8 --// memory manager. --class ForwardingMemoryManager : public llvm::RTDyldMemoryManager { --public: -- void setMemMgr(std::unique_ptr MemMgr) { -- this->MemMgr = std::move(MemMgr); -- } -- -- void setResolver(std::shared_ptr Resolver) { -- this->Resolver = std::move(Resolver); -- } -- -- uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, -- unsigned SectionID, -- StringRef SectionName) override { -- return MemMgr->allocateCodeSection(Size, Alignment, SectionID, SectionName); -- } -- -- uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, -- unsigned SectionID, StringRef SectionName, -- bool IsReadOnly) override { -- return MemMgr->allocateDataSection(Size, Alignment, SectionID, SectionName, -- IsReadOnly); -- } -- -- void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, -- uintptr_t RODataSize, uint32_t RODataAlign, -- uintptr_t RWDataSize, -- uint32_t RWDataAlign) override { -- MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign, -- RWDataSize, RWDataAlign); -- } -- -- bool needsToReserveAllocationSpace() override { -- return MemMgr->needsToReserveAllocationSpace(); -- } -- -- void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, -- size_t Size) override { -- MemMgr->registerEHFrames(Addr, LoadAddr, Size); -- } -- -- void deregisterEHFrames() override { -- MemMgr->deregisterEHFrames(); -- } -- -- bool finalizeMemory(std::string *ErrMsg = nullptr) override { -- return MemMgr->finalizeMemory(ErrMsg); -- } -- -- void notifyObjectLoaded(RuntimeDyld &RTDyld, -- const object::ObjectFile &Obj) override { -- MemMgr->notifyObjectLoaded(RTDyld, Obj); -- } -- -- // Don't hide the sibling notifyObjectLoaded from RTDyldMemoryManager. -- using RTDyldMemoryManager::notifyObjectLoaded; -- -- JITSymbol findSymbol(const std::string &Name) override { -- return Resolver->findSymbol(Name); -- } -- -- JITSymbol -- findSymbolInLogicalDylib(const std::string &Name) override { -- return Resolver->findSymbolInLogicalDylib(Name); -- } -- --private: -- std::unique_ptr MemMgr; -- std::shared_ptr Resolver; --}; --} -- --#endif -diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp -index 091ca22b4e8..77ff6d4a01c 100644 ---- a/tools/lli/lli.cpp -+++ b/tools/lli/lli.cpp -@@ -13,6 +13,8 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 -+ - #include "OrcLazyJIT.h" - #include "RemoteJITUtils.h" - #include "llvm/IR/LLVMContext.h" -@@ -757,3 +759,8 @@ std::unique_ptr launchRemote() { - return llvm::make_unique(PipeFD[1][0], PipeFD[0][1]); - #endif - } -+#endif -+ -+int main(int argc, char **argv, char * const *envp) { -+ return 0; -+} -diff --git a/tools/llvm-cov/CodeCoverage.cpp b/tools/llvm-cov/CodeCoverage.cpp -index 3cbd6591134..2b270a35edb 100644 ---- a/tools/llvm-cov/CodeCoverage.cpp -+++ b/tools/llvm-cov/CodeCoverage.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- CodeCoverage.cpp - Coverage tool based on profiling instrumentation-===// - // - // The LLVM Compiler Infrastructure -@@ -879,7 +880,10 @@ int reportMain(int argc, const char *argv[]) { - return Tool.run(CodeCoverageTool::Report, argc, argv); - } - -+ - int exportMain(int argc, const char *argv[]) { - CodeCoverageTool Tool; - return Tool.run(CodeCoverageTool::Export, argc, argv); - } -+ -+#endif -diff --git a/tools/llvm-cov/CoverageExporterJson.cpp b/tools/llvm-cov/CoverageExporterJson.cpp -index ef50bba2123..d3d0a8f5f01 100644 ---- a/tools/llvm-cov/CoverageExporterJson.cpp -+++ b/tools/llvm-cov/CoverageExporterJson.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- CoverageExporterJson.cpp - Code coverage export --------------------===// - // - // The LLVM Compiler Infrastructure -@@ -419,3 +420,4 @@ void exportCoverageDataToJson(const CoverageMapping &CoverageMapping, - - Exporter.print(); - } -+#endif -diff --git a/tools/llvm-cov/CoverageFilters.cpp b/tools/llvm-cov/CoverageFilters.cpp -index 325dd723578..8a41ba8c1d8 100644 ---- a/tools/llvm-cov/CoverageFilters.cpp -+++ b/tools/llvm-cov/CoverageFilters.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- CoverageFilters.cpp - Function coverage mapping filters ------------===// - // - // The LLVM Compiler Infrastructure -@@ -57,3 +58,4 @@ CoverageFiltersMatchAll::matches(const coverage::FunctionRecord &Function) { - } - return true; - } -+#endif -diff --git a/tools/llvm-cov/CoverageFilters.h b/tools/llvm-cov/CoverageFilters.h -deleted file mode 100644 -index 756c4b47872..00000000000 ---- a/tools/llvm-cov/CoverageFilters.h -+++ /dev/null -@@ -1,127 +0,0 @@ --//===- CoverageFilters.h - Function coverage mapping filters --------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// These classes provide filtering for function coverage mapping records. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGEFILTERS_H --#define LLVM_COV_COVERAGEFILTERS_H -- --#include "llvm/ProfileData/Coverage/CoverageMapping.h" --#include --#include -- --namespace llvm { -- --/// \brief Matches specific functions that pass the requirement of this filter. --class CoverageFilter { --public: -- virtual ~CoverageFilter() {} -- -- /// \brief Return true if the function passes the requirements of this filter. -- virtual bool matches(const coverage::FunctionRecord &Function) { -- return true; -- } --}; -- --/// \brief Matches functions that contain a specific string in their name. --class NameCoverageFilter : public CoverageFilter { -- StringRef Name; -- --public: -- NameCoverageFilter(StringRef Name) : Name(Name) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief Matches functions whose name matches a certain regular expression. --class NameRegexCoverageFilter : public CoverageFilter { -- StringRef Regex; -- --public: -- NameRegexCoverageFilter(StringRef Regex) : Regex(Regex) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief Matches numbers that pass a certain threshold. --template class StatisticThresholdFilter { --public: -- enum Operation { LessThan, GreaterThan }; -- --protected: -- Operation Op; -- T Threshold; -- -- StatisticThresholdFilter(Operation Op, T Threshold) -- : Op(Op), Threshold(Threshold) {} -- -- /// \brief Return true if the given number is less than -- /// or greater than the certain threshold. -- bool PassesThreshold(T Value) const { -- switch (Op) { -- case LessThan: -- return Value < Threshold; -- case GreaterThan: -- return Value > Threshold; -- } -- return false; -- } --}; -- --/// \brief Matches functions whose region coverage percentage --/// is above/below a certain percentage. --class RegionCoverageFilter : public CoverageFilter, -- public StatisticThresholdFilter { --public: -- RegionCoverageFilter(Operation Op, double Threshold) -- : StatisticThresholdFilter(Op, Threshold) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief Matches functions whose line coverage percentage --/// is above/below a certain percentage. --class LineCoverageFilter : public CoverageFilter, -- public StatisticThresholdFilter { --public: -- LineCoverageFilter(Operation Op, double Threshold) -- : StatisticThresholdFilter(Op, Threshold) {} -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief A collection of filters. --/// Matches functions that match any filters contained --/// in an instance of this class. --class CoverageFilters : public CoverageFilter { --protected: -- std::vector> Filters; -- --public: -- /// \brief Append a filter to this collection. -- void push_back(std::unique_ptr Filter); -- -- bool empty() const { return Filters.empty(); } -- -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --/// \brief A collection of filters. --/// Matches functions that match all of the filters contained --/// in an instance of this class. --class CoverageFiltersMatchAll : public CoverageFilters { --public: -- bool matches(const coverage::FunctionRecord &Function) override; --}; -- --} // namespace llvm -- --#endif // LLVM_COV_COVERAGEFILTERS_H -diff --git a/tools/llvm-cov/CoverageReport.cpp b/tools/llvm-cov/CoverageReport.cpp -index c68bb9048df..b17831bcaa8 100644 ---- a/tools/llvm-cov/CoverageReport.cpp -+++ b/tools/llvm-cov/CoverageReport.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- CoverageReport.cpp - Code coverage report -------------------------===// - // - // The LLVM Compiler Infrastructure -@@ -386,3 +387,4 @@ void CoverageReport::renderFileReports(raw_ostream &OS, - } - - } // end namespace llvm -+#endif -diff --git a/tools/llvm-cov/CoverageReport.h b/tools/llvm-cov/CoverageReport.h -deleted file mode 100644 -index 071be2e2159..00000000000 ---- a/tools/llvm-cov/CoverageReport.h -+++ /dev/null -@@ -1,53 +0,0 @@ --//===- CoverageReport.h - Code coverage report ---------------------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// This class implements rendering of a code coverage report. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGEREPORT_H --#define LLVM_COV_COVERAGEREPORT_H -- --#include "CoverageSummaryInfo.h" --#include "CoverageViewOptions.h" -- --namespace llvm { -- --/// \brief Displays the code coverage report. --class CoverageReport { -- const CoverageViewOptions &Options; -- const coverage::CoverageMapping &Coverage; -- -- void render(const FileCoverageSummary &File, raw_ostream &OS) const; -- void render(const FunctionCoverageSummary &Function, const DemangleCache &DC, -- raw_ostream &OS) const; -- --public: -- CoverageReport(const CoverageViewOptions &Options, -- const coverage::CoverageMapping &Coverage) -- : Options(Options), Coverage(Coverage) {} -- -- void renderFunctionReports(ArrayRef Files, -- const DemangleCache &DC, raw_ostream &OS); -- -- /// Prepare file reports for the files specified in \p Files. -- static std::vector -- prepareFileReports(const coverage::CoverageMapping &Coverage, -- FileCoverageSummary &Totals, ArrayRef Files); -- -- /// Render file reports for every unique file in the coverage mapping. -- void renderFileReports(raw_ostream &OS) const; -- -- /// Render file reports for the files specified in \p Files. -- void renderFileReports(raw_ostream &OS, ArrayRef Files) const; --}; -- --} // end namespace llvm -- --#endif // LLVM_COV_COVERAGEREPORT_H -diff --git a/tools/llvm-cov/CoverageSummaryInfo.cpp b/tools/llvm-cov/CoverageSummaryInfo.cpp -index 21aa7ff73a0..5a325b40cf8 100644 ---- a/tools/llvm-cov/CoverageSummaryInfo.cpp -+++ b/tools/llvm-cov/CoverageSummaryInfo.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- CoverageSummaryInfo.cpp - Coverage summary for function/file -------===// - // - // The LLVM Compiler Infrastructure -@@ -81,3 +82,4 @@ void FunctionCoverageSummary::update(const FunctionCoverageSummary &Summary) { - LineCoverage.NotCovered = - std::min(LineCoverage.NotCovered, Summary.LineCoverage.NotCovered); - } -+#endif -diff --git a/tools/llvm-cov/CoverageSummaryInfo.h b/tools/llvm-cov/CoverageSummaryInfo.h -deleted file mode 100644 -index 680fc375768..00000000000 ---- a/tools/llvm-cov/CoverageSummaryInfo.h -+++ /dev/null -@@ -1,178 +0,0 @@ --//===- CoverageSummaryInfo.h - Coverage summary for function/file ---------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --// --// These structures are used to represent code coverage metrics --// for functions/files. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGESUMMARYINFO_H --#define LLVM_COV_COVERAGESUMMARYINFO_H -- --#include "llvm/ProfileData/Coverage/CoverageMapping.h" --#include "llvm/Support/raw_ostream.h" -- --namespace llvm { -- --/// \brief Provides information about region coverage for a function/file. --struct RegionCoverageInfo { -- /// \brief The number of regions that were executed at least once. -- size_t Covered; -- -- /// \brief The number of regions that weren't executed. -- size_t NotCovered; -- -- /// \brief The total number of regions in a function/file. -- size_t NumRegions; -- -- RegionCoverageInfo() : Covered(0), NotCovered(0), NumRegions(0) {} -- -- RegionCoverageInfo(size_t Covered, size_t NumRegions) -- : Covered(Covered), NotCovered(NumRegions - Covered), -- NumRegions(NumRegions) {} -- -- RegionCoverageInfo &operator+=(const RegionCoverageInfo &RHS) { -- Covered += RHS.Covered; -- NotCovered += RHS.NotCovered; -- NumRegions += RHS.NumRegions; -- return *this; -- } -- -- bool isFullyCovered() const { return Covered == NumRegions; } -- -- double getPercentCovered() const { -- if (NumRegions == 0) -- return 0.0; -- return double(Covered) / double(NumRegions) * 100.0; -- } --}; -- --/// \brief Provides information about line coverage for a function/file. --struct LineCoverageInfo { -- /// \brief The number of lines that were executed at least once. -- size_t Covered; -- -- /// \brief The number of lines that weren't executed. -- size_t NotCovered; -- -- /// \brief The total number of lines in a function/file. -- size_t NumLines; -- -- LineCoverageInfo() : Covered(0), NotCovered(0), NumLines(0) {} -- -- LineCoverageInfo(size_t Covered, size_t NumLines) -- : Covered(Covered), NotCovered(NumLines - Covered), NumLines(NumLines) {} -- -- LineCoverageInfo &operator+=(const LineCoverageInfo &RHS) { -- Covered += RHS.Covered; -- NotCovered += RHS.NotCovered; -- NumLines += RHS.NumLines; -- return *this; -- } -- -- bool isFullyCovered() const { return Covered == NumLines; } -- -- double getPercentCovered() const { -- if (NumLines == 0) -- return 0.0; -- return double(Covered) / double(NumLines) * 100.0; -- } --}; -- --/// \brief Provides information about function coverage for a file. --struct FunctionCoverageInfo { -- /// \brief The number of functions that were executed. -- size_t Executed; -- -- /// \brief The total number of functions in this file. -- size_t NumFunctions; -- -- FunctionCoverageInfo() : Executed(0), NumFunctions(0) {} -- -- FunctionCoverageInfo(size_t Executed, size_t NumFunctions) -- : Executed(Executed), NumFunctions(NumFunctions) {} -- -- void addFunction(bool Covered) { -- if (Covered) -- ++Executed; -- ++NumFunctions; -- } -- -- bool isFullyCovered() const { return Executed == NumFunctions; } -- -- double getPercentCovered() const { -- if (NumFunctions == 0) -- return 0.0; -- return double(Executed) / double(NumFunctions) * 100.0; -- } --}; -- --/// \brief A summary of function's code coverage. --struct FunctionCoverageSummary { -- StringRef Name; -- uint64_t ExecutionCount; -- RegionCoverageInfo RegionCoverage; -- LineCoverageInfo LineCoverage; -- -- FunctionCoverageSummary(StringRef Name) : Name(Name), ExecutionCount(0) {} -- -- FunctionCoverageSummary(StringRef Name, uint64_t ExecutionCount, -- const RegionCoverageInfo &RegionCoverage, -- const LineCoverageInfo &LineCoverage) -- : Name(Name), ExecutionCount(ExecutionCount), -- RegionCoverage(RegionCoverage), LineCoverage(LineCoverage) { -- } -- -- /// \brief Compute the code coverage summary for the given function coverage -- /// mapping record. -- static FunctionCoverageSummary -- get(const coverage::FunctionRecord &Function); -- -- /// \brief Update the summary with information from another instantiation -- /// of this function. -- void update(const FunctionCoverageSummary &Summary); --}; -- --/// \brief A summary of file's code coverage. --struct FileCoverageSummary { -- StringRef Name; -- RegionCoverageInfo RegionCoverage; -- LineCoverageInfo LineCoverage; -- FunctionCoverageInfo FunctionCoverage; -- FunctionCoverageInfo InstantiationCoverage; -- -- FileCoverageSummary(StringRef Name) : Name(Name) {} -- -- void addFunction(const FunctionCoverageSummary &Function) { -- RegionCoverage += Function.RegionCoverage; -- LineCoverage += Function.LineCoverage; -- FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); -- } -- -- void addInstantiation(const FunctionCoverageSummary &Function) { -- InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); -- } --}; -- --/// \brief A cache for demangled symbols. --struct DemangleCache { -- StringMap DemangledNames; -- -- /// \brief Demangle \p Sym if possible. Otherwise, just return \p Sym. -- StringRef demangle(StringRef Sym) const { -- const auto DemangledName = DemangledNames.find(Sym); -- if (DemangledName == DemangledNames.end()) -- return Sym; -- return DemangledName->getValue(); -- } --}; -- --} // namespace llvm -- --#endif // LLVM_COV_COVERAGESUMMARYINFO_H -diff --git a/tools/llvm-cov/CoverageViewOptions.h b/tools/llvm-cov/CoverageViewOptions.h -deleted file mode 100644 -index 266b380b7d3..00000000000 ---- a/tools/llvm-cov/CoverageViewOptions.h -+++ /dev/null -@@ -1,68 +0,0 @@ --//===- CoverageViewOptions.h - Code coverage display options -------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_COVERAGEVIEWOPTIONS_H --#define LLVM_COV_COVERAGEVIEWOPTIONS_H -- --#include "RenderingSupport.h" --#include -- --namespace llvm { -- --/// \brief The options for displaying the code coverage information. --struct CoverageViewOptions { -- enum class OutputFormat { -- Text, -- HTML -- }; -- -- bool Debug; -- bool Colors; -- bool ShowLineNumbers; -- bool ShowLineStats; -- bool ShowRegionMarkers; -- bool ShowLineStatsOrRegionMarkers; -- bool ShowExpandedRegions; -- bool ShowFunctionInstantiations; -- bool ShowFullFilenames; -- OutputFormat Format; -- std::string ShowOutputDirectory; -- std::vector DemanglerOpts; -- uint32_t TabSize; -- std::string ProjectTitle; -- std::string CreatedTimeStr; -- -- /// \brief Change the output's stream color if the colors are enabled. -- ColoredRawOstream colored_ostream(raw_ostream &OS, -- raw_ostream::Colors Color) const { -- return llvm::colored_ostream(OS, Color, Colors); -- } -- -- /// \brief Check if an output directory has been specified. -- bool hasOutputDirectory() const { return !ShowOutputDirectory.empty(); } -- -- /// \brief Check if a demangler has been specified. -- bool hasDemangler() const { return !DemanglerOpts.empty(); } -- -- /// \brief Check if a project title has been specified. -- bool hasProjectTitle() const { return !ProjectTitle.empty(); } -- -- /// \brief Check if the created time of the profile data file is available. -- bool hasCreatedTime() const { return !CreatedTimeStr.empty(); } -- -- /// \brief Get the LLVM version string. -- std::string getLLVMVersionString() const { -- std::string VersionString = "Generated by llvm-cov -- llvm version "; -- VersionString += LLVM_VERSION_STRING; -- return VersionString; -- } --}; --} -- --#endif // LLVM_COV_COVERAGEVIEWOPTIONS_H -diff --git a/tools/llvm-cov/RenderingSupport.h b/tools/llvm-cov/RenderingSupport.h -deleted file mode 100644 -index aa70fbc23e3..00000000000 ---- a/tools/llvm-cov/RenderingSupport.h -+++ /dev/null -@@ -1,61 +0,0 @@ --//===- RenderingSupport.h - output stream rendering support functions ----===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_RENDERINGSUPPORT_H --#define LLVM_COV_RENDERINGSUPPORT_H -- --#include "llvm/Support/raw_ostream.h" --#include -- --namespace llvm { -- --/// \brief A helper class that resets the output stream's color if needed --/// when destroyed. --class ColoredRawOstream { -- ColoredRawOstream(const ColoredRawOstream &OS) = delete; -- --public: -- raw_ostream &OS; -- bool IsColorUsed; -- -- ColoredRawOstream(raw_ostream &OS, bool IsColorUsed) -- : OS(OS), IsColorUsed(IsColorUsed) {} -- -- ColoredRawOstream(ColoredRawOstream &&Other) -- : OS(Other.OS), IsColorUsed(Other.IsColorUsed) { -- // Reset the other IsColorUsed so that the other object won't reset the -- // color when destroyed. -- Other.IsColorUsed = false; -- } -- -- ~ColoredRawOstream() { -- if (IsColorUsed) -- OS.resetColor(); -- } --}; -- --template --inline raw_ostream &operator<<(const ColoredRawOstream &OS, T &&Value) { -- return OS.OS << std::forward(Value); --} -- --/// \brief Change the color of the output stream if the `IsColorUsed` flag --/// is true. Returns an object that resets the color when destroyed. --inline ColoredRawOstream colored_ostream(raw_ostream &OS, -- raw_ostream::Colors Color, -- bool IsColorUsed = true, -- bool Bold = false, bool BG = false) { -- if (IsColorUsed) -- OS.changeColor(Color, Bold, BG); -- return ColoredRawOstream(OS, IsColorUsed); --} -- --} // namespace llvm -- --#endif // LLVM_COV_RENDERINGSUPPORT_H -diff --git a/tools/llvm-cov/SourceCoverageView.cpp b/tools/llvm-cov/SourceCoverageView.cpp -index 52b8ff1747f..84c2cb7e8d6 100644 ---- a/tools/llvm-cov/SourceCoverageView.cpp -+++ b/tools/llvm-cov/SourceCoverageView.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- SourceCoverageView.cpp - Code coverage view for source code --------===// - // - // The LLVM Compiler Infrastructure -@@ -265,3 +266,4 @@ void SourceCoverageView::print(raw_ostream &OS, bool WholeFile, - - renderViewFooter(OS); - } -+#endif -diff --git a/tools/llvm-cov/SourceCoverageView.h b/tools/llvm-cov/SourceCoverageView.h -deleted file mode 100644 -index 9cb608fed60..00000000000 ---- a/tools/llvm-cov/SourceCoverageView.h -+++ /dev/null -@@ -1,289 +0,0 @@ --//===- SourceCoverageView.h - Code coverage view for source code ----------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This class implements rendering for code coverage of source code. --/// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_SOURCECOVERAGEVIEW_H --#define LLVM_COV_SOURCECOVERAGEVIEW_H -- --#include "CoverageViewOptions.h" --#include "llvm/ProfileData/Coverage/CoverageMapping.h" --#include "llvm/Support/MemoryBuffer.h" --#include -- --namespace llvm { -- --class SourceCoverageView; -- --/// \brief A view that represents a macro or include expansion. --struct ExpansionView { -- coverage::CounterMappingRegion Region; -- std::unique_ptr View; -- -- ExpansionView(const coverage::CounterMappingRegion &Region, -- std::unique_ptr View) -- : Region(Region), View(std::move(View)) {} -- ExpansionView(ExpansionView &&RHS) -- : Region(std::move(RHS.Region)), View(std::move(RHS.View)) {} -- ExpansionView &operator=(ExpansionView &&RHS) { -- Region = std::move(RHS.Region); -- View = std::move(RHS.View); -- return *this; -- } -- -- unsigned getLine() const { return Region.LineStart; } -- unsigned getStartCol() const { return Region.ColumnStart; } -- unsigned getEndCol() const { return Region.ColumnEnd; } -- -- friend bool operator<(const ExpansionView &LHS, const ExpansionView &RHS) { -- return LHS.Region.startLoc() < RHS.Region.startLoc(); -- } --}; -- --/// \brief A view that represents a function instantiation. --struct InstantiationView { -- StringRef FunctionName; -- unsigned Line; -- std::unique_ptr View; -- -- InstantiationView(StringRef FunctionName, unsigned Line, -- std::unique_ptr View) -- : FunctionName(FunctionName), Line(Line), View(std::move(View)) {} -- -- friend bool operator<(const InstantiationView &LHS, -- const InstantiationView &RHS) { -- return LHS.Line < RHS.Line; -- } --}; -- --/// \brief Coverage statistics for a single line. --struct LineCoverageStats { -- uint64_t ExecutionCount; -- unsigned RegionCount; -- bool Mapped; -- -- LineCoverageStats() : ExecutionCount(0), RegionCount(0), Mapped(false) {} -- -- bool isMapped() const { return Mapped; } -- -- bool hasMultipleRegions() const { return RegionCount > 1; } -- -- void addRegionStartCount(uint64_t Count) { -- // The max of all region starts is the most interesting value. -- addRegionCount(RegionCount ? std::max(ExecutionCount, Count) : Count); -- ++RegionCount; -- } -- -- void addRegionCount(uint64_t Count) { -- Mapped = true; -- ExecutionCount = Count; -- } --}; -- --/// \brief A file manager that handles format-aware file creation. --class CoveragePrinter { --public: -- struct StreamDestructor { -- void operator()(raw_ostream *OS) const; -- }; -- -- using OwnedStream = std::unique_ptr; -- --protected: -- const CoverageViewOptions &Opts; -- -- CoveragePrinter(const CoverageViewOptions &Opts) : Opts(Opts) {} -- -- /// \brief Return `OutputDir/ToplevelDir/Path.Extension`. If \p InToplevel is -- /// false, skip the ToplevelDir component. If \p Relative is false, skip the -- /// OutputDir component. -- std::string getOutputPath(StringRef Path, StringRef Extension, -- bool InToplevel, bool Relative = true) const; -- -- /// \brief If directory output is enabled, create a file in that directory -- /// at the path given by getOutputPath(). Otherwise, return stdout. -- Expected createOutputStream(StringRef Path, StringRef Extension, -- bool InToplevel) const; -- -- /// \brief Return the sub-directory name for file coverage reports. -- static StringRef getCoverageDir() { return "coverage"; } -- --public: -- static std::unique_ptr -- create(const CoverageViewOptions &Opts); -- -- virtual ~CoveragePrinter() {} -- -- /// @name File Creation Interface -- /// @{ -- -- /// \brief Create a file to print a coverage view into. -- virtual Expected createViewFile(StringRef Path, -- bool InToplevel) = 0; -- -- /// \brief Close a file which has been used to print a coverage view. -- virtual void closeViewFile(OwnedStream OS) = 0; -- -- /// \brief Create an index which lists reports for the given source files. -- virtual Error createIndexFile(ArrayRef SourceFiles, -- const coverage::CoverageMapping &Coverage) = 0; -- -- /// @} --}; -- --/// \brief A code coverage view of a source file or function. --/// --/// A source coverage view and its nested sub-views form a file-oriented --/// representation of code coverage data. This view can be printed out by a --/// renderer which implements the Rendering Interface. --class SourceCoverageView { -- /// A function or file name. -- StringRef SourceName; -- -- /// A memory buffer backing the source on display. -- const MemoryBuffer &File; -- -- /// Various options to guide the coverage renderer. -- const CoverageViewOptions &Options; -- -- /// Complete coverage information about the source on display. -- coverage::CoverageData CoverageInfo; -- -- /// A container for all expansions (e.g macros) in the source on display. -- std::vector ExpansionSubViews; -- -- /// A container for all instantiations (e.g template functions) in the source -- /// on display. -- std::vector InstantiationSubViews; -- -- /// Get the first uncovered line number for the source file. -- unsigned getFirstUncoveredLineNo(); -- --protected: -- struct LineRef { -- StringRef Line; -- int64_t LineNo; -- -- LineRef(StringRef Line, int64_t LineNo) : Line(Line), LineNo(LineNo) {} -- }; -- -- using CoverageSegmentArray = ArrayRef; -- -- /// @name Rendering Interface -- /// @{ -- -- /// \brief Render a header for the view. -- virtual void renderViewHeader(raw_ostream &OS) = 0; -- -- /// \brief Render a footer for the view. -- virtual void renderViewFooter(raw_ostream &OS) = 0; -- -- /// \brief Render the source name for the view. -- virtual void renderSourceName(raw_ostream &OS, bool WholeFile) = 0; -- -- /// \brief Render the line prefix at the given \p ViewDepth. -- virtual void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) = 0; -- -- /// \brief Render the line suffix at the given \p ViewDepth. -- virtual void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) = 0; -- -- /// \brief Render a view divider at the given \p ViewDepth. -- virtual void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) = 0; -- -- /// \brief Render a source line with highlighting. -- virtual void renderLine(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) = 0; -- -- /// \brief Render the line's execution count column. -- virtual void renderLineCoverageColumn(raw_ostream &OS, -- const LineCoverageStats &Line) = 0; -- -- /// \brief Render the line number column. -- virtual void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo) = 0; -- -- /// \brief Render all the region's execution counts on a line. -- virtual void renderRegionMarkers(raw_ostream &OS, -- CoverageSegmentArray Segments, -- unsigned ViewDepth) = 0; -- -- /// \brief Render the site of an expansion. -- virtual void -- renderExpansionSite(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) = 0; -- -- /// \brief Render an expansion view and any nested views. -- virtual void renderExpansionView(raw_ostream &OS, ExpansionView &ESV, -- unsigned ViewDepth) = 0; -- -- /// \brief Render an instantiation view and any nested views. -- virtual void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV, -- unsigned ViewDepth) = 0; -- -- /// \brief Render \p Title, a project title if one is available, and the -- /// created time. -- virtual void renderTitle(raw_ostream &OS, StringRef CellText) = 0; -- -- /// \brief Render the table header for a given source file. -- virtual void renderTableHeader(raw_ostream &OS, unsigned FirstUncoveredLineNo, -- unsigned IndentLevel) = 0; -- -- /// @} -- -- /// \brief Format a count using engineering notation with 3 significant -- /// digits. -- static std::string formatCount(uint64_t N); -- -- /// \brief Check if region marker output is expected for a line. -- bool shouldRenderRegionMarkers(bool LineHasMultipleRegions) const; -- -- /// \brief Check if there are any sub-views attached to this view. -- bool hasSubViews() const; -- -- SourceCoverageView(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo) -- : SourceName(SourceName), File(File), Options(Options), -- CoverageInfo(std::move(CoverageInfo)) {} -- --public: -- static std::unique_ptr -- create(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo); -- -- virtual ~SourceCoverageView() {} -- -- /// \brief Return the source name formatted for the host OS. -- std::string getSourceName() const; -- -- const CoverageViewOptions &getOptions() const { return Options; } -- -- /// \brief Add an expansion subview to this view. -- void addExpansion(const coverage::CounterMappingRegion &Region, -- std::unique_ptr View); -- -- /// \brief Add a function instantiation subview to this view. -- void addInstantiation(StringRef FunctionName, unsigned Line, -- std::unique_ptr View); -- -- /// \brief Print the code coverage information for a specific portion of a -- /// source file to the output stream. -- void print(raw_ostream &OS, bool WholeFile, bool ShowSourceName, -- unsigned ViewDepth = 0); --}; -- --} // namespace llvm -- --#endif // LLVM_COV_SOURCECOVERAGEVIEW_H -diff --git a/tools/llvm-cov/SourceCoverageViewHTML.cpp b/tools/llvm-cov/SourceCoverageViewHTML.cpp -index 64b888e89d7..929b224b66b 100644 ---- a/tools/llvm-cov/SourceCoverageViewHTML.cpp -+++ b/tools/llvm-cov/SourceCoverageViewHTML.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- SourceCoverageViewHTML.cpp - A html code coverage view -------------===// - // - // The LLVM Compiler Infrastructure -@@ -636,3 +637,5 @@ void SourceCoverageViewHTML::renderTableHeader(raw_ostream &OS, - << SourceLabel; - renderLineSuffix(OS, ViewDepth); - } -+ -+#endif -diff --git a/tools/llvm-cov/SourceCoverageViewHTML.h b/tools/llvm-cov/SourceCoverageViewHTML.h -deleted file mode 100644 -index 94b08a5e7fc..00000000000 ---- a/tools/llvm-cov/SourceCoverageViewHTML.h -+++ /dev/null -@@ -1,96 +0,0 @@ --//===- SourceCoverageViewHTML.h - A html code coverage view ---------------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This file defines the interface to the html coverage renderer. --/// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_SOURCECOVERAGEVIEWHTML_H --#define LLVM_COV_SOURCECOVERAGEVIEWHTML_H -- --#include "SourceCoverageView.h" -- --namespace llvm { -- --struct FileCoverageSummary; -- --/// \brief A coverage printer for html output. --class CoveragePrinterHTML : public CoveragePrinter { --public: -- Expected createViewFile(StringRef Path, -- bool InToplevel) override; -- -- void closeViewFile(OwnedStream OS) override; -- -- Error createIndexFile(ArrayRef SourceFiles, -- const coverage::CoverageMapping &Coverage) override; -- -- CoveragePrinterHTML(const CoverageViewOptions &Opts) -- : CoveragePrinter(Opts) {} -- --private: -- void emitFileSummary(raw_ostream &OS, StringRef SF, -- const FileCoverageSummary &FCS, -- bool IsTotals = false) const; --}; -- --/// \brief A code coverage view which supports html-based rendering. --class SourceCoverageViewHTML : public SourceCoverageView { -- void renderViewHeader(raw_ostream &OS) override; -- -- void renderViewFooter(raw_ostream &OS) override; -- -- void renderSourceName(raw_ostream &OS, bool WholeFile) override; -- -- void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLine(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionSite(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionView(raw_ostream &OS, ExpansionView &ESV, -- unsigned ViewDepth) override; -- -- void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV, -- unsigned ViewDepth) override; -- -- void renderLineCoverageColumn(raw_ostream &OS, -- const LineCoverageStats &Line) override; -- -- void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo) override; -- -- void renderRegionMarkers(raw_ostream &OS, CoverageSegmentArray Segments, -- unsigned ViewDepth) override; -- -- void renderTitle(raw_ostream &OS, StringRef Title) override; -- -- void renderTableHeader(raw_ostream &OS, unsigned FirstUncoveredLineNo, -- unsigned IndentLevel) override; -- --public: -- SourceCoverageViewHTML(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo) -- : SourceCoverageView(SourceName, File, Options, std::move(CoverageInfo)) { -- } --}; -- --} // namespace llvm -- --#endif // LLVM_COV_SOURCECOVERAGEVIEWHTML_H -diff --git a/tools/llvm-cov/SourceCoverageViewText.cpp b/tools/llvm-cov/SourceCoverageViewText.cpp -index 4ad120f642e..03422a36a37 100644 ---- a/tools/llvm-cov/SourceCoverageViewText.cpp -+++ b/tools/llvm-cov/SourceCoverageViewText.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- SourceCoverageViewText.cpp - A text-based code coverage view -------===// - // - // The LLVM Compiler Infrastructure -@@ -237,3 +238,5 @@ void SourceCoverageViewText::renderTitle(raw_ostream &OS, StringRef Title) { - - void SourceCoverageViewText::renderTableHeader(raw_ostream &, unsigned, - unsigned) {} -+ -+#endif -diff --git a/tools/llvm-cov/SourceCoverageViewText.h b/tools/llvm-cov/SourceCoverageViewText.h -deleted file mode 100644 -index c3f20de9297..00000000000 ---- a/tools/llvm-cov/SourceCoverageViewText.h -+++ /dev/null -@@ -1,89 +0,0 @@ --//===- SourceCoverageViewText.h - A text-based code coverage view ---------===// --// --// The LLVM Compiler Infrastructure --// --// This file is distributed under the University of Illinois Open Source --// License. See LICENSE.TXT for details. --// --//===----------------------------------------------------------------------===// --/// --/// \file This file defines the interface to the text-based coverage renderer. --/// --//===----------------------------------------------------------------------===// -- --#ifndef LLVM_COV_SOURCECOVERAGEVIEWTEXT_H --#define LLVM_COV_SOURCECOVERAGEVIEWTEXT_H -- --#include "SourceCoverageView.h" -- --namespace llvm { -- --/// \brief A coverage printer for text output. --class CoveragePrinterText : public CoveragePrinter { --public: -- Expected createViewFile(StringRef Path, -- bool InToplevel) override; -- -- void closeViewFile(OwnedStream OS) override; -- -- Error createIndexFile(ArrayRef SourceFiles, -- const coverage::CoverageMapping &Coverage) override; -- -- CoveragePrinterText(const CoverageViewOptions &Opts) -- : CoveragePrinter(Opts) {} --}; -- --/// \brief A code coverage view which supports text-based rendering. --class SourceCoverageViewText : public SourceCoverageView { -- void renderViewHeader(raw_ostream &OS) override; -- -- void renderViewFooter(raw_ostream &OS) override; -- -- void renderSourceName(raw_ostream &OS, bool WholeFile) override; -- -- void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) override; -- -- void renderLine(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionSite(raw_ostream &OS, LineRef L, -- const coverage::CoverageSegment *WrappedSegment, -- CoverageSegmentArray Segments, unsigned ExpansionCol, -- unsigned ViewDepth) override; -- -- void renderExpansionView(raw_ostream &OS, ExpansionView &ESV, -- unsigned ViewDepth) override; -- -- void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV, -- unsigned ViewDepth) override; -- -- void renderLineCoverageColumn(raw_ostream &OS, -- const LineCoverageStats &Line) override; -- -- void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo) override; -- -- void renderRegionMarkers(raw_ostream &OS, CoverageSegmentArray Segments, -- unsigned ViewDepth) override; -- -- void renderTitle(raw_ostream &OS, StringRef Title) override; -- -- void renderTableHeader(raw_ostream &OS, unsigned FirstUncoveredLineNo, -- unsigned IndentLevel) override; -- --public: -- SourceCoverageViewText(StringRef SourceName, const MemoryBuffer &File, -- const CoverageViewOptions &Options, -- coverage::CoverageData &&CoverageInfo) -- : SourceCoverageView(SourceName, File, Options, std::move(CoverageInfo)) { -- } --}; -- --} // namespace llvm -- --#endif // LLVM_COV_SOURCECOVERAGEVIEWTEXT_H -diff --git a/tools/llvm-cov/TestingSupport.cpp b/tools/llvm-cov/TestingSupport.cpp -index 4713d75f17d..5c2916220dc 100644 ---- a/tools/llvm-cov/TestingSupport.cpp -+++ b/tools/llvm-cov/TestingSupport.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- TestingSupport.cpp - Convert objects files into test files --------===// - // - // The LLVM Compiler Infrastructure -@@ -93,3 +94,4 @@ int convertForTestingMain(int argc, const char *argv[]) { - - return 0; - } -+#endif -diff --git a/tools/llvm-cov/gcov.cpp b/tools/llvm-cov/gcov.cpp -index 4df7f015fd1..7790789b522 100644 ---- a/tools/llvm-cov/gcov.cpp -+++ b/tools/llvm-cov/gcov.cpp -@@ -1,3 +1,4 @@ -+#if 0 - //===- gcov.cpp - GCOV compatible LLVM coverage tool ----------------------===// - // - // The LLVM Compiler Infrastructure -@@ -143,3 +144,4 @@ int gcovMain(int argc, const char *argv[]) { - Options); - return 0; - } -+#endif -diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp -index 15841587025..5103688cd7c 100644 ---- a/tools/llvm-cov/llvm-cov.cpp -+++ b/tools/llvm-cov/llvm-cov.cpp -@@ -11,6 +11,7 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 - #include "llvm/ADT/StringRef.h" - #include "llvm/ADT/StringSwitch.h" - #include "llvm/Support/CommandLine.h" -@@ -57,8 +58,10 @@ static int versionMain(int argc, const char *argv[]) { - cl::PrintVersionMessage(); - return 0; - } -+#endif - - int main(int argc, const char **argv) { -+#if 0 - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(argv[0]); - PrettyStackTraceProgram X(argc, argv); -@@ -96,5 +99,6 @@ int main(int argc, const char **argv) { - errs().resetColor(); - } - helpMain(argc, argv); -+#endif - return 1; - } -diff --git a/tools/llvm-profdata/llvm-profdata.cpp b/tools/llvm-profdata/llvm-profdata.cpp -index eee242107da..595dc0e2c64 100644 ---- a/tools/llvm-profdata/llvm-profdata.cpp -+++ b/tools/llvm-profdata/llvm-profdata.cpp -@@ -11,6 +11,8 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 -+ - #include "llvm/ADT/SmallSet.h" - #include "llvm/ADT/SmallVector.h" - #include "llvm/ADT/StringRef.h" -@@ -754,8 +756,10 @@ static int show_main(int argc, const char *argv[]) { - return showSampleProfile(Filename, ShowCounts, ShowAllFunctions, - ShowFunction, OS); - } -+#endif - - int main(int argc, const char *argv[]) { -+#if 0 - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(argv[0]); - PrettyStackTraceProgram X(argc, argv); -@@ -794,5 +798,6 @@ int main(int argc, const char *argv[]) { - errs() << ProgName << ": Unknown command!\n"; - - errs() << "USAGE: " << ProgName << " [args...]\n"; -+#endif - return 1; - } -diff --git a/tools/sancov/sancov.cc b/tools/sancov/sancov.cc -index 7f103ebb904..31de719f8c8 100644 ---- a/tools/sancov/sancov.cc -+++ b/tools/sancov/sancov.cc -@@ -10,6 +10,7 @@ - // This file is a command-line tool for reading and analyzing sanitizer - // coverage. - //===----------------------------------------------------------------------===// -+#if 0 - #include "llvm/ADT/STLExtras.h" - #include "llvm/ADT/StringExtras.h" - #include "llvm/ADT/Twine.h" -@@ -1199,8 +1200,10 @@ readSymbolizeAndMergeCmdArguments(std::vector FileNames) { - } - - } // namespace -+#endif - - int main(int Argc, char **Argv) { -+#if 0 - // Print stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(Argv[0]); - PrettyStackTraceProgram X(Argc, Argv); -@@ -1264,4 +1267,6 @@ int main(int Argc, char **Argv) { - case PrintCovPointsAction: - llvm_unreachable("unsupported action"); - } -+#endif -+ return 1; - } -diff --git a/unittests/Support/ThreadPool.cpp b/unittests/Support/ThreadPool.cpp -index 0da33ad50c0..50287484f29 100644 ---- a/unittests/Support/ThreadPool.cpp -+++ b/unittests/Support/ThreadPool.cpp -@@ -7,6 +7,8 @@ - // - //===----------------------------------------------------------------------===// - -+#if 0 -+ - #include "llvm/Support/ThreadPool.h" - - #include "llvm/ADT/STLExtras.h" -@@ -164,3 +166,5 @@ TEST_F(ThreadPoolTest, PoolDestruction) { - } - ASSERT_EQ(5, checked_in); - } -+ -+#endif --- -2.14.1 - diff --git a/deps/patches/llvm-D23597_sdag_names.patch b/deps/patches/llvm-D23597_sdag_names.patch deleted file mode 100644 index 9eea510f7d62f..0000000000000 --- a/deps/patches/llvm-D23597_sdag_names.patch +++ /dev/null @@ -1,796 +0,0 @@ -Index: include/llvm/Target/TargetSelectionDAG.td -=================================================================== ---- a/include/llvm/Target/TargetSelectionDAG.td -+++ b/include/llvm/Target/TargetSelectionDAG.td -@@ -450,10 +450,10 @@ - def fceil : SDNode<"ISD::FCEIL" , SDTFPUnaryOp>; - def ffloor : SDNode<"ISD::FFLOOR" , SDTFPUnaryOp>; - def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>; --def frnd : SDNode<"ISD::FROUND" , SDTFPUnaryOp>; -+def fround : SDNode<"ISD::FROUND" , SDTFPUnaryOp>; - --def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; --def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; -+def fpround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; -+def fpextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; - def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPSignOp>; - - def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>; -Index: lib/Target/AArch64/AArch64InstrFormats.td -=================================================================== ---- a/lib/Target/AArch64/AArch64InstrFormats.td -+++ b/lib/Target/AArch64/AArch64InstrFormats.td -@@ -3936,27 +3936,27 @@ - multiclass FPConversion { - // Double-precision to Half-precision - def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, -- [(set FPR16:$Rd, (fround FPR64:$Rn))]>; -+ [(set FPR16:$Rd, (fpround FPR64:$Rn))]>; - - // Double-precision to Single-precision - def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, -- [(set FPR32:$Rd, (fround FPR64:$Rn))]>; -+ [(set FPR32:$Rd, (fpround FPR64:$Rn))]>; - - // Half-precision to Double-precision - def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, -- [(set FPR64:$Rd, (fextend FPR16:$Rn))]>; -+ [(set FPR64:$Rd, (fpextend FPR16:$Rn))]>; - - // Half-precision to Single-precision - def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, -- [(set FPR32:$Rd, (fextend FPR16:$Rn))]>; -+ [(set FPR32:$Rd, (fpextend FPR16:$Rn))]>; - - // Single-precision to Double-precision - def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, -- [(set FPR64:$Rd, (fextend FPR32:$Rn))]>; -+ [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>; - - // Single-precision to Half-precision - def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, -- [(set FPR16:$Rd, (fround FPR32:$Rn))]>; -+ [(set FPR16:$Rd, (fpround FPR32:$Rn))]>; - } - - //--- -Index: lib/Target/AArch64/AArch64InstrInfo.td -=================================================================== ---- a/lib/Target/AArch64/AArch64InstrInfo.td -+++ b/lib/Target/AArch64/AArch64InstrInfo.td -@@ -2545,8 +2545,8 @@ - defm : FPToIntegerPats; - defm : FPToIntegerPats; - defm : FPToIntegerPats; --defm : FPToIntegerPats; --defm : FPToIntegerPats; -+defm : FPToIntegerPats; -+defm : FPToIntegerPats; - - //===----------------------------------------------------------------------===// - // Scaled integer to floating point conversion instructions. -@@ -2582,7 +2582,7 @@ - defm FABS : SingleOperandFPData<0b0001, "fabs", fabs>; - defm FMOV : SingleOperandFPData<0b0000, "fmov">; - defm FNEG : SingleOperandFPData<0b0010, "fneg", fneg>; --defm FRINTA : SingleOperandFPData<0b1100, "frinta", frnd>; -+defm FRINTA : SingleOperandFPData<0b1100, "frinta", fround>; - defm FRINTI : SingleOperandFPData<0b1111, "frinti", fnearbyint>; - defm FRINTM : SingleOperandFPData<0b1010, "frintm", ffloor>; - defm FRINTN : SingleOperandFPData<0b1000, "frintn", int_aarch64_neon_frintn>; -@@ -2788,13 +2788,13 @@ - def : Pat<(v4f32 (int_aarch64_neon_vcvthf2fp (extract_subvector (v8i16 V128:$Rn), - (i64 4)))), - (FCVTLv8i16 V128:$Rn)>; --def : Pat<(v2f64 (fextend (v2f32 V64:$Rn))), (FCVTLv2i32 V64:$Rn)>; --def : Pat<(v2f64 (fextend (v2f32 (extract_subvector (v4f32 V128:$Rn), -+def : Pat<(v2f64 (fpextend (v2f32 V64:$Rn))), (FCVTLv2i32 V64:$Rn)>; -+def : Pat<(v2f64 (fpextend (v2f32 (extract_subvector (v4f32 V128:$Rn), - (i64 2))))), - (FCVTLv4i32 V128:$Rn)>; - --def : Pat<(v4f32 (fextend (v4f16 V64:$Rn))), (FCVTLv4i16 V64:$Rn)>; --def : Pat<(v4f32 (fextend (v4f16 (extract_subvector (v8f16 V128:$Rn), -+def : Pat<(v4f32 (fpextend (v4f16 V64:$Rn))), (FCVTLv4i16 V64:$Rn)>; -+def : Pat<(v4f32 (fpextend (v4f16 (extract_subvector (v8f16 V128:$Rn), - (i64 4))))), - (FCVTLv8i16 V128:$Rn)>; - -@@ -2808,9 +2808,9 @@ - def : Pat<(concat_vectors V64:$Rd, - (v4i16 (int_aarch64_neon_vcvtfp2hf (v4f32 V128:$Rn)))), - (FCVTNv8i16 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; --def : Pat<(v2f32 (fround (v2f64 V128:$Rn))), (FCVTNv2i32 V128:$Rn)>; --def : Pat<(v4f16 (fround (v4f32 V128:$Rn))), (FCVTNv4i16 V128:$Rn)>; --def : Pat<(concat_vectors V64:$Rd, (v2f32 (fround (v2f64 V128:$Rn)))), -+def : Pat<(v2f32 (fpround (v2f64 V128:$Rn))), (FCVTNv2i32 V128:$Rn)>; -+def : Pat<(v4f16 (fpround (v4f32 V128:$Rn))), (FCVTNv4i16 V128:$Rn)>; -+def : Pat<(concat_vectors V64:$Rd, (v2f32 (fpround (v2f64 V128:$Rn)))), - (FCVTNv4i32 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; - defm FCVTPS : SIMDTwoVectorFPToInt<0,1,0b11010, "fcvtps",int_aarch64_neon_fcvtps>; - defm FCVTPU : SIMDTwoVectorFPToInt<1,1,0b11010, "fcvtpu",int_aarch64_neon_fcvtpu>; -@@ -2833,7 +2833,7 @@ - - defm FNEG : SIMDTwoVectorFP<1, 1, 0b01111, "fneg", fneg>; - defm FRECPE : SIMDTwoVectorFP<0, 1, 0b11101, "frecpe", int_aarch64_neon_frecpe>; --defm FRINTA : SIMDTwoVectorFP<1, 0, 0b11000, "frinta", frnd>; -+defm FRINTA : SIMDTwoVectorFP<1, 0, 0b11000, "frinta", fround>; - defm FRINTI : SIMDTwoVectorFP<1, 1, 0b11001, "frinti", fnearbyint>; - defm FRINTM : SIMDTwoVectorFP<0, 0, 0b11001, "frintm", ffloor>; - defm FRINTN : SIMDTwoVectorFP<0, 0, 0b11000, "frintn", int_aarch64_neon_frintn>; -Index: lib/Target/AMDGPU/SIInstructions.td -=================================================================== ---- a/lib/Target/AMDGPU/SIInstructions.td -+++ b/lib/Target/AMDGPU/SIInstructions.td -@@ -1107,10 +1107,10 @@ - VOP_I32_F32, cvt_flr_i32_f32>; - defm V_CVT_OFF_F32_I4 : VOP1Inst , "v_cvt_off_f32_i4", VOP_F32_I32>; - defm V_CVT_F32_F64 : VOP1Inst , "v_cvt_f32_f64", -- VOP_F32_F64, fround -+ VOP_F32_F64, fpround - >; - defm V_CVT_F64_F32 : VOP1Inst , "v_cvt_f64_f32", -- VOP_F64_F32, fextend -+ VOP_F64_F32, fpextend - >; - defm V_CVT_F32_UBYTE0 : VOP1Inst , "v_cvt_f32_ubyte0", - VOP_F32_I32, AMDGPUcvt_f32_ubyte0 -Index: lib/Target/ARM/ARMInstrVFP.td -=================================================================== ---- a/lib/Target/ARM/ARMInstrVFP.td -+++ b/lib/Target/ARM/ARMInstrVFP.td -@@ -624,7 +624,7 @@ - def VCVTDS : ASuI<0b11101, 0b11, 0b0111, 0b11, 0, - (outs DPR:$Dd), (ins SPR:$Sm), - IIC_fpCVTDS, "vcvt", ".f64.f32\t$Dd, $Sm", -- [(set DPR:$Dd, (fextend SPR:$Sm))]> { -+ [(set DPR:$Dd, (fpextend SPR:$Sm))]> { - // Instruction operands. - bits<5> Dd; - bits<5> Sm; -@@ -641,7 +641,7 @@ - // Special case encoding: bits 11-8 is 0b1011. - def VCVTSD : VFPAI<(outs SPR:$Sd), (ins DPR:$Dm), VFPUnaryFrm, - IIC_fpCVTSD, "vcvt", ".f32.f64\t$Sd, $Dm", -- [(set SPR:$Sd, (fround DPR:$Dm))]> { -+ [(set SPR:$Sd, (fpround DPR:$Dm))]> { - // Instruction operands. - bits<5> Sd; - bits<5> Dm; -@@ -838,7 +838,7 @@ - } - } - --defm VCVTA : vcvt_inst<"a", 0b00, frnd>; -+defm VCVTA : vcvt_inst<"a", 0b00, fround>; - defm VCVTN : vcvt_inst<"n", 0b01>; - defm VCVTP : vcvt_inst<"p", 0b10, fceil>; - defm VCVTM : vcvt_inst<"m", 0b11, ffloor>; -@@ -938,7 +938,7 @@ - Requires<[HasFPARMv8,HasDPVFP]>; - } - --defm VRINTA : vrint_inst_anpm<"a", 0b00, frnd>; -+defm VRINTA : vrint_inst_anpm<"a", 0b00, fround>; - defm VRINTN : vrint_inst_anpm<"n", 0b01>; - defm VRINTP : vrint_inst_anpm<"p", 0b10, fceil>; - defm VRINTM : vrint_inst_anpm<"m", 0b11, ffloor>; -Index: lib/Target/Hexagon/HexagonISelLowering.cpp -=================================================================== ---- a/lib/Target/Hexagon/HexagonISelLowering.cpp -+++ b/lib/Target/Hexagon/HexagonISelLowering.cpp -@@ -1906,7 +1906,7 @@ - } - // Turn FP truncstore into trunc + store. - setTruncStoreAction(MVT::f64, MVT::f32, Expand); -- // Turn FP extload into load/fextend. -+ // Turn FP extload into load/fpextend. - for (MVT VT : MVT::fp_valuetypes()) - setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand); - -Index: lib/Target/Hexagon/HexagonInstrInfoV5.td -=================================================================== ---- a/lib/Target/Hexagon/HexagonInstrInfoV5.td -+++ b/lib/Target/Hexagon/HexagonInstrInfoV5.td -@@ -564,10 +564,10 @@ - - // Convert single precision to double precision and vice-versa. - def F2_conv_sf2df : F2_RDD_RS_CONVERT <"convert_sf2df", 0b000, -- fextend, F64, F32>; -+ fpextend, F64, F32>; - - def F2_conv_df2sf : F2_RD_RSS_CONVERT <"convert_df2sf", 0b000, -- fround, F32, F64>; -+ fpround, F32, F64>; - - // Convert Integer to Floating Point. - def F2_conv_d2sf : F2_RD_RSS_CONVERT <"convert_d2sf", 0b010, -Index: lib/Target/Mips/MipsInstrFPU.td -=================================================================== ---- a/lib/Target/Mips/MipsInstrFPU.td -+++ b/lib/Target/Mips/MipsInstrFPU.td -@@ -635,9 +635,9 @@ - (PseudoCVT_D32_W GPR32Opnd:$src)>, FGR_32; - def : MipsPat<(MipsTruncIntFP AFGR64Opnd:$src), - (TRUNC_W_D32 AFGR64Opnd:$src)>, FGR_32; --def : MipsPat<(f32 (fround AFGR64Opnd:$src)), -+def : MipsPat<(f32 (fpround AFGR64Opnd:$src)), - (CVT_S_D32 AFGR64Opnd:$src)>, FGR_32; --def : MipsPat<(f64 (fextend FGR32Opnd:$src)), -+def : MipsPat<(f64 (fpextend FGR32Opnd:$src)), - (CVT_D32_S FGR32Opnd:$src)>, FGR_32; - - def : MipsPat<(f64 fpimm0), (DMTC1 ZERO_64)>, FGR_64; -@@ -657,9 +657,9 @@ - def : MipsPat<(MipsTruncIntFP FGR64Opnd:$src), - (TRUNC_L_D64 FGR64Opnd:$src)>, FGR_64; - --def : MipsPat<(f32 (fround FGR64Opnd:$src)), -+def : MipsPat<(f32 (fpround FGR64Opnd:$src)), - (CVT_S_D64 FGR64Opnd:$src)>, FGR_64; --def : MipsPat<(f64 (fextend FGR32Opnd:$src)), -+def : MipsPat<(f64 (fpextend FGR32Opnd:$src)), - (CVT_D64_S FGR32Opnd:$src)>, FGR_64; - - // Patterns for loads/stores with a reg+imm operand. -Index: lib/Target/NVPTX/NVPTXISelLowering.cpp -=================================================================== ---- a/lib/Target/NVPTX/NVPTXISelLowering.cpp -+++ b/lib/Target/NVPTX/NVPTXISelLowering.cpp -@@ -206,7 +206,7 @@ - // intrinsics. - setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); - -- // Turn FP extload into load/fextend -+ // Turn FP extload into load/fpextend - setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand); - setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand); - setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand); -Index: lib/Target/NVPTX/NVPTXInstrInfo.td -=================================================================== ---- a/lib/Target/NVPTX/NVPTXInstrInfo.td -+++ b/lib/Target/NVPTX/NVPTXInstrInfo.td -@@ -2613,16 +2613,16 @@ - def : Pat<(ctpop Int16Regs:$a), - (CVT_u16_u32 (POPCr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE)), CvtNONE)>; - --// fround f64 -> f32 --def : Pat<(f32 (fround Float64Regs:$a)), -+// fpround f64 -> f32 -+def : Pat<(f32 (fpround Float64Regs:$a)), - (CVT_f32_f64 Float64Regs:$a, CvtRN_FTZ)>, Requires<[doF32FTZ]>; --def : Pat<(f32 (fround Float64Regs:$a)), -+def : Pat<(f32 (fpround Float64Regs:$a)), - (CVT_f32_f64 Float64Regs:$a, CvtRN)>; - --// fextend f32 -> f64 --def : Pat<(f64 (fextend Float32Regs:$a)), -+// fpextend f32 -> f64 -+def : Pat<(f64 (fpextend Float32Regs:$a)), - (CVT_f64_f32 Float32Regs:$a, CvtNONE_FTZ)>, Requires<[doF32FTZ]>; --def : Pat<(f64 (fextend Float32Regs:$a)), -+def : Pat<(f64 (fpextend Float32Regs:$a)), - (CVT_f64_f32 Float32Regs:$a, CvtNONE)>; - - def retflag : SDNode<"NVPTXISD::RET_FLAG", SDTNone, -Index: lib/Target/PowerPC/PPCInstrInfo.td -=================================================================== ---- a/lib/Target/PowerPC/PPCInstrInfo.td -+++ b/lib/Target/PowerPC/PPCInstrInfo.td -@@ -2110,15 +2110,15 @@ - - defm FRSP : XForm_26r<63, 12, (outs f4rc:$frD), (ins f8rc:$frB), - "frsp", "$frD, $frB", IIC_FPGeneral, -- [(set f32:$frD, (fround f64:$frB))]>; -+ [(set f32:$frD, (fpround f64:$frB))]>; - - let Interpretation64Bit = 1, isCodeGenOnly = 1 in - defm FRIND : XForm_26r<63, 392, (outs f8rc:$frD), (ins f8rc:$frB), - "frin", "$frD, $frB", IIC_FPGeneral, -- [(set f64:$frD, (frnd f64:$frB))]>; -+ [(set f64:$frD, (fround f64:$frB))]>; - defm FRINS : XForm_26r<63, 392, (outs f4rc:$frD), (ins f4rc:$frB), - "frin", "$frD, $frB", IIC_FPGeneral, -- [(set f32:$frD, (frnd f32:$frB))]>; -+ [(set f32:$frD, (fround f32:$frB))]>; - } - - let hasSideEffects = 0 in { -@@ -2856,7 +2856,7 @@ - def : Pat<(f64 (extloadf32 xaddr:$src)), - (COPY_TO_REGCLASS (LFSX xaddr:$src), F8RC)>; - --def : Pat<(f64 (fextend f32:$src)), -+def : Pat<(f64 (fpextend f32:$src)), - (COPY_TO_REGCLASS $src, F8RC)>; - - // Only seq_cst fences require the heavyweight sync (SYNC 0). -Index: lib/Target/PowerPC/PPCInstrQPX.td -=================================================================== ---- a/lib/Target/PowerPC/PPCInstrQPX.td -+++ b/lib/Target/PowerPC/PPCInstrQPX.td -@@ -88,11 +88,11 @@ - return cast(N)->getMemoryVT() == MVT::v4f32; - }]>; - --def fround_inexact : PatFrag<(ops node:$val), (fround node:$val), [{ -+def fround_inexact : PatFrag<(ops node:$val), (fpround node:$val), [{ - return cast(N->getOperand(1))->getZExtValue() == 0; - }]>; - --def fround_exact : PatFrag<(ops node:$val), (fround node:$val), [{ -+def fround_exact : PatFrag<(ops node:$val), (fpround node:$val), [{ - return cast(N->getOperand(1))->getZExtValue() == 1; - }]>; - -@@ -311,11 +311,11 @@ - - def QVFRIN : XForm_19<4, 392, (outs qfrc:$FRT), (ins qfrc:$FRB), - "qvfrin $FRT, $FRB", IIC_FPGeneral, -- [(set v4f64:$FRT, (frnd v4f64:$FRB))]>; -+ [(set v4f64:$FRT, (fround v4f64:$FRB))]>; - let isCodeGenOnly = 1 in - def QVFRINs : XForm_19<4, 392, (outs qsrc:$FRT), (ins qsrc:$FRB), - "qvfrin $FRT, $FRB", IIC_FPGeneral, -- [(set v4f32:$FRT, (frnd v4f32:$FRB))]>; -+ [(set v4f32:$FRT, (fround v4f32:$FRB))]>; - - def QVFRIP : XForm_19<4, 456, (outs qfrc:$FRT), (ins qfrc:$FRB), - "qvfrip $FRT, $FRB", IIC_FPGeneral, -@@ -1103,7 +1103,7 @@ - def : Pat<(not v4i1:$FRA), - (QVFLOGICALb $FRA, $FRA, (i32 10))>; - --def : Pat<(v4f64 (fextend v4f32:$src)), -+def : Pat<(v4f64 (fpextend v4f32:$src)), - (COPY_TO_REGCLASS $src, QFRC)>; - - def : Pat<(v4f32 (fround_exact v4f64:$src)), -Index: lib/Target/PowerPC/PPCInstrVSX.td -=================================================================== ---- a/lib/Target/PowerPC/PPCInstrVSX.td -+++ b/lib/Target/PowerPC/PPCInstrVSX.td -@@ -634,7 +634,7 @@ - def XSRDPI : XX2Form<60, 73, - (outs vsfrc:$XT), (ins vsfrc:$XB), - "xsrdpi $XT, $XB", IIC_VecFP, -- [(set f64:$XT, (frnd f64:$XB))]>; -+ [(set f64:$XT, (fround f64:$XB))]>; - def XSRDPIC : XX2Form<60, 107, - (outs vsfrc:$XT), (ins vsfrc:$XB), - "xsrdpic $XT, $XB", IIC_VecFP, -@@ -655,7 +655,7 @@ - def XVRDPI : XX2Form<60, 201, - (outs vsrc:$XT), (ins vsrc:$XB), - "xvrdpi $XT, $XB", IIC_VecFP, -- [(set v2f64:$XT, (frnd v2f64:$XB))]>; -+ [(set v2f64:$XT, (fround v2f64:$XB))]>; - def XVRDPIC : XX2Form<60, 235, - (outs vsrc:$XT), (ins vsrc:$XB), - "xvrdpic $XT, $XB", IIC_VecFP, -@@ -676,7 +676,7 @@ - def XVRSPI : XX2Form<60, 137, - (outs vsrc:$XT), (ins vsrc:$XB), - "xvrspi $XT, $XB", IIC_VecFP, -- [(set v4f32:$XT, (frnd v4f32:$XB))]>; -+ [(set v4f32:$XT, (fround v4f32:$XB))]>; - def XVRSPIC : XX2Form<60, 171, - (outs vsrc:$XT), (ins vsrc:$XB), - "xvrspic $XT, $XB", IIC_VecFP, -@@ -1108,7 +1108,7 @@ - - def : Pat<(f64 (extloadf32 xoaddr:$src)), - (COPY_TO_REGCLASS (LXSSPX xoaddr:$src), VSFRC)>; -- def : Pat<(f64 (fextend f32:$src)), -+ def : Pat<(f64 (fpextend f32:$src)), - (COPY_TO_REGCLASS $src, VSFRC)>; - - def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)), -Index: lib/Target/Sparc/SparcISelLowering.cpp -=================================================================== ---- a/lib/Target/Sparc/SparcISelLowering.cpp -+++ b/lib/Target/Sparc/SparcISelLowering.cpp -@@ -1508,7 +1508,7 @@ - // AddPromotedToType(ISD::STORE, MVT::i64, MVT::v2i32); - } - -- // Turn FP extload into load/fextend -+ // Turn FP extload into load/fpextend - for (MVT VT : MVT::fp_valuetypes()) { - setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand); - setLoadExtAction(ISD::EXTLOAD, VT, MVT::f64, Expand); -Index: lib/Target/Sparc/SparcInstrInfo.td -=================================================================== ---- a/lib/Target/Sparc/SparcInstrInfo.td -+++ b/lib/Target/Sparc/SparcInstrInfo.td -@@ -1131,32 +1131,32 @@ - def FSTOD : F3_3u<2, 0b110100, 0b011001001, - (outs DFPRegs:$rd), (ins FPRegs:$rs2), - "fstod $rs2, $rd", -- [(set f64:$rd, (fextend f32:$rs2))], -+ [(set f64:$rd, (fpextend f32:$rs2))], - IIC_fpu_stod>; - def FSTOQ : F3_3u<2, 0b110100, 0b011001101, - (outs QFPRegs:$rd), (ins FPRegs:$rs2), - "fstoq $rs2, $rd", -- [(set f128:$rd, (fextend f32:$rs2))]>, -+ [(set f128:$rd, (fpextend f32:$rs2))]>, - Requires<[HasHardQuad]>; - def FDTOS : F3_3u<2, 0b110100, 0b011000110, - (outs FPRegs:$rd), (ins DFPRegs:$rs2), - "fdtos $rs2, $rd", -- [(set f32:$rd, (fround f64:$rs2))], -+ [(set f32:$rd, (fpround f64:$rs2))], - IIC_fpu_fast_instr>; - def FDTOQ : F3_3u<2, 0b110100, 0b011001110, - (outs QFPRegs:$rd), (ins DFPRegs:$rs2), - "fdtoq $rs2, $rd", -- [(set f128:$rd, (fextend f64:$rs2))]>, -+ [(set f128:$rd, (fpextend f64:$rs2))]>, - Requires<[HasHardQuad]>; - def FQTOS : F3_3u<2, 0b110100, 0b011000111, - (outs FPRegs:$rd), (ins QFPRegs:$rs2), - "fqtos $rs2, $rd", -- [(set f32:$rd, (fround f128:$rs2))]>, -+ [(set f32:$rd, (fpround f128:$rs2))]>, - Requires<[HasHardQuad]>; - def FQTOD : F3_3u<2, 0b110100, 0b011001011, - (outs DFPRegs:$rd), (ins QFPRegs:$rs2), - "fqtod $rs2, $rd", -- [(set f64:$rd, (fround f128:$rs2))]>, -+ [(set f64:$rd, (fpround f128:$rs2))]>, - Requires<[HasHardQuad]>; - - // Floating-point Move Instructions, p. 144 -@@ -1255,14 +1255,14 @@ - def FSMULD : F3_3<2, 0b110100, 0b001101001, - (outs DFPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), - "fsmuld $rs1, $rs2, $rd", -- [(set f64:$rd, (fmul (fextend f32:$rs1), -- (fextend f32:$rs2)))], -+ [(set f64:$rd, (fmul (fpextend f32:$rs1), -+ (fpextend f32:$rs2)))], - IIC_fpu_muld>; - def FDMULQ : F3_3<2, 0b110100, 0b001101110, - (outs QFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), - "fdmulq $rs1, $rs2, $rd", -- [(set f128:$rd, (fmul (fextend f64:$rs1), -- (fextend f64:$rs2)))]>, -+ [(set f128:$rd, (fmul (fpextend f64:$rs1), -+ (fpextend f64:$rs2)))]>, - Requires<[HasHardQuad]>; - - // FDIVS generates an erratum on LEON processors, so by disabling this instruction -Index: lib/Target/SystemZ/SystemZISelLowering.cpp -=================================================================== ---- a/lib/Target/SystemZ/SystemZISelLowering.cpp -+++ b/lib/Target/SystemZ/SystemZISelLowering.cpp -@@ -4995,8 +4995,8 @@ - - SDValue SystemZTargetLowering::combineFP_ROUND( - SDNode *N, DAGCombinerInfo &DCI) const { -- // (fround (extract_vector_elt X 0)) -- // (fround (extract_vector_elt X 1)) -> -+ // (fpround (extract_vector_elt X 0)) -+ // (fpround (extract_vector_elt X 1)) -> - // (extract_vector_elt (VROUND X) 0) - // (extract_vector_elt (VROUND X) 1) - // -Index: lib/Target/SystemZ/SystemZInstrFP.td -=================================================================== ---- a/lib/Target/SystemZ/SystemZInstrFP.td -+++ b/lib/Target/SystemZ/SystemZInstrFP.td -@@ -154,7 +154,7 @@ - // Convert floating-point values to narrower representations, rounding - // according to the current mode. The destination of LEXBR and LDXBR - // is a 128-bit value, but only the first register of the pair is used. --def LEDBR : UnaryRRE<"ledb", 0xB344, fround, FP32, FP64>; -+def LEDBR : UnaryRRE<"ledb", 0xB344, fpround, FP32, FP64>; - def LEXBR : UnaryRRE<"lexb", 0xB346, null_frag, FP128, FP128>; - def LDXBR : UnaryRRE<"ldxb", 0xB345, null_frag, FP128, FP128>; - -@@ -165,15 +165,15 @@ - def LDXBRA : UnaryRRF4<"ldxbra", 0xB345, FP128, FP128>, - Requires<[FeatureFPExtension]>; - --def : Pat<(f32 (fround FP128:$src)), -+def : Pat<(f32 (fpround FP128:$src)), - (EXTRACT_SUBREG (LEXBR FP128:$src), subreg_hr32)>; --def : Pat<(f64 (fround FP128:$src)), -+def : Pat<(f64 (fpround FP128:$src)), - (EXTRACT_SUBREG (LDXBR FP128:$src), subreg_h64)>; - - // Extend register floating-point values to wider representations. --def LDEBR : UnaryRRE<"ldeb", 0xB304, fextend, FP64, FP32>; --def LXEBR : UnaryRRE<"lxeb", 0xB306, fextend, FP128, FP32>; --def LXDBR : UnaryRRE<"lxdb", 0xB305, fextend, FP128, FP64>; -+def LDEBR : UnaryRRE<"ldeb", 0xB304, fpextend, FP64, FP32>; -+def LXEBR : UnaryRRE<"lxeb", 0xB306, fpextend, FP128, FP32>; -+def LXDBR : UnaryRRE<"lxdb", 0xB305, fpextend, FP128, FP64>; - - // Extend memory floating-point values to wider representations. - def LDEB : UnaryRXE<"ldeb", 0xED04, extloadf32, FP64, 4>; -@@ -347,9 +347,9 @@ - - // Same idea for round, where mode 1 is round towards nearest with - // ties away from zero. -- def : Pat<(frnd FP32:$src), (FIEBRA 1, FP32:$src, 4)>; -- def : Pat<(frnd FP64:$src), (FIDBRA 1, FP64:$src, 4)>; -- def : Pat<(frnd FP128:$src), (FIXBRA 1, FP128:$src, 4)>; -+ def : Pat<(fround FP32:$src), (FIEBRA 1, FP32:$src, 4)>; -+ def : Pat<(fround FP64:$src), (FIDBRA 1, FP64:$src, 4)>; -+ def : Pat<(fround FP128:$src), (FIXBRA 1, FP128:$src, 4)>; - } - - //===----------------------------------------------------------------------===// -@@ -388,26 +388,26 @@ - - // f64 multiplication of two FP32 registers. - def MDEBR : BinaryRRE<"mdeb", 0xB30C, null_frag, FP64, FP32>; --def : Pat<(fmul (f64 (fextend FP32:$src1)), (f64 (fextend FP32:$src2))), -+def : Pat<(fmul (f64 (fpextend FP32:$src1)), (f64 (fpextend FP32:$src2))), - (MDEBR (INSERT_SUBREG (f64 (IMPLICIT_DEF)), - FP32:$src1, subreg_r32), FP32:$src2)>; - - // f64 multiplication of an FP32 register and an f32 memory. - def MDEB : BinaryRXE<"mdeb", 0xED0C, null_frag, FP64, load, 4>; --def : Pat<(fmul (f64 (fextend FP32:$src1)), -+def : Pat<(fmul (f64 (fpextend FP32:$src1)), - (f64 (extloadf32 bdxaddr12only:$addr))), - (MDEB (INSERT_SUBREG (f64 (IMPLICIT_DEF)), FP32:$src1, subreg_r32), - bdxaddr12only:$addr)>; - - // f128 multiplication of two FP64 registers. - def MXDBR : BinaryRRE<"mxdb", 0xB307, null_frag, FP128, FP64>; --def : Pat<(fmul (f128 (fextend FP64:$src1)), (f128 (fextend FP64:$src2))), -+def : Pat<(fmul (f128 (fpextend FP64:$src1)), (f128 (fpextend FP64:$src2))), - (MXDBR (INSERT_SUBREG (f128 (IMPLICIT_DEF)), - FP64:$src1, subreg_h64), FP64:$src2)>; - - // f128 multiplication of an FP64 register and an f64 memory. - def MXDB : BinaryRXE<"mxdb", 0xED07, null_frag, FP128, load, 8>; --def : Pat<(fmul (f128 (fextend FP64:$src1)), -+def : Pat<(fmul (f128 (fpextend FP64:$src1)), - (f128 (extloadf64 bdxaddr12only:$addr))), - (MXDB (INSERT_SUBREG (f128 (IMPLICIT_DEF)), FP64:$src1, subreg_h64), - bdxaddr12only:$addr)>; -Index: lib/Target/SystemZ/SystemZInstrVector.td -=================================================================== ---- a/lib/Target/SystemZ/SystemZInstrVector.td -+++ b/lib/Target/SystemZ/SystemZInstrVector.td -@@ -798,7 +798,7 @@ - def : FPConversion; - def : FPConversion; - def : FPConversion; -- def : FPConversion; -+ def : FPConversion; - } - - let Predicates = [FeatureVector] in { -@@ -840,13 +840,13 @@ - - // Load lengthened. - def VLDEB : UnaryVRRa<"vldeb", 0xE7C4, z_vextend, v128db, v128eb, 2, 0>; -- def WLDEB : UnaryVRRa<"wldeb", 0xE7C4, fextend, v64db, v32eb, 2, 8>; -+ def WLDEB : UnaryVRRa<"wldeb", 0xE7C4, fpextend, v64db, v32eb, 2, 8>; - - // Load rounded, - def VLEDB : TernaryVRRa<"vledb", 0xE7C5, null_frag, v128eb, v128db, 3, 0>; - def WLEDB : TernaryVRRa<"wledb", 0xE7C5, null_frag, v32eb, v64db, 3, 8>; - def : Pat<(v4f32 (z_vround (v2f64 VR128:$src))), (VLEDB VR128:$src, 0, 0)>; -- def : FPConversion; -+ def : FPConversion; - - // Multiply. - def VFMDB : BinaryVRRc<"vfmdb", 0xE7E7, fmul, v128db, v128db, 3, 0>; -Index: lib/Target/WebAssembly/WebAssemblyInstrConv.td -=================================================================== ---- a/lib/Target/WebAssembly/WebAssemblyInstrConv.td -+++ b/lib/Target/WebAssembly/WebAssemblyInstrConv.td -@@ -89,10 +89,10 @@ - "f64.convert_u/i64\t$dst, $src">; - - def F64_PROMOTE_F32 : I<(outs F64:$dst), (ins F32:$src), -- [(set F64:$dst, (fextend F32:$src))], -+ [(set F64:$dst, (fpextend F32:$src))], - "f64.promote/f32\t$dst, $src">; - def F32_DEMOTE_F64 : I<(outs F32:$dst), (ins F64:$src), -- [(set F32:$dst, (fround F64:$src))], -+ [(set F32:$dst, (fpround F64:$src))], - "f32.demote/f64\t$dst, $src">; - - def I32_REINTERPRET_F32 : I<(outs I32:$dst), (ins F32:$src), -Index: lib/Target/X86/X86InstrAVX512.td -=================================================================== ---- a/lib/Target/X86/X86InstrAVX512.td -+++ b/lib/Target/X86/X86InstrAVX512.td -@@ -5595,11 +5595,11 @@ - defm VCVTSS2SD : avx512_cvt_fp_scalar_ss2sd<0x5A, "vcvtss2sd", X86fpext, - X86fpextRnd,f32x_info, f64x_info >; - --def : Pat<(f64 (fextend FR32X:$src)), -+def : Pat<(f64 (fpextend FR32X:$src)), - (COPY_TO_REGCLASS (VCVTSS2SDZrr (COPY_TO_REGCLASS FR32X:$src, VR128X), - (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X)>, - Requires<[HasAVX512]>; --def : Pat<(f64 (fextend (loadf32 addr:$src))), -+def : Pat<(f64 (fpextend (loadf32 addr:$src))), - (COPY_TO_REGCLASS (VCVTSS2SDZrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>, - Requires<[HasAVX512]>; - -@@ -5612,7 +5612,7 @@ - (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)), VR128X)>, - Requires<[HasAVX512, OptForSpeed]>; - --def : Pat<(f32 (fround FR64X:$src)), -+def : Pat<(f32 (fpround FR64X:$src)), - (COPY_TO_REGCLASS (VCVTSD2SSZrr (COPY_TO_REGCLASS FR64X:$src, VR128X), - (COPY_TO_REGCLASS FR64X:$src, VR128X)), VR128X)>, - Requires<[HasAVX512]>; -@@ -5666,29 +5666,29 @@ - // Extend Float to Double - multiclass avx512_cvtps2pd opc, string OpcodeStr> { - let Predicates = [HasAVX512] in { -- defm Z : avx512_vcvt_fp, -+ defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_sae, EVEX_V512; - } - let Predicates = [HasVLX] in { - defm Z128 : avx512_vcvt_fp, EVEX_V128; -- defm Z256 : avx512_vcvt_fp, -+ defm Z256 : avx512_vcvt_fp, - EVEX_V256; - } - } - - // Truncate Double to Float - multiclass avx512_cvtpd2ps opc, string OpcodeStr> { - let Predicates = [HasAVX512] in { -- defm Z : avx512_vcvt_fp, -+ defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_rc, EVEX_V512; - } - let Predicates = [HasVLX] in { - defm Z128 : avx512_vcvt_fp, EVEX_V128; -- defm Z256 : avx512_vcvt_fp, EVEX_V256; - } - } -@@ -6025,7 +6025,7 @@ - } - - let Predicates = [HasAVX512] in { -- def : Pat<(v8f32 (fround (loadv8f64 addr:$src))), -+ def : Pat<(v8f32 (fpround (loadv8f64 addr:$src))), - (VCVTPD2PSZrm addr:$src)>; - def : Pat<(v8f64 (extloadv8f32 addr:$src)), - (VCVTPS2PDZrm addr:$src)>; -Index: lib/Target/X86/X86InstrFPStack.td -=================================================================== ---- a/lib/Target/X86/X86InstrFPStack.td -+++ b/lib/Target/X86/X86InstrFPStack.td -@@ -711,19 +711,19 @@ - - // FP extensions map onto simple pseudo-value conversions if they are to/from - // the FP stack. --def : Pat<(f64 (fextend RFP32:$src)), (COPY_TO_REGCLASS RFP32:$src, RFP64)>, -+def : Pat<(f64 (fpextend RFP32:$src)), (COPY_TO_REGCLASS RFP32:$src, RFP64)>, - Requires<[FPStackf32]>; --def : Pat<(f80 (fextend RFP32:$src)), (COPY_TO_REGCLASS RFP32:$src, RFP80)>, -+def : Pat<(f80 (fpextend RFP32:$src)), (COPY_TO_REGCLASS RFP32:$src, RFP80)>, - Requires<[FPStackf32]>; --def : Pat<(f80 (fextend RFP64:$src)), (COPY_TO_REGCLASS RFP64:$src, RFP80)>, -+def : Pat<(f80 (fpextend RFP64:$src)), (COPY_TO_REGCLASS RFP64:$src, RFP80)>, - Requires<[FPStackf64]>; - - // FP truncations map onto simple pseudo-value conversions if they are to/from - // the FP stack. We have validated that only value-preserving truncations make - // it through isel. --def : Pat<(f32 (fround RFP64:$src)), (COPY_TO_REGCLASS RFP64:$src, RFP32)>, -+def : Pat<(f32 (fpround RFP64:$src)), (COPY_TO_REGCLASS RFP64:$src, RFP32)>, - Requires<[FPStackf32]>; --def : Pat<(f32 (fround RFP80:$src)), (COPY_TO_REGCLASS RFP80:$src, RFP32)>, -+def : Pat<(f32 (fpround RFP80:$src)), (COPY_TO_REGCLASS RFP80:$src, RFP32)>, - Requires<[FPStackf32]>; --def : Pat<(f64 (fround RFP80:$src)), (COPY_TO_REGCLASS RFP80:$src, RFP64)>, -+def : Pat<(f64 (fpround RFP80:$src)), (COPY_TO_REGCLASS RFP80:$src, RFP64)>, - Requires<[FPStackf64]>; -Index: lib/Target/X86/X86InstrSSE.td -=================================================================== ---- a/lib/Target/X86/X86InstrSSE.td -+++ b/lib/Target/X86/X86InstrSSE.td -@@ -1799,16 +1799,16 @@ - Sched<[WriteCvtF2FLd, ReadAfterLd]>; - } - --def : Pat<(f32 (fround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>, -+def : Pat<(f32 (fpround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>, - Requires<[UseAVX]>; - - def CVTSD2SSrr : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src), - "cvtsd2ss\t{$src, $dst|$dst, $src}", -- [(set FR32:$dst, (fround FR64:$src))], -+ [(set FR32:$dst, (fpround FR64:$src))], - IIC_SSE_CVT_Scalar_RR>, Sched<[WriteCvtF2F]>; - def CVTSD2SSrm : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src), - "cvtsd2ss\t{$src, $dst|$dst, $src}", -- [(set FR32:$dst, (fround (loadf64 addr:$src)))], -+ [(set FR32:$dst, (fpround (loadf64 addr:$src)))], - IIC_SSE_CVT_Scalar_RM>, - XD, - Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>; -@@ -1865,9 +1865,9 @@ - Sched<[WriteCvtF2FLd, ReadAfterLd]>; - } - --def : Pat<(f64 (fextend FR32:$src)), -+def : Pat<(f64 (fpextend FR32:$src)), - (VCVTSS2SDrr FR32:$src, FR32:$src)>, Requires<[UseAVX]>; --def : Pat<(fextend (loadf32 addr:$src)), -+def : Pat<(fpextend (loadf32 addr:$src)), - (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>, Requires<[UseAVX]>; - - def : Pat<(extloadf32 addr:$src), -@@ -1879,21 +1879,21 @@ - - def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src), - "cvtss2sd\t{$src, $dst|$dst, $src}", -- [(set FR64:$dst, (fextend FR32:$src))], -+ [(set FR64:$dst, (fpextend FR32:$src))], - IIC_SSE_CVT_Scalar_RR>, XS, - Requires<[UseSSE2]>, Sched<[WriteCvtF2F]>; - def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src), - "cvtss2sd\t{$src, $dst|$dst, $src}", - [(set FR64:$dst, (extloadf32 addr:$src))], - IIC_SSE_CVT_Scalar_RM>, XS, - Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>; - --// extload f32 -> f64. This matches load+fextend because we have a hack in -+// extload f32 -> f64. This matches load+fpextend because we have a hack in - // the isel (PreprocessForFPConvert) that can introduce loads after dag - // combine. --// Since these loads aren't folded into the fextend, we have to match it -+// Since these loads aren't folded into the fpextend, we have to match it - // explicitly here. --def : Pat<(fextend (loadf32 addr:$src)), -+def : Pat<(fpextend (loadf32 addr:$src)), - (CVTSS2SDrm addr:$src)>, Requires<[UseSSE2]>; - def : Pat<(extloadf32 addr:$src), - (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[UseSSE2, OptForSpeed]>; -@@ -2269,26 +2269,26 @@ - } - - let Predicates = [HasAVX, NoVLX] in { -- // Match fround and fextend for 128/256-bit conversions -+ // Match fpround and fpextend for 128/256-bit conversions - def : Pat<(v4f32 (X86vfpround (v2f64 VR128:$src))), - (VCVTPD2PSrr VR128:$src)>; - def : Pat<(v4f32 (X86vfpround (loadv2f64 addr:$src))), - (VCVTPD2PSXrm addr:$src)>; -- def : Pat<(v4f32 (fround (v4f64 VR256:$src))), -+ def : Pat<(v4f32 (fpround (v4f64 VR256:$src))), - (VCVTPD2PSYrr VR256:$src)>; -- def : Pat<(v4f32 (fround (loadv4f64 addr:$src))), -+ def : Pat<(v4f32 (fpround (loadv4f64 addr:$src))), - (VCVTPD2PSYrm addr:$src)>; - - def : Pat<(v2f64 (X86vfpext (v4f32 VR128:$src))), - (VCVTPS2PDrr VR128:$src)>; -- def : Pat<(v4f64 (fextend (v4f32 VR128:$src))), -+ def : Pat<(v4f64 (fpextend (v4f32 VR128:$src))), - (VCVTPS2PDYrr VR128:$src)>; - def : Pat<(v4f64 (extloadv4f32 addr:$src)), - (VCVTPS2PDYrm addr:$src)>; - } - - let Predicates = [UseSSE2] in { -- // Match fround and fextend for 128 conversions -+ // Match fpround and fpextend for 128 conversions - def : Pat<(v4f32 (X86vfpround (v2f64 VR128:$src))), - (CVTPD2PSrr VR128:$src)>; - def : Pat<(v4f32 (X86vfpround (memopv2f64 addr:$src))), diff --git a/deps/patches/llvm-D24300_ptx_intrinsics.patch b/deps/patches/llvm-D24300_ptx_intrinsics.patch deleted file mode 100644 index e0c1e5a286c56..0000000000000 --- a/deps/patches/llvm-D24300_ptx_intrinsics.patch +++ /dev/null @@ -1,506 +0,0 @@ -Index: lib/Target/NVPTX/NVPTXISelLowering.cpp -=================================================================== ---- a/lib/Target/NVPTX/NVPTXISelLowering.cpp -+++ b/lib/Target/NVPTX/NVPTXISelLowering.cpp -@@ -279,6 +279,28 @@ - setTargetDAGCombine(ISD::SHL); - setTargetDAGCombine(ISD::SELECT); - -+ // Library functions. These default to Expand, but we have instructions -+ // for them. -+ setOperationAction(ISD::FCEIL, MVT::f32, Legal); -+ setOperationAction(ISD::FCEIL, MVT::f64, Legal); -+ setOperationAction(ISD::FFLOOR, MVT::f32, Legal); -+ setOperationAction(ISD::FFLOOR, MVT::f64, Legal); -+ setOperationAction(ISD::FNEARBYINT, MVT::f32, Legal); -+ setOperationAction(ISD::FNEARBYINT, MVT::f64, Legal); -+ setOperationAction(ISD::FRINT, MVT::f32, Legal); -+ setOperationAction(ISD::FRINT, MVT::f64, Legal); -+ setOperationAction(ISD::FROUND, MVT::f32, Legal); -+ setOperationAction(ISD::FROUND, MVT::f64, Legal); -+ setOperationAction(ISD::FTRUNC, MVT::f32, Legal); -+ setOperationAction(ISD::FTRUNC, MVT::f64, Legal); -+ setOperationAction(ISD::FMINNUM, MVT::f32, Legal); -+ setOperationAction(ISD::FMINNUM, MVT::f64, Legal); -+ setOperationAction(ISD::FMAXNUM, MVT::f32, Legal); -+ setOperationAction(ISD::FMAXNUM, MVT::f64, Legal); -+ -+ // No FEXP2, FLOG2. The PTX ex2 and log2 functions are always approximate. -+ // No FPOW or FREM in PTX. -+ - // Now deduce the information based on the above mentioned - // actions - computeRegisterProperties(STI.getRegisterInfo()); -Index: lib/Target/NVPTX/NVPTXInstrInfo.td -=================================================================== ---- a/lib/Target/NVPTX/NVPTXInstrInfo.td -+++ b/lib/Target/NVPTX/NVPTXInstrInfo.td -@@ -207,15 +207,63 @@ - } - - // Template for instructions which take three fp64 or fp32 args. The --// instructions are named ".f" (e.g. "add.f64"). -+// instructions are named ".f" (e.g. "min.f64"). - // - // Also defines ftz (flush subnormal inputs and results to sign-preserving - // zero) variants for fp32 functions. -+// -+// This multiclass should be used for nodes that cannot be folded into FMAs. -+// For nodes that can be folded into FMAs (i.e. adds and muls), use -+// F3_fma_component. - multiclass F3 { - def f64rr : - NVPTXInst<(outs Float64Regs:$dst), - (ins Float64Regs:$a, Float64Regs:$b), - !strconcat(OpcStr, ".f64 \t$dst, $a, $b;"), -+ [(set Float64Regs:$dst, (OpNode Float64Regs:$a, Float64Regs:$b))]>; -+ def f64ri : -+ NVPTXInst<(outs Float64Regs:$dst), -+ (ins Float64Regs:$a, f64imm:$b), -+ !strconcat(OpcStr, ".f64 \t$dst, $a, $b;"), -+ [(set Float64Regs:$dst, (OpNode Float64Regs:$a, fpimm:$b))]>; -+ def f32rr_ftz : -+ NVPTXInst<(outs Float32Regs:$dst), -+ (ins Float32Regs:$a, Float32Regs:$b), -+ !strconcat(OpcStr, ".ftz.f32 \t$dst, $a, $b;"), -+ [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>, -+ Requires<[doF32FTZ]>; -+ def f32ri_ftz : -+ NVPTXInst<(outs Float32Regs:$dst), -+ (ins Float32Regs:$a, f32imm:$b), -+ !strconcat(OpcStr, ".ftz.f32 \t$dst, $a, $b;"), -+ [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>, -+ Requires<[doF32FTZ]>; -+ def f32rr : -+ NVPTXInst<(outs Float32Regs:$dst), -+ (ins Float32Regs:$a, Float32Regs:$b), -+ !strconcat(OpcStr, ".f32 \t$dst, $a, $b;"), -+ [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>; -+ def f32ri : -+ NVPTXInst<(outs Float32Regs:$dst), -+ (ins Float32Regs:$a, f32imm:$b), -+ !strconcat(OpcStr, ".f32 \t$dst, $a, $b;"), -+ [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>; -+} -+ -+// Template for instructions which take three fp64 or fp32 args. The -+// instructions are named ".f" (e.g. "add.f64"). -+// -+// Also defines ftz (flush subnormal inputs and results to sign-preserving -+// zero) variants for fp32 functions. -+// -+// This multiclass should be used for nodes that can be folded to make fma ops. -+// In this case, we use the ".rn" variant when FMA is disabled, as this behaves -+// just like the non ".rn" op, but prevents ptxas from creating FMAs. -+multiclass F3_fma_component { -+ def f64rr : -+ NVPTXInst<(outs Float64Regs:$dst), -+ (ins Float64Regs:$a, Float64Regs:$b), -+ !strconcat(OpcStr, ".f64 \t$dst, $a, $b;"), - [(set Float64Regs:$dst, (OpNode Float64Regs:$a, Float64Regs:$b))]>, - Requires<[allowFMA]>; - def f64ri : -@@ -248,41 +296,39 @@ - !strconcat(OpcStr, ".f32 \t$dst, $a, $b;"), - [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>, - Requires<[allowFMA]>; --} - --// Same as F3, but defines ".rn" variants (round to nearest even). --multiclass F3_rn { -- def f64rr : -+ // These have strange names so we don't perturb existing mir tests. -+ def _rnf64rr : - NVPTXInst<(outs Float64Regs:$dst), - (ins Float64Regs:$a, Float64Regs:$b), - !strconcat(OpcStr, ".rn.f64 \t$dst, $a, $b;"), - [(set Float64Regs:$dst, (OpNode Float64Regs:$a, Float64Regs:$b))]>, - Requires<[noFMA]>; -- def f64ri : -+ def _rnf64ri : - NVPTXInst<(outs Float64Regs:$dst), - (ins Float64Regs:$a, f64imm:$b), - !strconcat(OpcStr, ".rn.f64 \t$dst, $a, $b;"), - [(set Float64Regs:$dst, (OpNode Float64Regs:$a, fpimm:$b))]>, - Requires<[noFMA]>; -- def f32rr_ftz : -+ def _rnf32rr_ftz : - NVPTXInst<(outs Float32Regs:$dst), - (ins Float32Regs:$a, Float32Regs:$b), - !strconcat(OpcStr, ".rn.ftz.f32 \t$dst, $a, $b;"), - [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>, - Requires<[noFMA, doF32FTZ]>; -- def f32ri_ftz : -+ def _rnf32ri_ftz : - NVPTXInst<(outs Float32Regs:$dst), - (ins Float32Regs:$a, f32imm:$b), - !strconcat(OpcStr, ".rn.ftz.f32 \t$dst, $a, $b;"), - [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>, - Requires<[noFMA, doF32FTZ]>; -- def f32rr : -+ def _rnf32rr : - NVPTXInst<(outs Float32Regs:$dst), - (ins Float32Regs:$a, Float32Regs:$b), - !strconcat(OpcStr, ".rn.f32 \t$dst, $a, $b;"), - [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>, - Requires<[noFMA]>; -- def f32ri : -+ def _rnf32ri : - NVPTXInst<(outs Float32Regs:$dst), - (ins Float32Regs:$a, f32imm:$b), - !strconcat(OpcStr, ".rn.f32 \t$dst, $a, $b;"), -@@ -713,13 +759,12 @@ - N->getValueAPF().convertToDouble() == 1.0; - }]>; - --defm FADD : F3<"add", fadd>; --defm FSUB : F3<"sub", fsub>; --defm FMUL : F3<"mul", fmul>; -- --defm FADD_rn : F3_rn<"add", fadd>; --defm FSUB_rn : F3_rn<"sub", fsub>; --defm FMUL_rn : F3_rn<"mul", fmul>; -+defm FADD : F3_fma_component<"add", fadd>; -+defm FSUB : F3_fma_component<"sub", fsub>; -+defm FMUL : F3_fma_component<"mul", fmul>; -+ -+defm FMIN : F3<"min", fminnum>; -+defm FMAX : F3<"max", fmaxnum>; - - defm FABS : F2<"abs", fabs>; - defm FNEG : F2<"neg", fneg>; -@@ -2628,6 +2673,55 @@ - def retflag : SDNode<"NVPTXISD::RET_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInGlue]>; - -+// fceil, ffloor, fround, ftrunc. -+ -+def : Pat<(fceil Float32Regs:$a), -+ (CVT_f32_f32 Float32Regs:$a, CvtRPI_FTZ)>, Requires<[doF32FTZ]>; -+def : Pat<(fceil Float32Regs:$a), -+ (CVT_f32_f32 Float32Regs:$a, CvtRPI)>, Requires<[doNoF32FTZ]>; -+def : Pat<(fceil Float64Regs:$a), -+ (CVT_f64_f64 Float64Regs:$a, CvtRPI)>; -+ -+def : Pat<(ffloor Float32Regs:$a), -+ (CVT_f32_f32 Float32Regs:$a, CvtRMI_FTZ)>, Requires<[doF32FTZ]>; -+def : Pat<(ffloor Float32Regs:$a), -+ (CVT_f32_f32 Float32Regs:$a, CvtRMI)>, Requires<[doNoF32FTZ]>; -+def : Pat<(ffloor Float64Regs:$a), -+ (CVT_f64_f64 Float64Regs:$a, CvtRMI)>; -+ -+def : Pat<(fround Float32Regs:$a), -+ (CVT_f32_f32 Float32Regs:$a, CvtRNI_FTZ)>, Requires<[doF32FTZ]>; -+def : Pat<(f32 (fround Float32Regs:$a)), -+ (CVT_f32_f32 Float32Regs:$a, CvtRNI)>, Requires<[doNoF32FTZ]>; -+def : Pat<(f64 (fround Float64Regs:$a)), -+ (CVT_f64_f64 Float64Regs:$a, CvtRNI)>; -+ -+def : Pat<(ftrunc Float32Regs:$a), -+ (CVT_f32_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>; -+def : Pat<(ftrunc Float32Regs:$a), -+ (CVT_f32_f32 Float32Regs:$a, CvtRZI)>, Requires<[doNoF32FTZ]>; -+def : Pat<(ftrunc Float64Regs:$a), -+ (CVT_f64_f64 Float64Regs:$a, CvtRZI)>; -+ -+// nearbyint and rint are implemented as rounding to nearest even. This isn't -+// strictly correct, because it causes us to ignore the rounding mode. But it -+// matches what CUDA's "libm" does. -+ -+def : Pat<(fnearbyint Float32Regs:$a), -+ (CVT_f32_f32 Float32Regs:$a, CvtRNI_FTZ)>, Requires<[doF32FTZ]>; -+def : Pat<(fnearbyint Float32Regs:$a), -+ (CVT_f32_f32 Float32Regs:$a, CvtRNI)>, Requires<[doNoF32FTZ]>; -+def : Pat<(fnearbyint Float64Regs:$a), -+ (CVT_f64_f64 Float64Regs:$a, CvtRNI)>; -+ -+def : Pat<(frint Float32Regs:$a), -+ (CVT_f32_f32 Float32Regs:$a, CvtRNI_FTZ)>, Requires<[doF32FTZ]>; -+def : Pat<(frint Float32Regs:$a), -+ (CVT_f32_f32 Float32Regs:$a, CvtRNI)>, Requires<[doNoF32FTZ]>; -+def : Pat<(frint Float64Regs:$a), -+ (CVT_f64_f64 Float64Regs:$a, CvtRNI)>; -+ -+ - //----------------------------------- - // Control-flow - //----------------------------------- -Index: test/CodeGen/NVPTX/bug22322.ll -=================================================================== ---- a/test/CodeGen/NVPTX/bug22322.ll -+++ b/test/CodeGen/NVPTX/bug22322.ll -@@ -22,7 +22,7 @@ - %8 = icmp eq i32 %7, 0 - %9 = select i1 %8, float 0.000000e+00, float -1.000000e+00 - store float %9, float* %ret_vec.sroa.8.i, align 4 --; CHECK: setp.lt.f32 %p{{[0-9]+}}, %f{{[0-9]+}}, 0f00000000 -+; CHECK: max.f32 %f{{[0-9]+}}, %f{{[0-9]+}}, 0f00000000 - %10 = fcmp olt float %9, 0.000000e+00 - %ret_vec.sroa.8.i.val = load float, float* %ret_vec.sroa.8.i, align 4 - %11 = select i1 %10, float 0.000000e+00, float %ret_vec.sroa.8.i.val -Index: test/CodeGen/NVPTX/math-intrins.ll -=================================================================== ---- a/test/CodeGen/NVPTX/math-intrins.ll -+++ b/test/CodeGen/NVPTX/math-intrins.ll -@@ -0,0 +1,261 @@ -+; RUN: llc < %s | FileCheck %s -+target triple = "nvptx64-nvidia-cuda" -+ -+; Checks that llvm intrinsics for math functions are correctly lowered to PTX. -+ -+declare float @llvm.ceil.f32(float) #0 -+declare double @llvm.ceil.f64(double) #0 -+declare float @llvm.floor.f32(float) #0 -+declare double @llvm.floor.f64(double) #0 -+declare float @llvm.round.f32(float) #0 -+declare double @llvm.round.f64(double) #0 -+declare float @llvm.nearbyint.f32(float) #0 -+declare double @llvm.nearbyint.f64(double) #0 -+declare float @llvm.rint.f32(float) #0 -+declare double @llvm.rint.f64(double) #0 -+declare float @llvm.trunc.f32(float) #0 -+declare double @llvm.trunc.f64(double) #0 -+declare float @llvm.fabs.f32(float) #0 -+declare double @llvm.fabs.f64(double) #0 -+declare float @llvm.minnum.f32(float, float) #0 -+declare double @llvm.minnum.f64(double, double) #0 -+declare float @llvm.maxnum.f32(float, float) #0 -+declare double @llvm.maxnum.f64(double, double) #0 -+ -+; ---- ceil ---- -+ -+; CHECK-LABEL: ceil_float -+define float @ceil_float(float %a) { -+ ; CHECK: cvt.rpi.f32.f32 -+ %b = call float @llvm.ceil.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: ceil_float_ftz -+define float @ceil_float_ftz(float %a) #1 { -+ ; CHECK: cvt.rpi.ftz.f32.f32 -+ %b = call float @llvm.ceil.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: ceil_double -+define double @ceil_double(double %a) { -+ ; CHECK: cvt.rpi.f64.f64 -+ %b = call double @llvm.ceil.f64(double %a) -+ ret double %b -+} -+ -+; ---- floor ---- -+ -+; CHECK-LABEL: floor_float -+define float @floor_float(float %a) { -+ ; CHECK: cvt.rmi.f32.f32 -+ %b = call float @llvm.floor.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: floor_float_ftz -+define float @floor_float_ftz(float %a) #1 { -+ ; CHECK: cvt.rmi.ftz.f32.f32 -+ %b = call float @llvm.floor.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: floor_double -+define double @floor_double(double %a) { -+ ; CHECK: cvt.rmi.f64.f64 -+ %b = call double @llvm.floor.f64(double %a) -+ ret double %b -+} -+ -+; ---- round ---- -+ -+; CHECK-LABEL: round_float -+define float @round_float(float %a) { -+ ; CHECK: cvt.rni.f32.f32 -+ %b = call float @llvm.round.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: round_float_ftz -+define float @round_float_ftz(float %a) #1 { -+ ; CHECK: cvt.rni.ftz.f32.f32 -+ %b = call float @llvm.round.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: round_double -+define double @round_double(double %a) { -+ ; CHECK: cvt.rni.f64.f64 -+ %b = call double @llvm.round.f64(double %a) -+ ret double %b -+} -+ -+; ---- nearbyint ---- -+ -+; CHECK-LABEL: nearbyint_float -+define float @nearbyint_float(float %a) { -+ ; CHECK: cvt.rni.f32.f32 -+ %b = call float @llvm.nearbyint.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: nearbyint_float_ftz -+define float @nearbyint_float_ftz(float %a) #1 { -+ ; CHECK: cvt.rni.ftz.f32.f32 -+ %b = call float @llvm.nearbyint.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: nearbyint_double -+define double @nearbyint_double(double %a) { -+ ; CHECK: cvt.rni.f64.f64 -+ %b = call double @llvm.nearbyint.f64(double %a) -+ ret double %b -+} -+ -+; ---- rint ---- -+ -+; CHECK-LABEL: rint_float -+define float @rint_float(float %a) { -+ ; CHECK: cvt.rni.f32.f32 -+ %b = call float @llvm.rint.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: rint_float_ftz -+define float @rint_float_ftz(float %a) #1 { -+ ; CHECK: cvt.rni.ftz.f32.f32 -+ %b = call float @llvm.rint.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: rint_double -+define double @rint_double(double %a) { -+ ; CHECK: cvt.rni.f64.f64 -+ %b = call double @llvm.rint.f64(double %a) -+ ret double %b -+} -+ -+; ---- trunc ---- -+ -+; CHECK-LABEL: trunc_float -+define float @trunc_float(float %a) { -+ ; CHECK: cvt.rzi.f32.f32 -+ %b = call float @llvm.trunc.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: trunc_float_ftz -+define float @trunc_float_ftz(float %a) #1 { -+ ; CHECK: cvt.rzi.ftz.f32.f32 -+ %b = call float @llvm.trunc.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: trunc_double -+define double @trunc_double(double %a) { -+ ; CHECK: cvt.rzi.f64.f64 -+ %b = call double @llvm.trunc.f64(double %a) -+ ret double %b -+} -+ -+; ---- abs ---- -+ -+; CHECK-LABEL: abs_float -+define float @abs_float(float %a) { -+ ; CHECK: abs.f32 -+ %b = call float @llvm.fabs.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: abs_float_ftz -+define float @abs_float_ftz(float %a) #1 { -+ ; CHECK: abs.ftz.f32 -+ %b = call float @llvm.fabs.f32(float %a) -+ ret float %b -+} -+ -+; CHECK-LABEL: abs_double -+define double @abs_double(double %a) { -+ ; CHECK: abs.f64 -+ %b = call double @llvm.fabs.f64(double %a) -+ ret double %b -+} -+ -+; ---- min ---- -+ -+; CHECK-LABEL: min_float -+define float @min_float(float %a, float %b) { -+ ; CHECK: min.f32 -+ %x = call float @llvm.minnum.f32(float %a, float %b) -+ ret float %x -+} -+ -+; CHECK-LABEL: min_imm1 -+define float @min_imm1(float %a) { -+ ; CHECK: min.f32 -+ %x = call float @llvm.minnum.f32(float %a, float 0.0) -+ ret float %x -+} -+ -+; CHECK-LABEL: min_imm2 -+define float @min_imm2(float %a) { -+ ; CHECK: min.f32 -+ %x = call float @llvm.minnum.f32(float 0.0, float %a) -+ ret float %x -+} -+ -+; CHECK-LABEL: min_float_ftz -+define float @min_float_ftz(float %a, float %b) #1 { -+ ; CHECK: min.ftz.f32 -+ %x = call float @llvm.minnum.f32(float %a, float %b) -+ ret float %x -+} -+ -+; CHECK-LABEL: min_double -+define double @min_double(double %a, double %b) { -+ ; CHECK: min.f64 -+ %x = call double @llvm.minnum.f64(double %a, double %b) -+ ret double %x -+} -+ -+; ---- max ---- -+ -+; CHECK-LABEL: max_imm1 -+define float @max_imm1(float %a) { -+ ; CHECK: max.f32 -+ %x = call float @llvm.maxnum.f32(float %a, float 0.0) -+ ret float %x -+} -+ -+; CHECK-LABEL: max_imm2 -+define float @max_imm2(float %a) { -+ ; CHECK: max.f32 -+ %x = call float @llvm.maxnum.f32(float 0.0, float %a) -+ ret float %x -+} -+ -+; CHECK-LABEL: max_float -+define float @max_float(float %a, float %b) { -+ ; CHECK: max.f32 -+ %x = call float @llvm.maxnum.f32(float %a, float %b) -+ ret float %x -+} -+ -+; CHECK-LABEL: max_float_ftz -+define float @max_float_ftz(float %a, float %b) #1 { -+ ; CHECK: max.ftz.f32 -+ %x = call float @llvm.maxnum.f32(float %a, float %b) -+ ret float %x -+} -+ -+; CHECK-LABEL: max_double -+define double @max_double(double %a, double %b) { -+ ; CHECK: max.f64 -+ %x = call double @llvm.maxnum.f64(double %a, double %b) -+ ret double %x -+} -+ -+attributes #0 = { nounwind readnone } -+attributes #1 = { "nvptx-f32ftz" = "true" } diff --git a/deps/patches/llvm-D25865-cmakeshlib.patch b/deps/patches/llvm-D25865-cmakeshlib.patch deleted file mode 100644 index 1f982665facf0..0000000000000 --- a/deps/patches/llvm-D25865-cmakeshlib.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 417001588d232151050db2d32df443e2d073ebbf Mon Sep 17 00:00:00 2001 -From: Valentin Churavy -Date: Fri, 21 Oct 2016 17:25:04 +0900 -Subject: [PATCH] Fix llvm-shlib cmake build - -Summary: -This fixes a few things that used to work with a Makefile build, but were broken in cmake. - -1. Treat MINGW like a Linux system. -2. The shlib should never contain other shared libraries. - -Subscribers: beanz, mgorny - -Differential Revision: https://reviews.llvm.org/D25865 ---- - tools/llvm-shlib/CMakeLists.txt | 42 ++++++++++++++++++++--------------------- - 1 file changed, 20 insertions(+), 22 deletions(-) - -diff --git a/tools/llvm-shlib/CMakeLists.txt b/tools/llvm-shlib/CMakeLists.txt -index 3fe672d..edadb82 100644 ---- a/tools/llvm-shlib/CMakeLists.txt -+++ b/tools/llvm-shlib/CMakeLists.txt -@@ -8,29 +8,27 @@ set(SOURCES - - llvm_map_components_to_libnames(LIB_NAMES ${LLVM_DYLIB_COMPONENTS}) - --if(LLVM_LINK_LLVM_DYLIB) -- if(LLVM_DYLIB_EXPORTED_SYMBOL_FILE) -- message(WARNING "Using LLVM_LINK_LLVM_DYLIB with LLVM_DYLIB_EXPORTED_SYMBOL_FILE may not work. Use at your own risk.") -- endif() -- -- # libLLVM.so should not have any dependencies on any other LLVM -- # shared libraries. When using the "all" pseudo-component, -- # LLVM_AVAILABLE_LIBS is added to the dependencies, which may -- # contain shared libraries (e.g. libLTO). -- # -- # Also exclude libLLVMTableGen for the following reasons: -- # - it is only used by internal *-tblgen utilities; -- # - it pollutes the global options space. -- foreach(lib ${LIB_NAMES}) -- get_target_property(t ${lib} TYPE) -- if("${lib}" STREQUAL "LLVMTableGen") -- elseif("x${t}" STREQUAL "xSTATIC_LIBRARY") -- list(APPEND FILTERED_LIB_NAMES ${lib}) -- endif() -- endforeach() -- set(LIB_NAMES ${FILTERED_LIB_NAMES}) -+if(LLVM_LINK_LLVM_DYLIB AND LLVM_DYLIB_EXPORTED_SYMBOL_FILE) -+ message(WARNING "Using LLVM_LINK_LLVM_DYLIB with LLVM_DYLIB_EXPORTED_SYMBOL_FILE may not work. Use at your own risk.") - endif() - -+# libLLVM.so should not have any dependencies on any other LLVM -+# shared libraries. When using the "all" pseudo-component, -+# LLVM_AVAILABLE_LIBS is added to the dependencies, which may -+# contain shared libraries (e.g. libLTO). -+# -+# Also exclude libLLVMTableGen for the following reasons: -+# - it is only used by internal *-tblgen utilities; -+# - it pollutes the global options space. -+foreach(lib ${LIB_NAMES}) -+ get_target_property(t ${lib} TYPE) -+ if("${lib}" STREQUAL "LLVMTableGen") -+ elseif("x${t}" STREQUAL "xSTATIC_LIBRARY") -+ list(APPEND FILTERED_LIB_NAMES ${lib}) -+ endif() -+endforeach() -+set(LIB_NAMES ${FILTERED_LIB_NAMES}) -+ - if(LLVM_DYLIB_EXPORTED_SYMBOL_FILE) - set(LLVM_EXPORTED_SYMBOL_FILE ${LLVM_DYLIB_EXPORTED_SYMBOL_FILE}) - add_custom_target(libLLVMExports DEPENDS ${LLVM_EXPORTED_SYMBOL_FILE}) -@@ -39,7 +37,7 @@ endif() - add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB SONAME ${SOURCES}) - - list(REMOVE_DUPLICATES LIB_NAMES) --if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") # FIXME: It should be "GNU ld for elf" -+if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" OR MINGW) # FIXME: It should be "GNU ld for elf" - # GNU ld doesn't resolve symbols in the version script. - set(LIB_NAMES -Wl,--whole-archive ${LIB_NAMES} -Wl,--no-whole-archive) - elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") --- -2.10.1 - diff --git a/deps/patches/llvm-D27389.patch b/deps/patches/llvm-D27389.patch deleted file mode 100644 index 6ddc6e71e3b60..0000000000000 --- a/deps/patches/llvm-D27389.patch +++ /dev/null @@ -1,66 +0,0 @@ -commit 83dc06334ff95ad18a951d0bb540290510f2f81a -Author: Keno Fischer -Date: Thu Dec 8 17:22:35 2016 +0000 - - ConstantFolding: Don't crash when encountering vector GEP - - ConstantFolding tried to cast one of the scalar indices to a vector - type. Instead, use the vector type only for the first index (which - is the only one allowed to be a vector) and use its scalar type - otherwise. - - Fixes PR31250. - - Reviewers: majnemer - Differential Revision: https://reviews.llvm.org/D27389 - - git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289073 91177308-0d34-0410-b5e6-96231b3b80d8 - -diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp -index 2d1edfe..1c0bf01a 100644 ---- a/lib/Analysis/ConstantFolding.cpp -+++ b/lib/Analysis/ConstantFolding.cpp -@@ -692,14 +692,15 @@ Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef Ops, - Type *ResultTy, const DataLayout &DL, - const TargetLibraryInfo *TLI) { - Type *IntPtrTy = DL.getIntPtrType(ResultTy); -+ Type *IntPtrScalarTy = IntPtrTy->getScalarType(); - - bool Any = false; - SmallVector NewIdxs; - for (unsigned i = 1, e = Ops.size(); i != e; ++i) { - if ((i == 1 || -- !isa(GetElementPtrInst::getIndexedType(SrcElemTy, -- Ops.slice(1, i - 1)))) && -- Ops[i]->getType() != IntPtrTy) { -+ !isa(GetElementPtrInst::getIndexedType( -+ SrcElemTy, Ops.slice(1, i - 1)))) && -+ Ops[i]->getType() != (i == 1 ? IntPtrTy : IntPtrScalarTy)) { - Any = true; - NewIdxs.push_back(ConstantExpr::getCast(CastInst::getCastOpcode(Ops[i], - true, -diff --git a/test/Analysis/ConstantFolding/vectorgep-crash.ll b/test/Analysis/ConstantFolding/vectorgep-crash.ll -new file mode 100644 -index 0000000..bcc96b2 ---- /dev/null -+++ b/test/Analysis/ConstantFolding/vectorgep-crash.ll -@@ -0,0 +1,19 @@ -+; RUN: opt -instcombine -S -o - %s | FileCheck %s -+; Tests that we don't crash upon encountering a vector GEP -+ -+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -+target triple = "x86_64-unknown-linux-gnu" -+ -+%Dual = type { %Dual.72, %Partials.73 } -+%Dual.72 = type { double, %Partials } -+%Partials = type { [2 x double] } -+%Partials.73 = type { [2 x %Dual.72] } -+ -+; Function Attrs: sspreq -+define <8 x i64*> @"julia_axpy!_65480"(%Dual* %arg1, <8 x i64> %arg2) { -+top: -+; CHECK: %VectorGep14 = getelementptr inbounds %Dual, %Dual* %arg1, <8 x i64> %arg2, i32 1, i32 0, i64 0, i32 1, i32 0, i64 0 -+ %VectorGep14 = getelementptr inbounds %Dual, %Dual* %arg1, <8 x i64> %arg2, i32 1, i32 0, i64 0, i32 1, i32 0, i64 0 -+ %0 = bitcast <8 x double*> %VectorGep14 to <8 x i64*> -+ ret <8 x i64*> %0 -+} diff --git a/deps/patches/llvm-D27397.patch b/deps/patches/llvm-D27397.patch deleted file mode 100644 index fd18b3f3634b4..0000000000000 --- a/deps/patches/llvm-D27397.patch +++ /dev/null @@ -1,101 +0,0 @@ -commit 99ca52276f9ee1386866d6dff6179cfa64824621 -Author: Keno Fischer -Date: Mon Dec 5 21:25:03 2016 +0000 - - [LAA] Prevent invalid IR for loop-invariant bound in loop body - - Summary: - If LAA expands a bound that is loop invariant, but not hoisted out - of the loop body, it used to use that value anyway, causing a - non-domination error, because the memcheck block is of course not - dominated by the scalar loop body. Detect this situation and expand - the SCEV expression instead. - - Fixes PR31251 - - Reviewers: anemet - Subscribers: mzolotukhin, llvm-commits - - Differential Revision: https://reviews.llvm.org/D27397 - - git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288705 91177308-0d34-0410-b5e6-96231b3b80d8 - -diff --git a/lib/Analysis/LoopAccessAnalysis.cpp b/lib/Analysis/LoopAccessAnalysis.cpp -index 01a2f46..2f3dca3 100644 ---- a/lib/Analysis/LoopAccessAnalysis.cpp -+++ b/lib/Analysis/LoopAccessAnalysis.cpp -@@ -1870,18 +1870,24 @@ expandBounds(const RuntimePointerChecking::CheckingPtrGroup *CG, Loop *TheLoop, - Value *Ptr = PtrRtChecking.Pointers[CG->Members[0]].PointerValue; - const SCEV *Sc = SE->getSCEV(Ptr); - -+ unsigned AS = Ptr->getType()->getPointerAddressSpace(); -+ LLVMContext &Ctx = Loc->getContext(); -+ -+ // Use this type for pointer arithmetic. -+ Type *PtrArithTy = Type::getInt8PtrTy(Ctx, AS); -+ - if (SE->isLoopInvariant(Sc, TheLoop)) { - DEBUG(dbgs() << "LAA: Adding RT check for a loop invariant ptr:" << *Ptr - << "\n"); -- return {Ptr, Ptr}; -+ // Ptr could be in the loop body. If so, expand a new one at the correct -+ // location. -+ Instruction *Inst = dyn_cast(Ptr); -+ Value *NewPtr = (Inst && TheLoop->contains(Inst)) -+ ? Exp.expandCodeFor(Sc, PtrArithTy, Loc) -+ : Ptr; -+ return {NewPtr, NewPtr}; - } else { -- unsigned AS = Ptr->getType()->getPointerAddressSpace(); -- LLVMContext &Ctx = Loc->getContext(); -- -- // Use this type for pointer arithmetic. -- Type *PtrArithTy = Type::getInt8PtrTy(Ctx, AS); - Value *Start = nullptr, *End = nullptr; -- - DEBUG(dbgs() << "LAA: Adding RT check for range:\n"); - Start = Exp.expandCodeFor(CG->Low, PtrArithTy, Loc); - End = Exp.expandCodeFor(CG->High, PtrArithTy, Loc); -diff --git a/test/Transforms/LoopVersioning/loop-invariant-bound.ll b/test/Transforms/LoopVersioning/loop-invariant-bound.ll -new file mode 100644 -index 0000000..3411adb ---- /dev/null -+++ b/test/Transforms/LoopVersioning/loop-invariant-bound.ll -@@ -0,0 +1,37 @@ -+; RUN: opt -loop-versioning -S < %s | FileCheck %s -+; Checks that when introducing check, we don't accidentally introduce non-dominating instructions -+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -+ -+%Dual.212 = type { %Dual.213, %Partials.215 } -+%Dual.213 = type { double, %Partials.214 } -+%Partials.214 = type { [2 x double] } -+%Partials.215 = type { [2 x %Dual.213] } -+ -+; Function Attrs: sspreq -+define void @"julia_axpy!_65480"(%Dual.212*) { -+top: -+ br label %if24 -+ -+; CHECK-NOT: %bc = bitcast i64* %v2.sroa.0.0..sroa_cast -+; CHECK: %bound0 -+ -+if24: ; preds = %if24, %top -+ %"#temp#1.sroa.3.02" = phi i64 [ undef, %top ], [ %2, %if24 ] -+ %"#temp#1.sroa.0.01" = phi i64 [ undef, %top ], [ %1, %if24 ] -+ %1 = add i64 %"#temp#1.sroa.0.01", 1 -+ %2 = add i64 %"#temp#1.sroa.3.02", 1 -+ ; This pointer is loop invariant. LAA used to re-use it from memcheck, even though it didn't dominate. -+ %v2.sroa.0.0..sroa_cast = bitcast %Dual.212* %0 to i64* -+ %v2.sroa.0.0.copyload = load i64, i64* %v2.sroa.0.0..sroa_cast, align 1 -+ %3 = add i64 %"#temp#1.sroa.0.01", -1 -+ %4 = getelementptr inbounds %Dual.212, %Dual.212* undef, i64 %3, i32 1, i32 0, i64 0, i32 1, i32 0, i64 0 -+ %5 = bitcast double* %4 to i64* -+ store i64 undef, i64* %5, align 8 -+ %notlhs27 = icmp eq i64 %2, undef -+ %notrhs28 = icmp eq i64 %1, undef -+ %6 = or i1 %notrhs28, %notlhs27 -+ br i1 %6, label %L41.L335_crit_edge, label %if24 -+ -+L41.L335_crit_edge: ; preds = %if24 -+ ret void -+} diff --git a/deps/patches/llvm-D27609-AArch64-UABS_G3.patch b/deps/patches/llvm-D27609-AArch64-UABS_G3.patch deleted file mode 100644 index ba4a1b76d5804..0000000000000 --- a/deps/patches/llvm-D27609-AArch64-UABS_G3.patch +++ /dev/null @@ -1,311 +0,0 @@ -From df0ce05530fd3a0e4c283af817f4446d439647ea Mon Sep 17 00:00:00 2001 -From: yuyichao -Date: Thu, 15 Dec 2016 22:36:53 +0000 -Subject: [PATCH 1/2] Fix R_AARCH64_MOVW_UABS_G3 relocation - -Summary: The relocation is missing mask so an address that has non-zero bits in 47:43 may overwrite the register number. (Frequently shows up as target register changed to `xzr`....) - -Reviewers: t.p.northover, lhames - -Subscribers: davide, aemerson, rengolin, llvm-commits - -Differential Revision: https://reviews.llvm.org/D27609 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289880 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - include/llvm/Object/ELFObjectFile.h | 2 +- - include/llvm/Object/RelocVisitor.h | 1 + - lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 72 +++++++++++++++------- - .../RuntimeDyld/AArch64/ELF_ARM64_BE-relocations.s | 34 ++++++++++ - .../RuntimeDyld/AArch64/ELF_ARM64_relocations.s | 33 ++++++++++ - 5 files changed, 118 insertions(+), 24 deletions(-) - create mode 100644 test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-relocations.s - create mode 100644 test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_relocations.s - -diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h -index 4209da8..69987d4 100644 ---- a/include/llvm/Object/ELFObjectFile.h -+++ b/include/llvm/Object/ELFObjectFile.h -@@ -972,7 +972,7 @@ unsigned ELFObjectFile::getArch() const { - case ELF::EM_X86_64: - return Triple::x86_64; - case ELF::EM_AARCH64: -- return Triple::aarch64; -+ return IsLittleEndian ? Triple::aarch64 : Triple::aarch64_be; - case ELF::EM_ARM: - return Triple::arm; - case ELF::EM_AVR: -diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h -index e1926aa..3510d29 100644 ---- a/include/llvm/Object/RelocVisitor.h -+++ b/include/llvm/Object/RelocVisitor.h -@@ -86,6 +86,7 @@ private: - return RelocToApply(); - } - case Triple::aarch64: -+ case Triple::aarch64_be: - switch (RelocType) { - case llvm::ELF::R_AARCH64_ABS32: - return visitELF_AARCH64_ABS32(R, Value); -diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp -index c70e81a..a977dce 100644 ---- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp -+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp -@@ -325,6 +325,8 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, - uint32_t *TargetPtr = - reinterpret_cast(Section.getAddressWithOffset(Offset)); - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); -+ // Data should use target endian. Code should always use little endian. -+ bool isBE = Arch == Triple::aarch64_be; - - DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x" - << format("%llx", Section.getAddressWithOffset(Offset)) -@@ -340,14 +342,22 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, - case ELF::R_AARCH64_ABS64: { - uint64_t *TargetPtr = - reinterpret_cast(Section.getAddressWithOffset(Offset)); -- *TargetPtr = Value + Addend; -+ if (isBE) -+ support::ubig64_t::ref{TargetPtr} = Value + Addend; -+ else -+ support::ulittle64_t::ref{TargetPtr} = Value + Addend; - break; - } - case ELF::R_AARCH64_PREL32: { - uint64_t Result = Value + Addend - FinalAddress; - assert(static_cast(Result) >= INT32_MIN && - static_cast(Result) <= UINT32_MAX); -- *TargetPtr = static_cast(Result & 0xffffffffU); -+ if (isBE) -+ support::ubig32_t::ref{TargetPtr} = -+ static_cast(Result & 0xffffffffU); -+ else -+ support::ulittle32_t::ref{TargetPtr} = -+ static_cast(Result & 0xffffffffU); - break; - } - case ELF::R_AARCH64_CALL26: // fallthrough -@@ -355,104 +365,120 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, - // Operation: S+A-P. Set Call or B immediate value to bits fff_fffc of the - // calculation. - uint64_t BranchImm = Value + Addend - FinalAddress; -+ uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr}; - - // "Check that -2^27 <= result < 2^27". - assert(isInt<28>(BranchImm)); - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. -- *TargetPtr &= 0xfc000000U; -+ TargetValue &= 0xfc000000U; - // Immediate goes in bits 25:0 of B and BL. -- *TargetPtr |= static_cast(BranchImm & 0xffffffcU) >> 2; -+ TargetValue |= static_cast(BranchImm & 0xffffffcU) >> 2; -+ support::ulittle32_t::ref{TargetPtr} = TargetValue; - break; - } - case ELF::R_AARCH64_MOVW_UABS_G3: { - uint64_t Result = Value + Addend; -+ uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr}; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. -- *TargetPtr &= 0xffe0001fU; -+ TargetValue &= 0xffe0001fU; - // Immediate goes in bits 20:5 of MOVZ/MOVK instruction -- *TargetPtr |= Result >> (48 - 5); -+ TargetValue |= ((Result & 0xffff000000000000ULL) >> (48 - 5)); - // Shift must be "lsl #48", in bits 22:21 -- assert((*TargetPtr >> 21 & 0x3) == 3 && "invalid shift for relocation"); -+ assert((TargetValue >> 21 & 0x3) == 3 && "invalid shift for relocation"); -+ support::ulittle32_t::ref{TargetPtr} = TargetValue; - break; - } - case ELF::R_AARCH64_MOVW_UABS_G2_NC: { - uint64_t Result = Value + Addend; -+ uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr}; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. -- *TargetPtr &= 0xffe0001fU; -+ TargetValue &= 0xffe0001fU; - // Immediate goes in bits 20:5 of MOVZ/MOVK instruction -- *TargetPtr |= ((Result & 0xffff00000000ULL) >> (32 - 5)); -+ TargetValue |= ((Result & 0xffff00000000ULL) >> (32 - 5)); - // Shift must be "lsl #32", in bits 22:21 -- assert((*TargetPtr >> 21 & 0x3) == 2 && "invalid shift for relocation"); -+ assert((TargetValue >> 21 & 0x3) == 2 && "invalid shift for relocation"); -+ support::ulittle32_t::ref{TargetPtr} = TargetValue; - break; - } - case ELF::R_AARCH64_MOVW_UABS_G1_NC: { - uint64_t Result = Value + Addend; -+ uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr}; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. -- *TargetPtr &= 0xffe0001fU; -+ TargetValue &= 0xffe0001fU; - // Immediate goes in bits 20:5 of MOVZ/MOVK instruction -- *TargetPtr |= ((Result & 0xffff0000U) >> (16 - 5)); -+ TargetValue |= ((Result & 0xffff0000U) >> (16 - 5)); - // Shift must be "lsl #16", in bits 22:2 -- assert((*TargetPtr >> 21 & 0x3) == 1 && "invalid shift for relocation"); -+ assert((TargetValue >> 21 & 0x3) == 1 && "invalid shift for relocation"); -+ support::ulittle32_t::ref{TargetPtr} = TargetValue; - break; - } - case ELF::R_AARCH64_MOVW_UABS_G0_NC: { - uint64_t Result = Value + Addend; -+ uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr}; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. -- *TargetPtr &= 0xffe0001fU; -+ TargetValue &= 0xffe0001fU; - // Immediate goes in bits 20:5 of MOVZ/MOVK instruction -- *TargetPtr |= ((Result & 0xffffU) << 5); -+ TargetValue |= ((Result & 0xffffU) << 5); - // Shift must be "lsl #0", in bits 22:21. -- assert((*TargetPtr >> 21 & 0x3) == 0 && "invalid shift for relocation"); -+ assert((TargetValue >> 21 & 0x3) == 0 && "invalid shift for relocation"); -+ support::ulittle32_t::ref{TargetPtr} = TargetValue; - break; - } - case ELF::R_AARCH64_ADR_PREL_PG_HI21: { - // Operation: Page(S+A) - Page(P) - uint64_t Result = - ((Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL); -+ uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr}; - - // Check that -2^32 <= X < 2^32 - assert(isInt<33>(Result) && "overflow check failed for relocation"); - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. -- *TargetPtr &= 0x9f00001fU; -+ TargetValue &= 0x9f00001fU; - // Immediate goes in bits 30:29 + 5:23 of ADRP instruction, taken - // from bits 32:12 of X. -- *TargetPtr |= ((Result & 0x3000U) << (29 - 12)); -- *TargetPtr |= ((Result & 0x1ffffc000ULL) >> (14 - 5)); -+ TargetValue |= ((Result & 0x3000U) << (29 - 12)); -+ TargetValue |= ((Result & 0x1ffffc000ULL) >> (14 - 5)); -+ support::ulittle32_t::ref{TargetPtr} = TargetValue; - break; - } - case ELF::R_AARCH64_LDST32_ABS_LO12_NC: { - // Operation: S + A - uint64_t Result = Value + Addend; -+ uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr}; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. -- *TargetPtr &= 0xffc003ffU; -+ TargetValue &= 0xffc003ffU; - // Immediate goes in bits 21:10 of LD/ST instruction, taken - // from bits 11:2 of X -- *TargetPtr |= ((Result & 0xffc) << (10 - 2)); -+ TargetValue |= ((Result & 0xffc) << (10 - 2)); -+ support::ulittle32_t::ref{TargetPtr} = TargetValue; - break; - } - case ELF::R_AARCH64_LDST64_ABS_LO12_NC: { - // Operation: S + A - uint64_t Result = Value + Addend; -+ uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr}; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. -- *TargetPtr &= 0xffc003ffU; -+ TargetValue &= 0xffc003ffU; - // Immediate goes in bits 21:10 of LD/ST instruction, taken - // from bits 11:3 of X -- *TargetPtr |= ((Result & 0xff8) << (10 - 3)); -+ TargetValue |= ((Result & 0xff8) << (10 - 3)); -+ support::ulittle32_t::ref{TargetPtr} = TargetValue; - break; - } - } -diff --git a/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-relocations.s b/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-relocations.s -new file mode 100644 -index 0000000..3ba95e4 ---- /dev/null -+++ b/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-relocations.s -@@ -0,0 +1,34 @@ -+# RUN: llvm-mc -triple=aarch64_be-none-linux-gnu -filetype=obj -o %T/be-reloc.o %s -+# RUN: llvm-rtdyld -triple=aarch64_be-none-linux-gnu -verify -dummy-extern f=0x0123456789abcdef -check=%s %T/be-reloc.o -+ -+ .text -+ .globl g -+ .p2align 2 -+ .type g,@function -+g: -+# R_AARCH64_MOVW_UABS_G3 -+ movz x0, #:abs_g3:f -+# R_AARCH64_MOVW_UABS_G2_NC -+ movk x0, #:abs_g2_nc:f -+# R_AARCH64_MOVW_UABS_G1_NC -+ movk x0, #:abs_g1_nc:f -+# R_AARCH64_MOVW_UABS_G0_NC -+ movk x0, #:abs_g0_nc:f -+ ret -+ .Lfunc_end0: -+ .size g, .Lfunc_end0-g -+ -+ .type k,@object -+ .data -+ .globl k -+ .p2align 3 -+k: -+ .xword f -+ .size k, 8 -+ -+# LE instructions read as BE -+# rtdyld-check: *{4}(g) = 0x6024e0d2 -+# rtdyld-check: *{4}(g + 4) = 0xe0acc8f2 -+# rtdyld-check: *{4}(g + 8) = 0x6035b1f2 -+# rtdyld-check: *{4}(g + 12) = 0xe0bd99f2 -+# rtdyld-check: *{8}k = f -diff --git a/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_relocations.s b/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_relocations.s -new file mode 100644 -index 0000000..f83f6bf ---- /dev/null -+++ b/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_relocations.s -@@ -0,0 +1,33 @@ -+# RUN: llvm-mc -triple=arm64-none-linux-gnu -filetype=obj -o %T/reloc.o %s -+# RUN: llvm-rtdyld -triple=arm64-none-linux-gnu -verify -dummy-extern f=0x0123456789abcdef -check=%s %T/reloc.o -+ -+ .text -+ .globl g -+ .p2align 2 -+ .type g,@function -+g: -+# R_AARCH64_MOVW_UABS_G3 -+ movz x0, #:abs_g3:f -+# R_AARCH64_MOVW_UABS_G2_NC -+ movk x0, #:abs_g2_nc:f -+# R_AARCH64_MOVW_UABS_G1_NC -+ movk x0, #:abs_g1_nc:f -+# R_AARCH64_MOVW_UABS_G0_NC -+ movk x0, #:abs_g0_nc:f -+ ret -+ .Lfunc_end0: -+ .size g, .Lfunc_end0-g -+ -+ .type k,@object -+ .data -+ .globl k -+ .p2align 3 -+k: -+ .xword f -+ .size k, 8 -+ -+# rtdyld-check: *{4}(g) = 0xd2e02460 -+# rtdyld-check: *{4}(g + 4) = 0xf2c8ace0 -+# rtdyld-check: *{4}(g + 8) = 0xf2b13560 -+# rtdyld-check: *{4}(g + 12) = 0xf299bde0 -+# rtdyld-check: *{8}k = f --- -2.10.2 - diff --git a/deps/patches/llvm-D27629-AArch64-large_model.patch b/deps/patches/llvm-D27629-AArch64-large_model.patch deleted file mode 100644 index ed288534f0690..0000000000000 --- a/deps/patches/llvm-D27629-AArch64-large_model.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 073a3b4c0e422396016ddea15181411e45c96af5 Mon Sep 17 00:00:00 2001 -From: Yichao Yu -Date: Fri, 9 Dec 2016 15:59:46 -0500 -Subject: [PATCH 2/2] Fix unwind info relocation with large code model on - AArch64 - ---- - lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 10 ++++++++++ - lib/MC/MCObjectFileInfo.cpp | 2 ++ - .../AArch64/ELF_ARM64_BE-large-relocations.s | 18 ++++++++++++++++++ - .../RuntimeDyld/AArch64/ELF_ARM64_large-relocations.s | 18 ++++++++++++++++++ - 4 files changed, 48 insertions(+) - create mode 100644 test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-large-relocations.s - create mode 100644 test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_large-relocations.s - -diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp -index a977dce..2a832f8 100644 ---- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp -+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp -@@ -360,6 +360,16 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, - static_cast(Result & 0xffffffffU); - break; - } -+ case ELF::R_AARCH64_PREL64: { -+ uint64_t *TargetPtr = -+ reinterpret_cast(Section.getAddressWithOffset(Offset)); -+ uint64_t Result = Value + Addend - FinalAddress; -+ if (isBE) -+ support::ubig64_t::ref{TargetPtr} = Result; -+ else -+ support::ulittle64_t::ref{TargetPtr} = Result; -+ break; -+ } - case ELF::R_AARCH64_CALL26: // fallthrough - case ELF::R_AARCH64_JUMP26: { - // Operation: S+A-P. Set Call or B immediate value to bits fff_fffc of the -diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp -index 8fd71f6..bcf774e 100644 ---- a/lib/MC/MCObjectFileInfo.cpp -+++ b/lib/MC/MCObjectFileInfo.cpp -@@ -279,6 +279,8 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T) { - case Triple::mips64el: - FDECFIEncoding = dwarf::DW_EH_PE_sdata8; - break; -+ case Triple::aarch64: -+ case Triple::aarch64_be: - case Triple::x86_64: - FDECFIEncoding = dwarf::DW_EH_PE_pcrel | - ((CMModel == CodeModel::Large) ? dwarf::DW_EH_PE_sdata8 -diff --git a/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-large-relocations.s b/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-large-relocations.s -new file mode 100644 -index 0000000..e3eeb02 ---- /dev/null -+++ b/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-large-relocations.s -@@ -0,0 +1,18 @@ -+# RUN: llvm-mc -triple=aarch64_be-none-linux-gnu -code-model=large -filetype=obj -o %T/be-large-reloc.o %s -+# RUN: llvm-rtdyld -triple=aarch64_be-none-linux-gnu -verify -map-section be-large-reloc.o,.eh_frame=0x10000 -map-section be-large-reloc.o,.text=0xffff000000000000 -check=%s %T/be-large-reloc.o -+ -+ .text -+ .globl g -+ .p2align 2 -+ .type g,@function -+g: -+ .cfi_startproc -+ mov x0, xzr -+ ret -+ .Lfunc_end0: -+ .size g, .Lfunc_end0-g -+ .cfi_endproc -+ -+# Skip the CIE and load the 8 bytes PC begin pointer. -+# Assuming the CIE and the FDE length are both 4 bytes. -+# rtdyld-check: *{8}(section_addr(be-large-reloc.o, .eh_frame) + (*{4}(section_addr(be-large-reloc.o, .eh_frame))) + 0xc) = g - (section_addr(be-large-reloc.o, .eh_frame) + (*{4}(section_addr(be-large-reloc.o, .eh_frame))) + 0xc) -diff --git a/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_large-relocations.s b/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_large-relocations.s -new file mode 100644 -index 0000000..ec30f19 ---- /dev/null -+++ b/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_large-relocations.s -@@ -0,0 +1,18 @@ -+# RUN: llvm-mc -triple=arm64-none-linux-gnu -code-model=large -filetype=obj -o %T/large-reloc.o %s -+# RUN: llvm-rtdyld -triple=arm64-none-linux-gnu -verify -map-section large-reloc.o,.eh_frame=0x10000 -map-section large-reloc.o,.text=0xffff000000000000 -check=%s %T/large-reloc.o -+ -+ .text -+ .globl g -+ .p2align 2 -+ .type g,@function -+g: -+ .cfi_startproc -+ mov x0, xzr -+ ret -+ .Lfunc_end0: -+ .size g, .Lfunc_end0-g -+ .cfi_endproc -+ -+# Skip the CIE and load the 8 bytes PC begin pointer. -+# Assuming the CIE and the FDE length are both 4 bytes. -+# rtdyld-check: *{8}(section_addr(large-reloc.o, .eh_frame) + (*{4}(section_addr(large-reloc.o, .eh_frame))) + 0xc) = g - (section_addr(large-reloc.o, .eh_frame) + (*{4}(section_addr(large-reloc.o, .eh_frame))) + 0xc) --- -2.10.2 - diff --git a/deps/patches/llvm-D28009.patch b/deps/patches/llvm-D28009.patch deleted file mode 100644 index ceba0b1900130..0000000000000 --- a/deps/patches/llvm-D28009.patch +++ /dev/null @@ -1,68 +0,0 @@ -commit 57ab82784ddb8d21eb0041d52f8490d8fd404e29 -Author: Michael Kuperstein -Date: Wed Dec 21 17:34:21 2016 +0000 - - [ConstantFolding] Fix vector GEPs harder - - For vector GEPs, CastGEPIndices can end up in an infinite recursion, because - we compare the vector type to the scalar pointer type, find them different, - and then try to cast a type to itself. - - Differential Revision: https://reviews.llvm.org/D28009 - - - git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290260 91177308-0d34-0410-b5e6-96231b3b80d8 - -diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp -index cf0d5e4..9e521e1 100644 ---- a/lib/Analysis/ConstantFolding.cpp -+++ b/lib/Analysis/ConstantFolding.cpp -@@ -742,13 +742,16 @@ Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef Ops, - if ((i == 1 || - !isa(GetElementPtrInst::getIndexedType( - SrcElemTy, Ops.slice(1, i - 1)))) && -- Ops[i]->getType() != (i == 1 ? IntPtrTy : IntPtrScalarTy)) { -+ Ops[i]->getType()->getScalarType() != IntPtrScalarTy) { - Any = true; -+ Type *NewType = Ops[i]->getType()->isVectorTy() -+ ? IntPtrTy -+ : IntPtrTy->getScalarType(); - NewIdxs.push_back(ConstantExpr::getCast(CastInst::getCastOpcode(Ops[i], - true, -- IntPtrTy, -+ NewType, - true), -- Ops[i], IntPtrTy)); -+ Ops[i], NewType)); - } else - NewIdxs.push_back(Ops[i]); - } -diff --git a/test/Analysis/ConstantFolding/vectorgep-crash.ll b/test/Analysis/ConstantFolding/vectorgep-crash.ll -index bcc96b2..e7a5117 100644 ---- a/test/Analysis/ConstantFolding/vectorgep-crash.ll -+++ b/test/Analysis/ConstantFolding/vectorgep-crash.ll -@@ -17,3 +17,24 @@ top: - %0 = bitcast <8 x double*> %VectorGep14 to <8 x i64*> - ret <8 x i64*> %0 - } -+ -+%struct.A = type { i32, %struct.B* } -+%struct.B = type { i64, %struct.C* } -+%struct.C = type { i64 } -+ -+@G = internal global [65 x %struct.A] zeroinitializer, align 16 -+; CHECK-LABEL: @test -+; CHECK: ret <16 x i32*> getelementptr ([65 x %struct.A], [65 x %struct.A]* @G, <16 x i64> zeroinitializer, <16 x i64> , <16 x i32> zeroinitializer) -+define <16 x i32*> @test() { -+vector.body: -+ %VectorGep = getelementptr [65 x %struct.A], [65 x %struct.A]* @G, <16 x i64> zeroinitializer, <16 x i64> , <16 x i32> zeroinitializer -+ ret <16 x i32*> %VectorGep -+} -+ -+; CHECK-LABEL: @test2 -+; CHECK: ret <16 x i32*> getelementptr ([65 x %struct.A], [65 x %struct.A]* @G, <16 x i64> zeroinitializer, <16 x i64> @test2() { -+vector.body: -+ %VectorGep = getelementptr [65 x %struct.A], [65 x %struct.A]* @G, <16 x i32> zeroinitializer, <16 x i64> , <16 x i32> zeroinitializer -+ ret <16 x i32*> %VectorGep -+} diff --git a/deps/patches/llvm-D28215_FreeBSD_shlib.patch b/deps/patches/llvm-D28215_FreeBSD_shlib.patch deleted file mode 100644 index aa06a6a428db9..0000000000000 --- a/deps/patches/llvm-D28215_FreeBSD_shlib.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: tools/llvm-shlib/CMakeLists.txt -=================================================================== ---- a/tools/llvm-shlib/CMakeLists.txt -+++ b/tools/llvm-shlib/CMakeLists.txt -@@ -37,7 +37,7 @@ - add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB SONAME ${SOURCES}) - - list(REMOVE_DUPLICATES LIB_NAMES) --if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" OR MINGW) # FIXME: It should be "GNU ld for elf" -+if(("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") OR (MINGW) OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD") OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly")) # FIXME: It should be "GNU ld for elf" - # GNU ld doesn't resolve symbols in the version script. - set(LIB_NAMES -Wl,--whole-archive ${LIB_NAMES} -Wl,--no-whole-archive) - elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") diff --git a/deps/patches/llvm-D28221-avx512.patch b/deps/patches/llvm-D28221-avx512.patch deleted file mode 100644 index 659c814a37ebe..0000000000000 --- a/deps/patches/llvm-D28221-avx512.patch +++ /dev/null @@ -1,22 +0,0 @@ -Index: lib/Support/Host.cpp -=================================================================== ---- a/lib/Support/Host.cpp -+++ b/lib/Support/Host.cpp -@@ -475,13 +475,14 @@ - - // Skylake: - case 0x4e: -- *Type = INTEL_COREI7; // "skylake-avx512" -- *Subtype = INTEL_COREI7_SKYLAKE_AVX512; -- break; - case 0x5e: - *Type = INTEL_COREI7; // "skylake" - *Subtype = INTEL_COREI7_SKYLAKE; - break; -+ case 0x55: -+ *Type = INTEL_COREI7; // "skylake-avx512" -+ *Subtype = INTEL_COREI7_SKYLAKE_AVX512; -+ break; - - case 0x1c: // Most 45 nm Intel Atom processors - case 0x26: // 45 nm Atom Lincroft diff --git a/deps/patches/llvm-D28476-musl-targetlibraryinfo_3.9.patch b/deps/patches/llvm-D28476-musl-targetlibraryinfo_3.9.patch deleted file mode 100644 index 764512f5066a6..0000000000000 --- a/deps/patches/llvm-D28476-musl-targetlibraryinfo_3.9.patch +++ /dev/null @@ -1,3955 +0,0 @@ -commit 30f85ead353e6606db51b73908dd9862b005385b -Author: David L. Jones -Date: Mon Jan 23 23:16:46 2017 +0000 - - [Analysis] Add LibFunc_ prefix to enums in TargetLibraryInfo. (NFC) - - Summary: - The LibFunc::Func enum holds enumerators named for libc functions. - Unfortunately, there are real situations, including libc implementations, where - function names are actually macros (musl uses "#define fopen64 fopen", for - example; any other transitively visible macro would have similar effects). - - Strictly speaking, a conforming C++ Standard Library should provide any such - macros as functions instead (via ). However, there are some "library" - functions which are not part of the standard, and thus not subject to this - rule (fopen64, for example). So, in order to be both portable and consistent, - the enum should not use the bare function names. - - The old enum naming used a namespace LibFunc and an enum Func, with bare - enumerators. This patch changes LibFunc to be an enum with enumerators prefixed - with "LibFFunc_". (Unfortunately, a scoped enum is not sufficient to override - macros.) - - There are additional changes required in clang. - - Reviewers: rsmith - - Subscribers: mehdi_amini, mzolotukhin, nemanjai, llvm-commits - - Differential Revision: https://reviews.llvm.org/D28476 - - git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292848 91177308-0d34-0410-b5e6-96231b3b80d8 - -diff --git a/include/llvm/Analysis/TargetLibraryInfo.def b/include/llvm/Analysis/TargetLibraryInfo.def -index b2a593d67dc..775e2f31733 100644 ---- a/include/llvm/Analysis/TargetLibraryInfo.def -+++ b/include/llvm/Analysis/TargetLibraryInfo.def -@@ -20,7 +20,7 @@ - // One of TLI_DEFINE_ENUM/STRING are defined. - - #if defined(TLI_DEFINE_ENUM) --#define TLI_DEFINE_ENUM_INTERNAL(enum_variant) enum_variant, -+#define TLI_DEFINE_ENUM_INTERNAL(enum_variant) LibFunc_##enum_variant, - #define TLI_DEFINE_STRING_INTERNAL(string_repr) - #else - #define TLI_DEFINE_ENUM_INTERNAL(enum_variant) -diff --git a/include/llvm/Analysis/TargetLibraryInfo.h b/include/llvm/Analysis/TargetLibraryInfo.h -index 7efa6f05970..48156de1c3b 100644 ---- a/include/llvm/Analysis/TargetLibraryInfo.h -+++ b/include/llvm/Analysis/TargetLibraryInfo.h -@@ -30,14 +30,12 @@ struct VecDesc { - unsigned VectorizationFactor; - }; - -- namespace LibFunc { -- enum Func { -+ enum LibFunc { - #define TLI_DEFINE_ENUM - #include "llvm/Analysis/TargetLibraryInfo.def" - -- NumLibFuncs -- }; -- } -+ NumLibFuncs -+ }; - - /// Implementation of the target library information. - /// -@@ -48,20 +46,20 @@ struct VecDesc { - class TargetLibraryInfoImpl { - friend class TargetLibraryInfo; - -- unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4]; -+ unsigned char AvailableArray[(NumLibFuncs+3)/4]; - llvm::DenseMap CustomNames; -- static const char *const StandardNames[LibFunc::NumLibFuncs]; -+ static const char *const StandardNames[NumLibFuncs]; - - enum AvailabilityState { - StandardName = 3, // (memset to all ones) - CustomName = 1, - Unavailable = 0 // (memset to all zeros) - }; -- void setState(LibFunc::Func F, AvailabilityState State) { -+ void setState(LibFunc F, AvailabilityState State) { - AvailableArray[F/4] &= ~(3 << 2*(F&3)); - AvailableArray[F/4] |= State << 2*(F&3); - } -- AvailabilityState getState(LibFunc::Func F) const { -+ AvailabilityState getState(LibFunc F) const { - return static_cast((AvailableArray[F/4] >> 2*(F&3)) & 3); - } - -@@ -73,7 +71,7 @@ class TargetLibraryInfoImpl { - - /// Return true if the function type FTy is valid for the library function - /// F, regardless of whether the function is available. -- bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc::Func F, -+ bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, - const DataLayout *DL) const; - - public: -@@ -102,28 +100,28 @@ public: - /// - /// If it is one of the known library functions, return true and set F to the - /// corresponding value. -- bool getLibFunc(StringRef funcName, LibFunc::Func &F) const; -+ bool getLibFunc(StringRef funcName, LibFunc &F) const; - - /// Searches for a particular function name, also checking that its type is - /// valid for the library function matching that name. - /// - /// If it is one of the known library functions, return true and set F to the - /// corresponding value. -- bool getLibFunc(const Function &FDecl, LibFunc::Func &F) const; -+ bool getLibFunc(const Function &FDecl, LibFunc &F) const; - - /// Forces a function to be marked as unavailable. -- void setUnavailable(LibFunc::Func F) { -+ void setUnavailable(LibFunc F) { - setState(F, Unavailable); - } - - /// Forces a function to be marked as available. -- void setAvailable(LibFunc::Func F) { -+ void setAvailable(LibFunc F) { - setState(F, StandardName); - } - - /// Forces a function to be marked as available and provide an alternate name - /// that must be used. -- void setAvailableWithName(LibFunc::Func F, StringRef Name) { -+ void setAvailableWithName(LibFunc F, StringRef Name) { - if (StandardNames[F] != Name) { - setState(F, CustomName); - CustomNames[F] = Name; -@@ -203,16 +201,16 @@ public: - /// - /// If it is one of the known library functions, return true and set F to the - /// corresponding value. -- bool getLibFunc(StringRef funcName, LibFunc::Func &F) const { -+ bool getLibFunc(StringRef funcName, LibFunc &F) const { - return Impl->getLibFunc(funcName, F); - } - -- bool getLibFunc(const Function &FDecl, LibFunc::Func &F) const { -+ bool getLibFunc(const Function &FDecl, LibFunc &F) const { - return Impl->getLibFunc(FDecl, F); - } - - /// Tests whether a library function is available. -- bool has(LibFunc::Func F) const { -+ bool has(LibFunc F) const { - return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable; - } - bool isFunctionVectorizable(StringRef F, unsigned VF) const { -@@ -227,37 +225,37 @@ public: - - /// Tests if the function is both available and a candidate for optimized code - /// generation. -- bool hasOptimizedCodeGen(LibFunc::Func F) const { -+ bool hasOptimizedCodeGen(LibFunc F) const { - if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable) - return false; - switch (F) { - default: break; -- case LibFunc::copysign: case LibFunc::copysignf: case LibFunc::copysignl: -- case LibFunc::fabs: case LibFunc::fabsf: case LibFunc::fabsl: -- case LibFunc::sin: case LibFunc::sinf: case LibFunc::sinl: -- case LibFunc::cos: case LibFunc::cosf: case LibFunc::cosl: -- case LibFunc::sqrt: case LibFunc::sqrtf: case LibFunc::sqrtl: -- case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite: -- case LibFunc::sqrtl_finite: -- case LibFunc::fmax: case LibFunc::fmaxf: case LibFunc::fmaxl: -- case LibFunc::fmin: case LibFunc::fminf: case LibFunc::fminl: -- case LibFunc::floor: case LibFunc::floorf: case LibFunc::floorl: -- case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl: -- case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill: -- case LibFunc::rint: case LibFunc::rintf: case LibFunc::rintl: -- case LibFunc::round: case LibFunc::roundf: case LibFunc::roundl: -- case LibFunc::trunc: case LibFunc::truncf: case LibFunc::truncl: -- case LibFunc::log2: case LibFunc::log2f: case LibFunc::log2l: -- case LibFunc::exp2: case LibFunc::exp2f: case LibFunc::exp2l: -- case LibFunc::memcmp: case LibFunc::strcmp: case LibFunc::strcpy: -- case LibFunc::stpcpy: case LibFunc::strlen: case LibFunc::strnlen: -- case LibFunc::memchr: -+ case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl: -+ case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl: -+ case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl: -+ case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl: -+ case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl: -+ case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite: -+ case LibFunc_sqrtl_finite: -+ case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl: -+ case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl: -+ case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl: -+ case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl: -+ case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill: -+ case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl: -+ case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl: -+ case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl: -+ case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l: -+ case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l: -+ case LibFunc_memcmp: case LibFunc_strcmp: case LibFunc_strcpy: -+ case LibFunc_stpcpy: case LibFunc_strlen: case LibFunc_strnlen: -+ case LibFunc_memchr: - return true; - } - return false; - } - -- StringRef getName(LibFunc::Func F) const { -+ StringRef getName(LibFunc F) const { - auto State = Impl->getState(F); - if (State == TargetLibraryInfoImpl::Unavailable) - return StringRef(); -diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h -index 92ee2463395..a294ebae4b6 100644 ---- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h -+++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h -@@ -56,8 +56,8 @@ private: - Value *optimizeMemSetChk(CallInst *CI, IRBuilder<> &B); - - // Str/Stp cpy are similar enough to be handled in the same functions. -- Value *optimizeStrpCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc::Func Func); -- Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc::Func Func); -+ Value *optimizeStrpCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc Func); -+ Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc Func); - - /// \brief Checks whether the call \p CI to a fortified libcall is foldable - /// to the non-fortified version. -diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp -index 43d5c3ccf90..cce9aa5c2c0 100644 ---- a/lib/Analysis/BasicAliasAnalysis.cpp -+++ b/lib/Analysis/BasicAliasAnalysis.cpp -@@ -619,9 +619,9 @@ static bool isWriteOnlyParam(ImmutableCallSite CS, unsigned ArgIdx, - // whenever possible. - // FIXME Consider handling this in InferFunctionAttr.cpp together with other - // attributes. -- LibFunc::Func F; -+ LibFunc F; - if (CS.getCalledFunction() && TLI.getLibFunc(*CS.getCalledFunction(), F) && -- F == LibFunc::memset_pattern16 && TLI.has(F)) -+ F == LibFunc_memset_pattern16 && TLI.has(F)) - if (ArgIdx == 0) - return true; - -diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp -index c9adaa7b111..9672dcfdf97 100644 ---- a/lib/Analysis/ConstantFolding.cpp -+++ b/lib/Analysis/ConstantFolding.cpp -@@ -1554,51 +1554,51 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty, - - switch (Name[0]) { - case 'a': -- if ((Name == "acos" && TLI->has(LibFunc::acos)) || -- (Name == "acosf" && TLI->has(LibFunc::acosf))) -+ if ((Name == "acos" && TLI->has(LibFunc_acos)) || -+ (Name == "acosf" && TLI->has(LibFunc_acosf))) - return ConstantFoldFP(acos, V, Ty); -- else if ((Name == "asin" && TLI->has(LibFunc::asin)) || -- (Name == "asinf" && TLI->has(LibFunc::asinf))) -+ else if ((Name == "asin" && TLI->has(LibFunc_asin)) || -+ (Name == "asinf" && TLI->has(LibFunc_asinf))) - return ConstantFoldFP(asin, V, Ty); -- else if ((Name == "atan" && TLI->has(LibFunc::atan)) || -- (Name == "atanf" && TLI->has(LibFunc::atanf))) -+ else if ((Name == "atan" && TLI->has(LibFunc_atan)) || -+ (Name == "atanf" && TLI->has(LibFunc_atanf))) - return ConstantFoldFP(atan, V, Ty); - break; - case 'c': -- if ((Name == "ceil" && TLI->has(LibFunc::ceil)) || -- (Name == "ceilf" && TLI->has(LibFunc::ceilf))) -+ if ((Name == "ceil" && TLI->has(LibFunc_ceil)) || -+ (Name == "ceilf" && TLI->has(LibFunc_ceilf))) - return ConstantFoldFP(ceil, V, Ty); -- else if ((Name == "cos" && TLI->has(LibFunc::cos)) || -- (Name == "cosf" && TLI->has(LibFunc::cosf))) -+ else if ((Name == "cos" && TLI->has(LibFunc_cos)) || -+ (Name == "cosf" && TLI->has(LibFunc_cosf))) - return ConstantFoldFP(cos, V, Ty); -- else if ((Name == "cosh" && TLI->has(LibFunc::cosh)) || -- (Name == "coshf" && TLI->has(LibFunc::coshf))) -+ else if ((Name == "cosh" && TLI->has(LibFunc_cosh)) || -+ (Name == "coshf" && TLI->has(LibFunc_coshf))) - return ConstantFoldFP(cosh, V, Ty); - break; - case 'e': -- if ((Name == "exp" && TLI->has(LibFunc::exp)) || -- (Name == "expf" && TLI->has(LibFunc::expf))) -+ if ((Name == "exp" && TLI->has(LibFunc_exp)) || -+ (Name == "expf" && TLI->has(LibFunc_expf))) - return ConstantFoldFP(exp, V, Ty); -- if ((Name == "exp2" && TLI->has(LibFunc::exp2)) || -- (Name == "exp2f" && TLI->has(LibFunc::exp2f))) -+ if ((Name == "exp2" && TLI->has(LibFunc_exp2)) || -+ (Name == "exp2f" && TLI->has(LibFunc_exp2f))) - // Constant fold exp2(x) as pow(2,x) in case the host doesn't have a - // C99 library. - return ConstantFoldBinaryFP(pow, 2.0, V, Ty); - break; - case 'f': -- if ((Name == "fabs" && TLI->has(LibFunc::fabs)) || -- (Name == "fabsf" && TLI->has(LibFunc::fabsf))) -+ if ((Name == "fabs" && TLI->has(LibFunc_fabs)) || -+ (Name == "fabsf" && TLI->has(LibFunc_fabsf))) - return ConstantFoldFP(fabs, V, Ty); -- else if ((Name == "floor" && TLI->has(LibFunc::floor)) || -- (Name == "floorf" && TLI->has(LibFunc::floorf))) -+ else if ((Name == "floor" && TLI->has(LibFunc_floor)) || -+ (Name == "floorf" && TLI->has(LibFunc_floorf))) - return ConstantFoldFP(floor, V, Ty); - break; - case 'l': -- if ((Name == "log" && V > 0 && TLI->has(LibFunc::log)) || -- (Name == "logf" && V > 0 && TLI->has(LibFunc::logf))) -+ if ((Name == "log" && V > 0 && TLI->has(LibFunc_log)) || -+ (Name == "logf" && V > 0 && TLI->has(LibFunc_logf))) - return ConstantFoldFP(log, V, Ty); -- else if ((Name == "log10" && V > 0 && TLI->has(LibFunc::log10)) || -- (Name == "log10f" && V > 0 && TLI->has(LibFunc::log10f))) -+ else if ((Name == "log10" && V > 0 && TLI->has(LibFunc_log10)) || -+ (Name == "log10f" && V > 0 && TLI->has(LibFunc_log10f))) - return ConstantFoldFP(log10, V, Ty); - else if (IntrinsicID == Intrinsic::sqrt && - (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy())) { -@@ -1615,22 +1615,22 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty, - } - break; - case 's': -- if ((Name == "sin" && TLI->has(LibFunc::sin)) || -- (Name == "sinf" && TLI->has(LibFunc::sinf))) -+ if ((Name == "sin" && TLI->has(LibFunc_sin)) || -+ (Name == "sinf" && TLI->has(LibFunc_sinf))) - return ConstantFoldFP(sin, V, Ty); -- else if ((Name == "sinh" && TLI->has(LibFunc::sinh)) || -- (Name == "sinhf" && TLI->has(LibFunc::sinhf))) -+ else if ((Name == "sinh" && TLI->has(LibFunc_sinh)) || -+ (Name == "sinhf" && TLI->has(LibFunc_sinhf))) - return ConstantFoldFP(sinh, V, Ty); -- else if ((Name == "sqrt" && V >= 0 && TLI->has(LibFunc::sqrt)) || -- (Name == "sqrtf" && V >= 0 && TLI->has(LibFunc::sqrtf))) -+ else if ((Name == "sqrt" && V >= 0 && TLI->has(LibFunc_sqrt)) || -+ (Name == "sqrtf" && V >= 0 && TLI->has(LibFunc_sqrtf))) - return ConstantFoldFP(sqrt, V, Ty); - break; - case 't': -- if ((Name == "tan" && TLI->has(LibFunc::tan)) || -- (Name == "tanf" && TLI->has(LibFunc::tanf))) -+ if ((Name == "tan" && TLI->has(LibFunc_tan)) || -+ (Name == "tanf" && TLI->has(LibFunc_tanf))) - return ConstantFoldFP(tan, V, Ty); -- else if ((Name == "tanh" && TLI->has(LibFunc::tanh)) || -- (Name == "tanhf" && TLI->has(LibFunc::tanhf))) -+ else if ((Name == "tanh" && TLI->has(LibFunc_tanh)) || -+ (Name == "tanhf" && TLI->has(LibFunc_tanhf))) - return ConstantFoldFP(tanh, V, Ty); - break; - default: -@@ -1735,14 +1735,14 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty, - - if (!TLI) - return nullptr; -- if ((Name == "pow" && TLI->has(LibFunc::pow)) || -- (Name == "powf" && TLI->has(LibFunc::powf))) -+ if ((Name == "pow" && TLI->has(LibFunc_pow)) || -+ (Name == "powf" && TLI->has(LibFunc_powf))) - return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty); -- if ((Name == "fmod" && TLI->has(LibFunc::fmod)) || -- (Name == "fmodf" && TLI->has(LibFunc::fmodf))) -+ if ((Name == "fmod" && TLI->has(LibFunc_fmod)) || -+ (Name == "fmodf" && TLI->has(LibFunc_fmodf))) - return ConstantFoldBinaryFP(fmod, Op1V, Op2V, Ty); -- if ((Name == "atan2" && TLI->has(LibFunc::atan2)) || -- (Name == "atan2f" && TLI->has(LibFunc::atan2f))) -+ if ((Name == "atan2" && TLI->has(LibFunc_atan2)) || -+ (Name == "atan2f" && TLI->has(LibFunc_atan2f))) - return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty); - } else if (auto *Op2C = dyn_cast(Operands[1])) { - if (IntrinsicID == Intrinsic::powi && Ty->isHalfTy()) -diff --git a/lib/Analysis/MemoryBuiltins.cpp b/lib/Analysis/MemoryBuiltins.cpp -index f23477622be..89e7a358d4b 100644 ---- a/lib/Analysis/MemoryBuiltins.cpp -+++ b/lib/Analysis/MemoryBuiltins.cpp -@@ -50,30 +50,30 @@ struct AllocFnsTy { - - // FIXME: certain users need more information. E.g., SimplifyLibCalls needs to - // know which functions are nounwind, noalias, nocapture parameters, etc. --static const std::pair AllocationFnData[] = { -- {LibFunc::malloc, {MallocLike, 1, 0, -1}}, -- {LibFunc::valloc, {MallocLike, 1, 0, -1}}, -- {LibFunc::Znwj, {OpNewLike, 1, 0, -1}}, // new(unsigned int) -- {LibFunc::ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow) -- {LibFunc::Znwm, {OpNewLike, 1, 0, -1}}, // new(unsigned long) -- {LibFunc::ZnwmRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned long, nothrow) -- {LibFunc::Znaj, {OpNewLike, 1, 0, -1}}, // new[](unsigned int) -- {LibFunc::ZnajRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow) -- {LibFunc::Znam, {OpNewLike, 1, 0, -1}}, // new[](unsigned long) -- {LibFunc::ZnamRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned long, nothrow) -- {LibFunc::msvc_new_int, {OpNewLike, 1, 0, -1}}, // new(unsigned int) -- {LibFunc::msvc_new_int_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow) -- {LibFunc::msvc_new_longlong, {OpNewLike, 1, 0, -1}}, // new(unsigned long long) -- {LibFunc::msvc_new_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned long long, nothrow) -- {LibFunc::msvc_new_array_int, {OpNewLike, 1, 0, -1}}, // new[](unsigned int) -- {LibFunc::msvc_new_array_int_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow) -- {LibFunc::msvc_new_array_longlong, {OpNewLike, 1, 0, -1}}, // new[](unsigned long long) -- {LibFunc::msvc_new_array_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned long long, nothrow) -- {LibFunc::calloc, {CallocLike, 2, 0, 1}}, -- {LibFunc::realloc, {ReallocLike, 2, 1, -1}}, -- {LibFunc::reallocf, {ReallocLike, 2, 1, -1}}, -- {LibFunc::strdup, {StrDupLike, 1, -1, -1}}, -- {LibFunc::strndup, {StrDupLike, 2, 1, -1}} -+static const std::pair AllocationFnData[] = { -+ {LibFunc_malloc, {MallocLike, 1, 0, -1}}, -+ {LibFunc_valloc, {MallocLike, 1, 0, -1}}, -+ {LibFunc_Znwj, {OpNewLike, 1, 0, -1}}, // new(unsigned int) -+ {LibFunc_ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow) -+ {LibFunc_Znwm, {OpNewLike, 1, 0, -1}}, // new(unsigned long) -+ {LibFunc_ZnwmRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned long, nothrow) -+ {LibFunc_Znaj, {OpNewLike, 1, 0, -1}}, // new[](unsigned int) -+ {LibFunc_ZnajRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow) -+ {LibFunc_Znam, {OpNewLike, 1, 0, -1}}, // new[](unsigned long) -+ {LibFunc_ZnamRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned long, nothrow) -+ {LibFunc_msvc_new_int, {OpNewLike, 1, 0, -1}}, // new(unsigned int) -+ {LibFunc_msvc_new_int_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow) -+ {LibFunc_msvc_new_longlong, {OpNewLike, 1, 0, -1}}, // new(unsigned long long) -+ {LibFunc_msvc_new_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned long long, nothrow) -+ {LibFunc_msvc_new_array_int, {OpNewLike, 1, 0, -1}}, // new[](unsigned int) -+ {LibFunc_msvc_new_array_int_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow) -+ {LibFunc_msvc_new_array_longlong, {OpNewLike, 1, 0, -1}}, // new[](unsigned long long) -+ {LibFunc_msvc_new_array_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned long long, nothrow) -+ {LibFunc_calloc, {CallocLike, 2, 0, 1}}, -+ {LibFunc_realloc, {ReallocLike, 2, 1, -1}}, -+ {LibFunc_reallocf, {ReallocLike, 2, 1, -1}}, -+ {LibFunc_strdup, {StrDupLike, 1, -1, -1}}, -+ {LibFunc_strndup, {StrDupLike, 2, 1, -1}} - // TODO: Handle "int posix_memalign(void **, size_t, size_t)" - }; - -@@ -130,13 +130,13 @@ static Optional getAllocationData(const Value *V, AllocType AllocTy, - - // Make sure that the function is available. - StringRef FnName = Callee->getName(); -- LibFunc::Func TLIFn; -+ LibFunc TLIFn; - if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn)) - return None; - - const auto *Iter = - std::find_if(std::begin(AllocationFnData), std::end(AllocationFnData), -- [TLIFn](const std::pair &P) { -+ [TLIFn](const std::pair &P) { - return P.first == TLIFn; - }); - -@@ -316,33 +316,33 @@ const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) { - return nullptr; - - StringRef FnName = Callee->getName(); -- LibFunc::Func TLIFn; -+ LibFunc TLIFn; - if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn)) - return nullptr; - - unsigned ExpectedNumParams; -- if (TLIFn == LibFunc::free || -- TLIFn == LibFunc::ZdlPv || // operator delete(void*) -- TLIFn == LibFunc::ZdaPv || // operator delete[](void*) -- TLIFn == LibFunc::msvc_delete_ptr32 || // operator delete(void*) -- TLIFn == LibFunc::msvc_delete_ptr64 || // operator delete(void*) -- TLIFn == LibFunc::msvc_delete_array_ptr32 || // operator delete[](void*) -- TLIFn == LibFunc::msvc_delete_array_ptr64) // operator delete[](void*) -+ if (TLIFn == LibFunc_free || -+ TLIFn == LibFunc_ZdlPv || // operator delete(void*) -+ TLIFn == LibFunc_ZdaPv || // operator delete[](void*) -+ TLIFn == LibFunc_msvc_delete_ptr32 || // operator delete(void*) -+ TLIFn == LibFunc_msvc_delete_ptr64 || // operator delete(void*) -+ TLIFn == LibFunc_msvc_delete_array_ptr32 || // operator delete[](void*) -+ TLIFn == LibFunc_msvc_delete_array_ptr64) // operator delete[](void*) - ExpectedNumParams = 1; -- else if (TLIFn == LibFunc::ZdlPvj || // delete(void*, uint) -- TLIFn == LibFunc::ZdlPvm || // delete(void*, ulong) -- TLIFn == LibFunc::ZdlPvRKSt9nothrow_t || // delete(void*, nothrow) -- TLIFn == LibFunc::ZdaPvj || // delete[](void*, uint) -- TLIFn == LibFunc::ZdaPvm || // delete[](void*, ulong) -- TLIFn == LibFunc::ZdaPvRKSt9nothrow_t || // delete[](void*, nothrow) -- TLIFn == LibFunc::msvc_delete_ptr32_int || // delete(void*, uint) -- TLIFn == LibFunc::msvc_delete_ptr64_longlong || // delete(void*, ulonglong) -- TLIFn == LibFunc::msvc_delete_ptr32_nothrow || // delete(void*, nothrow) -- TLIFn == LibFunc::msvc_delete_ptr64_nothrow || // delete(void*, nothrow) -- TLIFn == LibFunc::msvc_delete_array_ptr32_int || // delete[](void*, uint) -- TLIFn == LibFunc::msvc_delete_array_ptr64_longlong || // delete[](void*, ulonglong) -- TLIFn == LibFunc::msvc_delete_array_ptr32_nothrow || // delete[](void*, nothrow) -- TLIFn == LibFunc::msvc_delete_array_ptr64_nothrow) // delete[](void*, nothrow) -+ else if (TLIFn == LibFunc_ZdlPvj || // delete(void*, uint) -+ TLIFn == LibFunc_ZdlPvm || // delete(void*, ulong) -+ TLIFn == LibFunc_ZdlPvRKSt9nothrow_t || // delete(void*, nothrow) -+ TLIFn == LibFunc_ZdaPvj || // delete[](void*, uint) -+ TLIFn == LibFunc_ZdaPvm || // delete[](void*, ulong) -+ TLIFn == LibFunc_ZdaPvRKSt9nothrow_t || // delete[](void*, nothrow) -+ TLIFn == LibFunc_msvc_delete_ptr32_int || // delete(void*, uint) -+ TLIFn == LibFunc_msvc_delete_ptr64_longlong || // delete(void*, ulonglong) -+ TLIFn == LibFunc_msvc_delete_ptr32_nothrow || // delete(void*, nothrow) -+ TLIFn == LibFunc_msvc_delete_ptr64_nothrow || // delete(void*, nothrow) -+ TLIFn == LibFunc_msvc_delete_array_ptr32_int || // delete[](void*, uint) -+ TLIFn == LibFunc_msvc_delete_array_ptr64_longlong || // delete[](void*, ulonglong) -+ TLIFn == LibFunc_msvc_delete_array_ptr32_nothrow || // delete[](void*, nothrow) -+ TLIFn == LibFunc_msvc_delete_array_ptr64_nothrow) // delete[](void*, nothrow) - ExpectedNumParams = 2; - else - return nullptr; -diff --git a/lib/Analysis/MemoryLocation.cpp b/lib/Analysis/MemoryLocation.cpp -index a0ae72f1415..9db6c499129 100644 ---- a/lib/Analysis/MemoryLocation.cpp -+++ b/lib/Analysis/MemoryLocation.cpp -@@ -142,9 +142,9 @@ MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS, - // for memcpy/memset. This is particularly important because the - // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 - // whenever possible. -- LibFunc::Func F; -+ LibFunc F; - if (CS.getCalledFunction() && TLI.getLibFunc(*CS.getCalledFunction(), F) && -- F == LibFunc::memset_pattern16 && TLI.has(F)) { -+ F == LibFunc_memset_pattern16 && TLI.has(F)) { - assert((ArgIdx == 0 || ArgIdx == 1) && - "Invalid argument index for memset_pattern16"); - if (ArgIdx == 1) -diff --git a/lib/Analysis/TargetLibraryInfo.cpp b/lib/Analysis/TargetLibraryInfo.cpp -index 93d537ad3ab..0895b8a6cfa 100644 ---- a/lib/Analysis/TargetLibraryInfo.cpp -+++ b/lib/Analysis/TargetLibraryInfo.cpp -@@ -62,24 +62,24 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - - if (T.getArch() == Triple::r600 || - T.getArch() == Triple::amdgcn) { -- TLI.setUnavailable(LibFunc::ldexp); -- TLI.setUnavailable(LibFunc::ldexpf); -- TLI.setUnavailable(LibFunc::ldexpl); -- TLI.setUnavailable(LibFunc::exp10); -- TLI.setUnavailable(LibFunc::exp10f); -- TLI.setUnavailable(LibFunc::exp10l); -- TLI.setUnavailable(LibFunc::log10); -- TLI.setUnavailable(LibFunc::log10f); -- TLI.setUnavailable(LibFunc::log10l); -+ TLI.setUnavailable(LibFunc_ldexp); -+ TLI.setUnavailable(LibFunc_ldexpf); -+ TLI.setUnavailable(LibFunc_ldexpl); -+ TLI.setUnavailable(LibFunc_exp10); -+ TLI.setUnavailable(LibFunc_exp10f); -+ TLI.setUnavailable(LibFunc_exp10l); -+ TLI.setUnavailable(LibFunc_log10); -+ TLI.setUnavailable(LibFunc_log10f); -+ TLI.setUnavailable(LibFunc_log10l); - } - - // There are no library implementations of mempcy and memset for AMD gpus and - // these can be difficult to lower in the backend. - if (T.getArch() == Triple::r600 || - T.getArch() == Triple::amdgcn) { -- TLI.setUnavailable(LibFunc::memcpy); -- TLI.setUnavailable(LibFunc::memset); -- TLI.setUnavailable(LibFunc::memset_pattern16); -+ TLI.setUnavailable(LibFunc_memcpy); -+ TLI.setUnavailable(LibFunc_memset); -+ TLI.setUnavailable(LibFunc_memset_pattern16); - return; - } - -@@ -87,21 +87,21 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // All versions of watchOS support it. - if (T.isMacOSX()) { - if (T.isMacOSXVersionLT(10, 5)) -- TLI.setUnavailable(LibFunc::memset_pattern16); -+ TLI.setUnavailable(LibFunc_memset_pattern16); - } else if (T.isiOS()) { - if (T.isOSVersionLT(3, 0)) -- TLI.setUnavailable(LibFunc::memset_pattern16); -+ TLI.setUnavailable(LibFunc_memset_pattern16); - } else if (!T.isWatchOS()) { -- TLI.setUnavailable(LibFunc::memset_pattern16); -+ TLI.setUnavailable(LibFunc_memset_pattern16); - } - - if (!hasSinCosPiStret(T)) { -- TLI.setUnavailable(LibFunc::sinpi); -- TLI.setUnavailable(LibFunc::sinpif); -- TLI.setUnavailable(LibFunc::cospi); -- TLI.setUnavailable(LibFunc::cospif); -- TLI.setUnavailable(LibFunc::sincospi_stret); -- TLI.setUnavailable(LibFunc::sincospif_stret); -+ TLI.setUnavailable(LibFunc_sinpi); -+ TLI.setUnavailable(LibFunc_sinpif); -+ TLI.setUnavailable(LibFunc_cospi); -+ TLI.setUnavailable(LibFunc_cospif); -+ TLI.setUnavailable(LibFunc_sincospi_stret); -+ TLI.setUnavailable(LibFunc_sincospif_stret); - } - - if (T.isMacOSX() && T.getArch() == Triple::x86 && -@@ -111,179 +111,179 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // has a $UNIX2003 suffix. The two implementations are identical except - // for the return value in some edge cases. However, we don't want to - // generate code that depends on the old symbols. -- TLI.setAvailableWithName(LibFunc::fwrite, "fwrite$UNIX2003"); -- TLI.setAvailableWithName(LibFunc::fputs, "fputs$UNIX2003"); -+ TLI.setAvailableWithName(LibFunc_fwrite, "fwrite$UNIX2003"); -+ TLI.setAvailableWithName(LibFunc_fputs, "fputs$UNIX2003"); - } - - // iprintf and friends are only available on XCore and TCE. - if (T.getArch() != Triple::xcore && T.getArch() != Triple::tce) { -- TLI.setUnavailable(LibFunc::iprintf); -- TLI.setUnavailable(LibFunc::siprintf); -- TLI.setUnavailable(LibFunc::fiprintf); -+ TLI.setUnavailable(LibFunc_iprintf); -+ TLI.setUnavailable(LibFunc_siprintf); -+ TLI.setUnavailable(LibFunc_fiprintf); - } - - if (T.isOSWindows() && !T.isOSCygMing()) { - // Win32 does not support long double -- TLI.setUnavailable(LibFunc::acosl); -- TLI.setUnavailable(LibFunc::asinl); -- TLI.setUnavailable(LibFunc::atanl); -- TLI.setUnavailable(LibFunc::atan2l); -- TLI.setUnavailable(LibFunc::ceill); -- TLI.setUnavailable(LibFunc::copysignl); -- TLI.setUnavailable(LibFunc::cosl); -- TLI.setUnavailable(LibFunc::coshl); -- TLI.setUnavailable(LibFunc::expl); -- TLI.setUnavailable(LibFunc::fabsf); // Win32 and Win64 both lack fabsf -- TLI.setUnavailable(LibFunc::fabsl); -- TLI.setUnavailable(LibFunc::floorl); -- TLI.setUnavailable(LibFunc::fmaxl); -- TLI.setUnavailable(LibFunc::fminl); -- TLI.setUnavailable(LibFunc::fmodl); -- TLI.setUnavailable(LibFunc::frexpl); -- TLI.setUnavailable(LibFunc::ldexpf); -- TLI.setUnavailable(LibFunc::ldexpl); -- TLI.setUnavailable(LibFunc::logl); -- TLI.setUnavailable(LibFunc::modfl); -- TLI.setUnavailable(LibFunc::powl); -- TLI.setUnavailable(LibFunc::sinl); -- TLI.setUnavailable(LibFunc::sinhl); -- TLI.setUnavailable(LibFunc::sqrtl); -- TLI.setUnavailable(LibFunc::tanl); -- TLI.setUnavailable(LibFunc::tanhl); -+ TLI.setUnavailable(LibFunc_acosl); -+ TLI.setUnavailable(LibFunc_asinl); -+ TLI.setUnavailable(LibFunc_atanl); -+ TLI.setUnavailable(LibFunc_atan2l); -+ TLI.setUnavailable(LibFunc_ceill); -+ TLI.setUnavailable(LibFunc_copysignl); -+ TLI.setUnavailable(LibFunc_cosl); -+ TLI.setUnavailable(LibFunc_coshl); -+ TLI.setUnavailable(LibFunc_expl); -+ TLI.setUnavailable(LibFunc_fabsf); // Win32 and Win64 both lack fabsf -+ TLI.setUnavailable(LibFunc_fabsl); -+ TLI.setUnavailable(LibFunc_floorl); -+ TLI.setUnavailable(LibFunc_fmaxl); -+ TLI.setUnavailable(LibFunc_fminl); -+ TLI.setUnavailable(LibFunc_fmodl); -+ TLI.setUnavailable(LibFunc_frexpl); -+ TLI.setUnavailable(LibFunc_ldexpf); -+ TLI.setUnavailable(LibFunc_ldexpl); -+ TLI.setUnavailable(LibFunc_logl); -+ TLI.setUnavailable(LibFunc_modfl); -+ TLI.setUnavailable(LibFunc_powl); -+ TLI.setUnavailable(LibFunc_sinl); -+ TLI.setUnavailable(LibFunc_sinhl); -+ TLI.setUnavailable(LibFunc_sqrtl); -+ TLI.setUnavailable(LibFunc_tanl); -+ TLI.setUnavailable(LibFunc_tanhl); - - // Win32 only has C89 math -- TLI.setUnavailable(LibFunc::acosh); -- TLI.setUnavailable(LibFunc::acoshf); -- TLI.setUnavailable(LibFunc::acoshl); -- TLI.setUnavailable(LibFunc::asinh); -- TLI.setUnavailable(LibFunc::asinhf); -- TLI.setUnavailable(LibFunc::asinhl); -- TLI.setUnavailable(LibFunc::atanh); -- TLI.setUnavailable(LibFunc::atanhf); -- TLI.setUnavailable(LibFunc::atanhl); -- TLI.setUnavailable(LibFunc::cbrt); -- TLI.setUnavailable(LibFunc::cbrtf); -- TLI.setUnavailable(LibFunc::cbrtl); -- TLI.setUnavailable(LibFunc::exp2); -- TLI.setUnavailable(LibFunc::exp2f); -- TLI.setUnavailable(LibFunc::exp2l); -- TLI.setUnavailable(LibFunc::expm1); -- TLI.setUnavailable(LibFunc::expm1f); -- TLI.setUnavailable(LibFunc::expm1l); -- TLI.setUnavailable(LibFunc::log2); -- TLI.setUnavailable(LibFunc::log2f); -- TLI.setUnavailable(LibFunc::log2l); -- TLI.setUnavailable(LibFunc::log1p); -- TLI.setUnavailable(LibFunc::log1pf); -- TLI.setUnavailable(LibFunc::log1pl); -- TLI.setUnavailable(LibFunc::logb); -- TLI.setUnavailable(LibFunc::logbf); -- TLI.setUnavailable(LibFunc::logbl); -- TLI.setUnavailable(LibFunc::nearbyint); -- TLI.setUnavailable(LibFunc::nearbyintf); -- TLI.setUnavailable(LibFunc::nearbyintl); -- TLI.setUnavailable(LibFunc::rint); -- TLI.setUnavailable(LibFunc::rintf); -- TLI.setUnavailable(LibFunc::rintl); -- TLI.setUnavailable(LibFunc::round); -- TLI.setUnavailable(LibFunc::roundf); -- TLI.setUnavailable(LibFunc::roundl); -- TLI.setUnavailable(LibFunc::trunc); -- TLI.setUnavailable(LibFunc::truncf); -- TLI.setUnavailable(LibFunc::truncl); -+ TLI.setUnavailable(LibFunc_acosh); -+ TLI.setUnavailable(LibFunc_acoshf); -+ TLI.setUnavailable(LibFunc_acoshl); -+ TLI.setUnavailable(LibFunc_asinh); -+ TLI.setUnavailable(LibFunc_asinhf); -+ TLI.setUnavailable(LibFunc_asinhl); -+ TLI.setUnavailable(LibFunc_atanh); -+ TLI.setUnavailable(LibFunc_atanhf); -+ TLI.setUnavailable(LibFunc_atanhl); -+ TLI.setUnavailable(LibFunc_cbrt); -+ TLI.setUnavailable(LibFunc_cbrtf); -+ TLI.setUnavailable(LibFunc_cbrtl); -+ TLI.setUnavailable(LibFunc_exp2); -+ TLI.setUnavailable(LibFunc_exp2f); -+ TLI.setUnavailable(LibFunc_exp2l); -+ TLI.setUnavailable(LibFunc_expm1); -+ TLI.setUnavailable(LibFunc_expm1f); -+ TLI.setUnavailable(LibFunc_expm1l); -+ TLI.setUnavailable(LibFunc_log2); -+ TLI.setUnavailable(LibFunc_log2f); -+ TLI.setUnavailable(LibFunc_log2l); -+ TLI.setUnavailable(LibFunc_log1p); -+ TLI.setUnavailable(LibFunc_log1pf); -+ TLI.setUnavailable(LibFunc_log1pl); -+ TLI.setUnavailable(LibFunc_logb); -+ TLI.setUnavailable(LibFunc_logbf); -+ TLI.setUnavailable(LibFunc_logbl); -+ TLI.setUnavailable(LibFunc_nearbyint); -+ TLI.setUnavailable(LibFunc_nearbyintf); -+ TLI.setUnavailable(LibFunc_nearbyintl); -+ TLI.setUnavailable(LibFunc_rint); -+ TLI.setUnavailable(LibFunc_rintf); -+ TLI.setUnavailable(LibFunc_rintl); -+ TLI.setUnavailable(LibFunc_round); -+ TLI.setUnavailable(LibFunc_roundf); -+ TLI.setUnavailable(LibFunc_roundl); -+ TLI.setUnavailable(LibFunc_trunc); -+ TLI.setUnavailable(LibFunc_truncf); -+ TLI.setUnavailable(LibFunc_truncl); - - // Win32 provides some C99 math with mangled names -- TLI.setAvailableWithName(LibFunc::copysign, "_copysign"); -+ TLI.setAvailableWithName(LibFunc_copysign, "_copysign"); - - if (T.getArch() == Triple::x86) { - // Win32 on x86 implements single-precision math functions as macros -- TLI.setUnavailable(LibFunc::acosf); -- TLI.setUnavailable(LibFunc::asinf); -- TLI.setUnavailable(LibFunc::atanf); -- TLI.setUnavailable(LibFunc::atan2f); -- TLI.setUnavailable(LibFunc::ceilf); -- TLI.setUnavailable(LibFunc::copysignf); -- TLI.setUnavailable(LibFunc::cosf); -- TLI.setUnavailable(LibFunc::coshf); -- TLI.setUnavailable(LibFunc::expf); -- TLI.setUnavailable(LibFunc::floorf); -- TLI.setUnavailable(LibFunc::fminf); -- TLI.setUnavailable(LibFunc::fmaxf); -- TLI.setUnavailable(LibFunc::fmodf); -- TLI.setUnavailable(LibFunc::logf); -- TLI.setUnavailable(LibFunc::log10f); -- TLI.setUnavailable(LibFunc::modff); -- TLI.setUnavailable(LibFunc::powf); -- TLI.setUnavailable(LibFunc::sinf); -- TLI.setUnavailable(LibFunc::sinhf); -- TLI.setUnavailable(LibFunc::sqrtf); -- TLI.setUnavailable(LibFunc::tanf); -- TLI.setUnavailable(LibFunc::tanhf); -+ TLI.setUnavailable(LibFunc_acosf); -+ TLI.setUnavailable(LibFunc_asinf); -+ TLI.setUnavailable(LibFunc_atanf); -+ TLI.setUnavailable(LibFunc_atan2f); -+ TLI.setUnavailable(LibFunc_ceilf); -+ TLI.setUnavailable(LibFunc_copysignf); -+ TLI.setUnavailable(LibFunc_cosf); -+ TLI.setUnavailable(LibFunc_coshf); -+ TLI.setUnavailable(LibFunc_expf); -+ TLI.setUnavailable(LibFunc_floorf); -+ TLI.setUnavailable(LibFunc_fminf); -+ TLI.setUnavailable(LibFunc_fmaxf); -+ TLI.setUnavailable(LibFunc_fmodf); -+ TLI.setUnavailable(LibFunc_logf); -+ TLI.setUnavailable(LibFunc_log10f); -+ TLI.setUnavailable(LibFunc_modff); -+ TLI.setUnavailable(LibFunc_powf); -+ TLI.setUnavailable(LibFunc_sinf); -+ TLI.setUnavailable(LibFunc_sinhf); -+ TLI.setUnavailable(LibFunc_sqrtf); -+ TLI.setUnavailable(LibFunc_tanf); -+ TLI.setUnavailable(LibFunc_tanhf); - } - - // Win32 does *not* provide provide these functions, but they are - // generally available on POSIX-compliant systems: -- TLI.setUnavailable(LibFunc::access); -- TLI.setUnavailable(LibFunc::bcmp); -- TLI.setUnavailable(LibFunc::bcopy); -- TLI.setUnavailable(LibFunc::bzero); -- TLI.setUnavailable(LibFunc::chmod); -- TLI.setUnavailable(LibFunc::chown); -- TLI.setUnavailable(LibFunc::closedir); -- TLI.setUnavailable(LibFunc::ctermid); -- TLI.setUnavailable(LibFunc::fdopen); -- TLI.setUnavailable(LibFunc::ffs); -- TLI.setUnavailable(LibFunc::fileno); -- TLI.setUnavailable(LibFunc::flockfile); -- TLI.setUnavailable(LibFunc::fseeko); -- TLI.setUnavailable(LibFunc::fstat); -- TLI.setUnavailable(LibFunc::fstatvfs); -- TLI.setUnavailable(LibFunc::ftello); -- TLI.setUnavailable(LibFunc::ftrylockfile); -- TLI.setUnavailable(LibFunc::funlockfile); -- TLI.setUnavailable(LibFunc::getc_unlocked); -- TLI.setUnavailable(LibFunc::getitimer); -- TLI.setUnavailable(LibFunc::getlogin_r); -- TLI.setUnavailable(LibFunc::getpwnam); -- TLI.setUnavailable(LibFunc::gettimeofday); -- TLI.setUnavailable(LibFunc::htonl); -- TLI.setUnavailable(LibFunc::htons); -- TLI.setUnavailable(LibFunc::lchown); -- TLI.setUnavailable(LibFunc::lstat); -- TLI.setUnavailable(LibFunc::memccpy); -- TLI.setUnavailable(LibFunc::mkdir); -- TLI.setUnavailable(LibFunc::ntohl); -- TLI.setUnavailable(LibFunc::ntohs); -- TLI.setUnavailable(LibFunc::open); -- TLI.setUnavailable(LibFunc::opendir); -- TLI.setUnavailable(LibFunc::pclose); -- TLI.setUnavailable(LibFunc::popen); -- TLI.setUnavailable(LibFunc::pread); -- TLI.setUnavailable(LibFunc::pwrite); -- TLI.setUnavailable(LibFunc::read); -- TLI.setUnavailable(LibFunc::readlink); -- TLI.setUnavailable(LibFunc::realpath); -- TLI.setUnavailable(LibFunc::rmdir); -- TLI.setUnavailable(LibFunc::setitimer); -- TLI.setUnavailable(LibFunc::stat); -- TLI.setUnavailable(LibFunc::statvfs); -- TLI.setUnavailable(LibFunc::stpcpy); -- TLI.setUnavailable(LibFunc::stpncpy); -- TLI.setUnavailable(LibFunc::strcasecmp); -- TLI.setUnavailable(LibFunc::strncasecmp); -- TLI.setUnavailable(LibFunc::times); -- TLI.setUnavailable(LibFunc::uname); -- TLI.setUnavailable(LibFunc::unlink); -- TLI.setUnavailable(LibFunc::unsetenv); -- TLI.setUnavailable(LibFunc::utime); -- TLI.setUnavailable(LibFunc::utimes); -- TLI.setUnavailable(LibFunc::write); -+ TLI.setUnavailable(LibFunc_access); -+ TLI.setUnavailable(LibFunc_bcmp); -+ TLI.setUnavailable(LibFunc_bcopy); -+ TLI.setUnavailable(LibFunc_bzero); -+ TLI.setUnavailable(LibFunc_chmod); -+ TLI.setUnavailable(LibFunc_chown); -+ TLI.setUnavailable(LibFunc_closedir); -+ TLI.setUnavailable(LibFunc_ctermid); -+ TLI.setUnavailable(LibFunc_fdopen); -+ TLI.setUnavailable(LibFunc_ffs); -+ TLI.setUnavailable(LibFunc_fileno); -+ TLI.setUnavailable(LibFunc_flockfile); -+ TLI.setUnavailable(LibFunc_fseeko); -+ TLI.setUnavailable(LibFunc_fstat); -+ TLI.setUnavailable(LibFunc_fstatvfs); -+ TLI.setUnavailable(LibFunc_ftello); -+ TLI.setUnavailable(LibFunc_ftrylockfile); -+ TLI.setUnavailable(LibFunc_funlockfile); -+ TLI.setUnavailable(LibFunc_getc_unlocked); -+ TLI.setUnavailable(LibFunc_getitimer); -+ TLI.setUnavailable(LibFunc_getlogin_r); -+ TLI.setUnavailable(LibFunc_getpwnam); -+ TLI.setUnavailable(LibFunc_gettimeofday); -+ TLI.setUnavailable(LibFunc_htonl); -+ TLI.setUnavailable(LibFunc_htons); -+ TLI.setUnavailable(LibFunc_lchown); -+ TLI.setUnavailable(LibFunc_lstat); -+ TLI.setUnavailable(LibFunc_memccpy); -+ TLI.setUnavailable(LibFunc_mkdir); -+ TLI.setUnavailable(LibFunc_ntohl); -+ TLI.setUnavailable(LibFunc_ntohs); -+ TLI.setUnavailable(LibFunc_open); -+ TLI.setUnavailable(LibFunc_opendir); -+ TLI.setUnavailable(LibFunc_pclose); -+ TLI.setUnavailable(LibFunc_popen); -+ TLI.setUnavailable(LibFunc_pread); -+ TLI.setUnavailable(LibFunc_pwrite); -+ TLI.setUnavailable(LibFunc_read); -+ TLI.setUnavailable(LibFunc_readlink); -+ TLI.setUnavailable(LibFunc_realpath); -+ TLI.setUnavailable(LibFunc_rmdir); -+ TLI.setUnavailable(LibFunc_setitimer); -+ TLI.setUnavailable(LibFunc_stat); -+ TLI.setUnavailable(LibFunc_statvfs); -+ TLI.setUnavailable(LibFunc_stpcpy); -+ TLI.setUnavailable(LibFunc_stpncpy); -+ TLI.setUnavailable(LibFunc_strcasecmp); -+ TLI.setUnavailable(LibFunc_strncasecmp); -+ TLI.setUnavailable(LibFunc_times); -+ TLI.setUnavailable(LibFunc_uname); -+ TLI.setUnavailable(LibFunc_unlink); -+ TLI.setUnavailable(LibFunc_unsetenv); -+ TLI.setUnavailable(LibFunc_utime); -+ TLI.setUnavailable(LibFunc_utimes); -+ TLI.setUnavailable(LibFunc_write); - - // Win32 does *not* provide provide these functions, but they are - // specified by C99: -- TLI.setUnavailable(LibFunc::atoll); -- TLI.setUnavailable(LibFunc::frexpf); -- TLI.setUnavailable(LibFunc::llabs); -+ TLI.setUnavailable(LibFunc_atoll); -+ TLI.setUnavailable(LibFunc_frexpf); -+ TLI.setUnavailable(LibFunc_llabs); - } - - switch (T.getOS()) { -@@ -291,28 +291,28 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // exp10 and exp10f are not available on OS X until 10.9 and iOS until 7.0 - // and their names are __exp10 and __exp10f. exp10l is not available on - // OS X or iOS. -- TLI.setUnavailable(LibFunc::exp10l); -+ TLI.setUnavailable(LibFunc_exp10l); - if (T.isMacOSXVersionLT(10, 9)) { -- TLI.setUnavailable(LibFunc::exp10); -- TLI.setUnavailable(LibFunc::exp10f); -+ TLI.setUnavailable(LibFunc_exp10); -+ TLI.setUnavailable(LibFunc_exp10f); - } else { -- TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); -- TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); -+ TLI.setAvailableWithName(LibFunc_exp10, "__exp10"); -+ TLI.setAvailableWithName(LibFunc_exp10f, "__exp10f"); - } - break; - case Triple::IOS: - case Triple::TvOS: - case Triple::WatchOS: -- TLI.setUnavailable(LibFunc::exp10l); -+ TLI.setUnavailable(LibFunc_exp10l); - if (!T.isWatchOS() && (T.isOSVersionLT(7, 0) || - (T.isOSVersionLT(9, 0) && - (T.getArch() == Triple::x86 || - T.getArch() == Triple::x86_64)))) { -- TLI.setUnavailable(LibFunc::exp10); -- TLI.setUnavailable(LibFunc::exp10f); -+ TLI.setUnavailable(LibFunc_exp10); -+ TLI.setUnavailable(LibFunc_exp10f); - } else { -- TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); -- TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); -+ TLI.setAvailableWithName(LibFunc_exp10, "__exp10"); -+ TLI.setAvailableWithName(LibFunc_exp10f, "__exp10f"); - } - break; - case Triple::Linux: -@@ -323,9 +323,9 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // - // Fall through to disable all of them. - default: -- TLI.setUnavailable(LibFunc::exp10); -- TLI.setUnavailable(LibFunc::exp10f); -- TLI.setUnavailable(LibFunc::exp10l); -+ TLI.setUnavailable(LibFunc_exp10); -+ TLI.setUnavailable(LibFunc_exp10f); -+ TLI.setUnavailable(LibFunc_exp10l); - } - - // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and -@@ -343,7 +343,7 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - case Triple::Linux: - break; - default: -- TLI.setUnavailable(LibFunc::ffsl); -+ TLI.setUnavailable(LibFunc_ffsl); - } - - // ffsll is available on at least FreeBSD and Linux (GLIBC): -@@ -359,7 +359,7 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - case Triple::Linux: - break; - default: -- TLI.setUnavailable(LibFunc::ffsll); -+ TLI.setUnavailable(LibFunc_ffsll); - } - - // The following functions are available on at least FreeBSD: -@@ -367,30 +367,30 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // http://svn.freebsd.org/base/head/lib/libc/string/flsl.c - // http://svn.freebsd.org/base/head/lib/libc/string/flsll.c - if (!T.isOSFreeBSD()) { -- TLI.setUnavailable(LibFunc::fls); -- TLI.setUnavailable(LibFunc::flsl); -- TLI.setUnavailable(LibFunc::flsll); -+ TLI.setUnavailable(LibFunc_fls); -+ TLI.setUnavailable(LibFunc_flsl); -+ TLI.setUnavailable(LibFunc_flsll); - } - - // The following functions are available on at least Linux: - if (!T.isOSLinux()) { -- TLI.setUnavailable(LibFunc::dunder_strdup); -- TLI.setUnavailable(LibFunc::dunder_strtok_r); -- TLI.setUnavailable(LibFunc::dunder_isoc99_scanf); -- TLI.setUnavailable(LibFunc::dunder_isoc99_sscanf); -- TLI.setUnavailable(LibFunc::under_IO_getc); -- TLI.setUnavailable(LibFunc::under_IO_putc); -- TLI.setUnavailable(LibFunc::memalign); -- TLI.setUnavailable(LibFunc::fopen64); -- TLI.setUnavailable(LibFunc::fseeko64); -- TLI.setUnavailable(LibFunc::fstat64); -- TLI.setUnavailable(LibFunc::fstatvfs64); -- TLI.setUnavailable(LibFunc::ftello64); -- TLI.setUnavailable(LibFunc::lstat64); -- TLI.setUnavailable(LibFunc::open64); -- TLI.setUnavailable(LibFunc::stat64); -- TLI.setUnavailable(LibFunc::statvfs64); -- TLI.setUnavailable(LibFunc::tmpfile64); -+ TLI.setUnavailable(LibFunc_dunder_strdup); -+ TLI.setUnavailable(LibFunc_dunder_strtok_r); -+ TLI.setUnavailable(LibFunc_dunder_isoc99_scanf); -+ TLI.setUnavailable(LibFunc_dunder_isoc99_sscanf); -+ TLI.setUnavailable(LibFunc_under_IO_getc); -+ TLI.setUnavailable(LibFunc_under_IO_putc); -+ TLI.setUnavailable(LibFunc_memalign); -+ TLI.setUnavailable(LibFunc_fopen64); -+ TLI.setUnavailable(LibFunc_fseeko64); -+ TLI.setUnavailable(LibFunc_fstat64); -+ TLI.setUnavailable(LibFunc_fstatvfs64); -+ TLI.setUnavailable(LibFunc_ftello64); -+ TLI.setUnavailable(LibFunc_lstat64); -+ TLI.setUnavailable(LibFunc_open64); -+ TLI.setUnavailable(LibFunc_stat64); -+ TLI.setUnavailable(LibFunc_statvfs64); -+ TLI.setUnavailable(LibFunc_tmpfile64); - } - - // As currently implemented in clang, NVPTX code has no standard library to -@@ -406,9 +406,9 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // optimizations, so this situation should be fixed. - if (T.isNVPTX()) { - TLI.disableAllFunctions(); -- TLI.setAvailable(LibFunc::nvvm_reflect); -+ TLI.setAvailable(LibFunc_nvvm_reflect); - } else { -- TLI.setUnavailable(LibFunc::nvvm_reflect); -+ TLI.setUnavailable(LibFunc_nvvm_reflect); - } - - TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary); -@@ -468,9 +468,9 @@ static StringRef sanitizeFunctionName(StringRef funcName) { - } - - bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, -- LibFunc::Func &F) const { -+ LibFunc &F) const { - const char *const *Start = &StandardNames[0]; -- const char *const *End = &StandardNames[LibFunc::NumLibFuncs]; -+ const char *const *End = &StandardNames[NumLibFuncs]; - - funcName = sanitizeFunctionName(funcName); - if (funcName.empty()) -@@ -481,14 +481,14 @@ bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, - return std::strncmp(LHS, RHS.data(), RHS.size()) < 0; - }); - if (I != End && *I == funcName) { -- F = (LibFunc::Func)(I - Start); -+ F = (LibFunc)(I - Start); - return true; - } - return false; - } - - bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, -- LibFunc::Func F, -+ LibFunc F, - const DataLayout *DL) const { - LLVMContext &Ctx = FTy.getContext(); - Type *PCharTy = Type::getInt8PtrTy(Ctx); -@@ -499,488 +499,488 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, - unsigned NumParams = FTy.getNumParams(); - - switch (F) { -- case LibFunc::strlen: -+ case LibFunc_strlen: - return (NumParams == 1 && FTy.getParamType(0)->isPointerTy() && - FTy.getReturnType()->isIntegerTy()); - -- case LibFunc::strchr: -- case LibFunc::strrchr: -+ case LibFunc_strchr: -+ case LibFunc_strrchr: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0) == FTy.getReturnType() && - FTy.getParamType(1)->isIntegerTy()); - -- case LibFunc::strtol: -- case LibFunc::strtod: -- case LibFunc::strtof: -- case LibFunc::strtoul: -- case LibFunc::strtoll: -- case LibFunc::strtold: -- case LibFunc::strtoull: -+ case LibFunc_strtol: -+ case LibFunc_strtod: -+ case LibFunc_strtof: -+ case LibFunc_strtoul: -+ case LibFunc_strtoll: -+ case LibFunc_strtold: -+ case LibFunc_strtoull: - return ((NumParams == 2 || NumParams == 3) && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::strcat: -+ case LibFunc_strcat: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0) == FTy.getReturnType() && - FTy.getParamType(1) == FTy.getReturnType()); - -- case LibFunc::strncat: -+ case LibFunc_strncat: - return (NumParams == 3 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0) == FTy.getReturnType() && - FTy.getParamType(1) == FTy.getReturnType() && - FTy.getParamType(2)->isIntegerTy()); - -- case LibFunc::strcpy_chk: -- case LibFunc::stpcpy_chk: -+ case LibFunc_strcpy_chk: -+ case LibFunc_stpcpy_chk: - --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) - return false; - // fallthrough -- case LibFunc::strcpy: -- case LibFunc::stpcpy: -+ case LibFunc_strcpy: -+ case LibFunc_stpcpy: - return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(0) && - FTy.getParamType(0) == FTy.getParamType(1) && - FTy.getParamType(0) == PCharTy); - -- case LibFunc::strncpy_chk: -- case LibFunc::stpncpy_chk: -+ case LibFunc_strncpy_chk: -+ case LibFunc_stpncpy_chk: - --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) - return false; - // fallthrough -- case LibFunc::strncpy: -- case LibFunc::stpncpy: -+ case LibFunc_strncpy: -+ case LibFunc_stpncpy: - return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && - FTy.getParamType(0) == FTy.getParamType(1) && - FTy.getParamType(0) == PCharTy && - FTy.getParamType(2)->isIntegerTy()); - -- case LibFunc::strxfrm: -+ case LibFunc_strxfrm: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); - -- case LibFunc::strcmp: -+ case LibFunc_strcmp: - return (NumParams == 2 && FTy.getReturnType()->isIntegerTy(32) && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(0) == FTy.getParamType(1)); - -- case LibFunc::strncmp: -+ case LibFunc_strncmp: - return (NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(0) == FTy.getParamType(1) && - FTy.getParamType(2)->isIntegerTy()); - -- case LibFunc::strspn: -- case LibFunc::strcspn: -+ case LibFunc_strspn: -+ case LibFunc_strcspn: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(0) == FTy.getParamType(1) && - FTy.getReturnType()->isIntegerTy()); - -- case LibFunc::strcoll: -- case LibFunc::strcasecmp: -- case LibFunc::strncasecmp: -+ case LibFunc_strcoll: -+ case LibFunc_strcasecmp: -+ case LibFunc_strncasecmp: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); - -- case LibFunc::strstr: -+ case LibFunc_strstr: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); - -- case LibFunc::strpbrk: -+ case LibFunc_strpbrk: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getReturnType() == FTy.getParamType(0) && - FTy.getParamType(0) == FTy.getParamType(1)); - -- case LibFunc::strtok: -- case LibFunc::strtok_r: -+ case LibFunc_strtok: -+ case LibFunc_strtok_r: - return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::scanf: -- case LibFunc::setbuf: -- case LibFunc::setvbuf: -+ case LibFunc_scanf: -+ case LibFunc_setbuf: -+ case LibFunc_setvbuf: - return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::strdup: -- case LibFunc::strndup: -+ case LibFunc_strdup: -+ case LibFunc_strndup: - return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy()); -- case LibFunc::sscanf: -- case LibFunc::stat: -- case LibFunc::statvfs: -- case LibFunc::sprintf: -+ case LibFunc_sscanf: -+ case LibFunc_stat: -+ case LibFunc_statvfs: -+ case LibFunc_sprintf: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::snprintf: -+ case LibFunc_snprintf: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::setitimer: -+ case LibFunc_setitimer: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::system: -+ case LibFunc_system: - return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::malloc: -+ case LibFunc_malloc: - return (NumParams == 1 && FTy.getReturnType()->isPointerTy()); -- case LibFunc::memcmp: -+ case LibFunc_memcmp: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy() && - FTy.getReturnType()->isIntegerTy(32)); - -- case LibFunc::memchr: -- case LibFunc::memrchr: -+ case LibFunc_memchr: -+ case LibFunc_memrchr: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isIntegerTy(32) && - FTy.getParamType(2)->isIntegerTy() && - FTy.getReturnType()->isPointerTy()); -- case LibFunc::modf: -- case LibFunc::modff: -- case LibFunc::modfl: -+ case LibFunc_modf: -+ case LibFunc_modff: -+ case LibFunc_modfl: - return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); - -- case LibFunc::memcpy_chk: -- case LibFunc::memmove_chk: -+ case LibFunc_memcpy_chk: -+ case LibFunc_memmove_chk: - --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) - return false; - // fallthrough -- case LibFunc::memcpy: -- case LibFunc::memmove: -+ case LibFunc_memcpy: -+ case LibFunc_memmove: - return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy() && - IsSizeTTy(FTy.getParamType(2))); - -- case LibFunc::memset_chk: -+ case LibFunc_memset_chk: - --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) - return false; - // fallthrough -- case LibFunc::memset: -+ case LibFunc_memset: - return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isIntegerTy() && - IsSizeTTy(FTy.getParamType(2))); - -- case LibFunc::memccpy: -+ case LibFunc_memccpy: - return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::memalign: -+ case LibFunc_memalign: - return (FTy.getReturnType()->isPointerTy()); -- case LibFunc::realloc: -+ case LibFunc_realloc: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getReturnType()->isPointerTy()); -- case LibFunc::read: -+ case LibFunc_read: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::rewind: -- case LibFunc::rmdir: -- case LibFunc::remove: -- case LibFunc::realpath: -+ case LibFunc_rewind: -+ case LibFunc_rmdir: -+ case LibFunc_remove: -+ case LibFunc_realpath: - return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::rename: -+ case LibFunc_rename: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::readlink: -+ case LibFunc_readlink: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::write: -+ case LibFunc_write: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::bcopy: -- case LibFunc::bcmp: -+ case LibFunc_bcopy: -+ case LibFunc_bcmp: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::bzero: -+ case LibFunc_bzero: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::calloc: -+ case LibFunc_calloc: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy()); - -- case LibFunc::atof: -- case LibFunc::atoi: -- case LibFunc::atol: -- case LibFunc::atoll: -- case LibFunc::ferror: -- case LibFunc::getenv: -- case LibFunc::getpwnam: -- case LibFunc::pclose: -- case LibFunc::perror: -- case LibFunc::printf: -- case LibFunc::puts: -- case LibFunc::uname: -- case LibFunc::under_IO_getc: -- case LibFunc::unlink: -- case LibFunc::unsetenv: -+ case LibFunc_atof: -+ case LibFunc_atoi: -+ case LibFunc_atol: -+ case LibFunc_atoll: -+ case LibFunc_ferror: -+ case LibFunc_getenv: -+ case LibFunc_getpwnam: -+ case LibFunc_pclose: -+ case LibFunc_perror: -+ case LibFunc_printf: -+ case LibFunc_puts: -+ case LibFunc_uname: -+ case LibFunc_under_IO_getc: -+ case LibFunc_unlink: -+ case LibFunc_unsetenv: - return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); - -- case LibFunc::chmod: -- case LibFunc::chown: -- case LibFunc::clearerr: -- case LibFunc::closedir: -- case LibFunc::ctermid: -- case LibFunc::fclose: -- case LibFunc::feof: -- case LibFunc::fflush: -- case LibFunc::fgetc: -- case LibFunc::fileno: -- case LibFunc::flockfile: -- case LibFunc::free: -- case LibFunc::fseek: -- case LibFunc::fseeko64: -- case LibFunc::fseeko: -- case LibFunc::fsetpos: -- case LibFunc::ftell: -- case LibFunc::ftello64: -- case LibFunc::ftello: -- case LibFunc::ftrylockfile: -- case LibFunc::funlockfile: -- case LibFunc::getc: -- case LibFunc::getc_unlocked: -- case LibFunc::getlogin_r: -- case LibFunc::mkdir: -- case LibFunc::mktime: -- case LibFunc::times: -+ case LibFunc_chmod: -+ case LibFunc_chown: -+ case LibFunc_clearerr: -+ case LibFunc_closedir: -+ case LibFunc_ctermid: -+ case LibFunc_fclose: -+ case LibFunc_feof: -+ case LibFunc_fflush: -+ case LibFunc_fgetc: -+ case LibFunc_fileno: -+ case LibFunc_flockfile: -+ case LibFunc_free: -+ case LibFunc_fseek: -+ case LibFunc_fseeko64: -+ case LibFunc_fseeko: -+ case LibFunc_fsetpos: -+ case LibFunc_ftell: -+ case LibFunc_ftello64: -+ case LibFunc_ftello: -+ case LibFunc_ftrylockfile: -+ case LibFunc_funlockfile: -+ case LibFunc_getc: -+ case LibFunc_getc_unlocked: -+ case LibFunc_getlogin_r: -+ case LibFunc_mkdir: -+ case LibFunc_mktime: -+ case LibFunc_times: - return (NumParams != 0 && FTy.getParamType(0)->isPointerTy()); - -- case LibFunc::access: -+ case LibFunc_access: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::fopen: -+ case LibFunc_fopen: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fdopen: -+ case LibFunc_fdopen: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fputc: -- case LibFunc::fstat: -- case LibFunc::frexp: -- case LibFunc::frexpf: -- case LibFunc::frexpl: -- case LibFunc::fstatvfs: -+ case LibFunc_fputc: -+ case LibFunc_fstat: -+ case LibFunc_frexp: -+ case LibFunc_frexpf: -+ case LibFunc_frexpl: -+ case LibFunc_fstatvfs: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fgets: -+ case LibFunc_fgets: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::fread: -+ case LibFunc_fread: - return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(3)->isPointerTy()); -- case LibFunc::fwrite: -+ case LibFunc_fwrite: - return (NumParams == 4 && FTy.getReturnType()->isIntegerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isIntegerTy() && - FTy.getParamType(2)->isIntegerTy() && - FTy.getParamType(3)->isPointerTy()); -- case LibFunc::fputs: -+ case LibFunc_fputs: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fscanf: -- case LibFunc::fprintf: -+ case LibFunc_fscanf: -+ case LibFunc_fprintf: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fgetpos: -+ case LibFunc_fgetpos: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::gets: -- case LibFunc::getchar: -- case LibFunc::getitimer: -+ case LibFunc_gets: -+ case LibFunc_getchar: -+ case LibFunc_getitimer: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::ungetc: -+ case LibFunc_ungetc: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::utime: -- case LibFunc::utimes: -+ case LibFunc_utime: -+ case LibFunc_utimes: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::putc: -+ case LibFunc_putc: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::pread: -- case LibFunc::pwrite: -+ case LibFunc_pread: -+ case LibFunc_pwrite: - return (NumParams == 4 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::popen: -+ case LibFunc_popen: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::vscanf: -+ case LibFunc_vscanf: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::vsscanf: -+ case LibFunc_vsscanf: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::vfscanf: -+ case LibFunc_vfscanf: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::valloc: -+ case LibFunc_valloc: - return (FTy.getReturnType()->isPointerTy()); -- case LibFunc::vprintf: -+ case LibFunc_vprintf: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::vfprintf: -- case LibFunc::vsprintf: -+ case LibFunc_vfprintf: -+ case LibFunc_vsprintf: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::vsnprintf: -+ case LibFunc_vsnprintf: - return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::open: -+ case LibFunc_open: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::opendir: -+ case LibFunc_opendir: - return (NumParams == 1 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy()); -- case LibFunc::tmpfile: -+ case LibFunc_tmpfile: - return (FTy.getReturnType()->isPointerTy()); -- case LibFunc::htonl: -- case LibFunc::htons: -- case LibFunc::ntohl: -- case LibFunc::ntohs: -- case LibFunc::lstat: -+ case LibFunc_htonl: -+ case LibFunc_htons: -+ case LibFunc_ntohl: -+ case LibFunc_ntohs: -+ case LibFunc_lstat: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::lchown: -+ case LibFunc_lchown: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::qsort: -+ case LibFunc_qsort: - return (NumParams == 4 && FTy.getParamType(3)->isPointerTy()); -- case LibFunc::dunder_strdup: -- case LibFunc::dunder_strndup: -+ case LibFunc_dunder_strdup: -+ case LibFunc_dunder_strndup: - return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy()); -- case LibFunc::dunder_strtok_r: -+ case LibFunc_dunder_strtok_r: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::under_IO_putc: -+ case LibFunc_under_IO_putc: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::dunder_isoc99_scanf: -+ case LibFunc_dunder_isoc99_scanf: - return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::stat64: -- case LibFunc::lstat64: -- case LibFunc::statvfs64: -+ case LibFunc_stat64: -+ case LibFunc_lstat64: -+ case LibFunc_statvfs64: - return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::dunder_isoc99_sscanf: -+ case LibFunc_dunder_isoc99_sscanf: - return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fopen64: -+ case LibFunc_fopen64: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::tmpfile64: -+ case LibFunc_tmpfile64: - return (FTy.getReturnType()->isPointerTy()); -- case LibFunc::fstat64: -- case LibFunc::fstatvfs64: -+ case LibFunc_fstat64: -+ case LibFunc_fstatvfs64: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::open64: -+ case LibFunc_open64: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::gettimeofday: -+ case LibFunc_gettimeofday: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); - -- case LibFunc::Znwj: // new(unsigned int); -- case LibFunc::Znwm: // new(unsigned long); -- case LibFunc::Znaj: // new[](unsigned int); -- case LibFunc::Znam: // new[](unsigned long); -- case LibFunc::msvc_new_int: // new(unsigned int); -- case LibFunc::msvc_new_longlong: // new(unsigned long long); -- case LibFunc::msvc_new_array_int: // new[](unsigned int); -- case LibFunc::msvc_new_array_longlong: // new[](unsigned long long); -+ case LibFunc_Znwj: // new(unsigned int); -+ case LibFunc_Znwm: // new(unsigned long); -+ case LibFunc_Znaj: // new[](unsigned int); -+ case LibFunc_Znam: // new[](unsigned long); -+ case LibFunc_msvc_new_int: // new(unsigned int); -+ case LibFunc_msvc_new_longlong: // new(unsigned long long); -+ case LibFunc_msvc_new_array_int: // new[](unsigned int); -+ case LibFunc_msvc_new_array_longlong: // new[](unsigned long long); - return (NumParams == 1); - -- case LibFunc::memset_pattern16: -+ case LibFunc_memset_pattern16: - return (!FTy.isVarArg() && NumParams == 3 && - isa(FTy.getParamType(0)) && - isa(FTy.getParamType(1)) && - isa(FTy.getParamType(2))); - - // int __nvvm_reflect(const char *); -- case LibFunc::nvvm_reflect: -+ case LibFunc_nvvm_reflect: - return (NumParams == 1 && isa(FTy.getParamType(0))); - -- case LibFunc::sin: -- case LibFunc::sinf: -- case LibFunc::sinl: -- case LibFunc::cos: -- case LibFunc::cosf: -- case LibFunc::cosl: -- case LibFunc::tan: -- case LibFunc::tanf: -- case LibFunc::tanl: -- case LibFunc::exp: -- case LibFunc::expf: -- case LibFunc::expl: -- case LibFunc::exp2: -- case LibFunc::exp2f: -- case LibFunc::exp2l: -- case LibFunc::log: -- case LibFunc::logf: -- case LibFunc::logl: -- case LibFunc::log10: -- case LibFunc::log10f: -- case LibFunc::log10l: -- case LibFunc::log2: -- case LibFunc::log2f: -- case LibFunc::log2l: -- case LibFunc::fabs: -- case LibFunc::fabsf: -- case LibFunc::fabsl: -- case LibFunc::floor: -- case LibFunc::floorf: -- case LibFunc::floorl: -- case LibFunc::ceil: -- case LibFunc::ceilf: -- case LibFunc::ceill: -- case LibFunc::trunc: -- case LibFunc::truncf: -- case LibFunc::truncl: -- case LibFunc::rint: -- case LibFunc::rintf: -- case LibFunc::rintl: -- case LibFunc::nearbyint: -- case LibFunc::nearbyintf: -- case LibFunc::nearbyintl: -- case LibFunc::round: -- case LibFunc::roundf: -- case LibFunc::roundl: -- case LibFunc::sqrt: -- case LibFunc::sqrtf: -- case LibFunc::sqrtl: -+ case LibFunc_sin: -+ case LibFunc_sinf: -+ case LibFunc_sinl: -+ case LibFunc_cos: -+ case LibFunc_cosf: -+ case LibFunc_cosl: -+ case LibFunc_tan: -+ case LibFunc_tanf: -+ case LibFunc_tanl: -+ case LibFunc_exp: -+ case LibFunc_expf: -+ case LibFunc_expl: -+ case LibFunc_exp2: -+ case LibFunc_exp2f: -+ case LibFunc_exp2l: -+ case LibFunc_log: -+ case LibFunc_logf: -+ case LibFunc_logl: -+ case LibFunc_log10: -+ case LibFunc_log10f: -+ case LibFunc_log10l: -+ case LibFunc_log2: -+ case LibFunc_log2f: -+ case LibFunc_log2l: -+ case LibFunc_fabs: -+ case LibFunc_fabsf: -+ case LibFunc_fabsl: -+ case LibFunc_floor: -+ case LibFunc_floorf: -+ case LibFunc_floorl: -+ case LibFunc_ceil: -+ case LibFunc_ceilf: -+ case LibFunc_ceill: -+ case LibFunc_trunc: -+ case LibFunc_truncf: -+ case LibFunc_truncl: -+ case LibFunc_rint: -+ case LibFunc_rintf: -+ case LibFunc_rintl: -+ case LibFunc_nearbyint: -+ case LibFunc_nearbyintf: -+ case LibFunc_nearbyintl: -+ case LibFunc_round: -+ case LibFunc_roundf: -+ case LibFunc_roundl: -+ case LibFunc_sqrt: -+ case LibFunc_sqrtf: -+ case LibFunc_sqrtl: - return (NumParams == 1 && FTy.getReturnType()->isFloatingPointTy() && - FTy.getReturnType() == FTy.getParamType(0)); - -- case LibFunc::fmin: -- case LibFunc::fminf: -- case LibFunc::fminl: -- case LibFunc::fmax: -- case LibFunc::fmaxf: -- case LibFunc::fmaxl: -- case LibFunc::copysign: -- case LibFunc::copysignf: -- case LibFunc::copysignl: -- case LibFunc::pow: -- case LibFunc::powf: -- case LibFunc::powl: -+ case LibFunc_fmin: -+ case LibFunc_fminf: -+ case LibFunc_fminl: -+ case LibFunc_fmax: -+ case LibFunc_fmaxf: -+ case LibFunc_fmaxl: -+ case LibFunc_copysign: -+ case LibFunc_copysignf: -+ case LibFunc_copysignl: -+ case LibFunc_pow: -+ case LibFunc_powf: -+ case LibFunc_powl: - return (NumParams == 2 && FTy.getReturnType()->isFloatingPointTy() && - FTy.getReturnType() == FTy.getParamType(0) && - FTy.getReturnType() == FTy.getParamType(1)); - -- case LibFunc::ffs: -- case LibFunc::ffsl: -- case LibFunc::ffsll: -- case LibFunc::isdigit: -- case LibFunc::isascii: -- case LibFunc::toascii: -+ case LibFunc_ffs: -+ case LibFunc_ffsl: -+ case LibFunc_ffsll: -+ case LibFunc_isdigit: -+ case LibFunc_isascii: -+ case LibFunc_toascii: - return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) && - FTy.getParamType(0)->isIntegerTy()); - -- case LibFunc::fls: -- case LibFunc::flsl: -- case LibFunc::flsll: -- case LibFunc::abs: -- case LibFunc::labs: -- case LibFunc::llabs: -+ case LibFunc_fls: -+ case LibFunc_flsl: -+ case LibFunc_flsll: -+ case LibFunc_abs: -+ case LibFunc_labs: -+ case LibFunc_llabs: - return (NumParams == 1 && FTy.getReturnType()->isIntegerTy() && - FTy.getReturnType() == FTy.getParamType(0)); - -- case LibFunc::cxa_atexit: -+ case LibFunc_cxa_atexit: - return (NumParams == 3 && FTy.getReturnType()->isIntegerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); - -- case LibFunc::sinpi: -- case LibFunc::cospi: -+ case LibFunc_sinpi: -+ case LibFunc_cospi: - return (NumParams == 1 && FTy.getReturnType()->isDoubleTy() && - FTy.getReturnType() == FTy.getParamType(0)); - -- case LibFunc::sinpif: -- case LibFunc::cospif: -+ case LibFunc_sinpif: -+ case LibFunc_cospif: - return (NumParams == 1 && FTy.getReturnType()->isFloatTy() && - FTy.getReturnType() == FTy.getParamType(0)); - -@@ -992,7 +992,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, - } - - bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl, -- LibFunc::Func &F) const { -+ LibFunc &F) const { - const DataLayout *DL = - FDecl.getParent() ? &FDecl.getParent()->getDataLayout() : nullptr; - return getLibFunc(FDecl.getName(), F) && -diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp -index f2b40787443..4dcf08b1c81 100644 ---- a/lib/Analysis/ValueTracking.cpp -+++ b/lib/Analysis/ValueTracking.cpp -@@ -2304,7 +2304,7 @@ Intrinsic::ID llvm::getIntrinsicForCallSite(ImmutableCallSite ICS, - if (!TLI) - return Intrinsic::not_intrinsic; - -- LibFunc::Func Func; -+ LibFunc Func; - // We're going to make assumptions on the semantics of the functions, check - // that the target knows that it's available in this environment and it does - // not have local linkage. -@@ -2319,81 +2319,81 @@ Intrinsic::ID llvm::getIntrinsicForCallSite(ImmutableCallSite ICS, - switch (Func) { - default: - break; -- case LibFunc::sin: -- case LibFunc::sinf: -- case LibFunc::sinl: -+ case LibFunc_sin: -+ case LibFunc_sinf: -+ case LibFunc_sinl: - return Intrinsic::sin; -- case LibFunc::cos: -- case LibFunc::cosf: -- case LibFunc::cosl: -+ case LibFunc_cos: -+ case LibFunc_cosf: -+ case LibFunc_cosl: - return Intrinsic::cos; -- case LibFunc::exp: -- case LibFunc::expf: -- case LibFunc::expl: -+ case LibFunc_exp: -+ case LibFunc_expf: -+ case LibFunc_expl: - return Intrinsic::exp; -- case LibFunc::exp2: -- case LibFunc::exp2f: -- case LibFunc::exp2l: -+ case LibFunc_exp2: -+ case LibFunc_exp2f: -+ case LibFunc_exp2l: - return Intrinsic::exp2; -- case LibFunc::log: -- case LibFunc::logf: -- case LibFunc::logl: -+ case LibFunc_log: -+ case LibFunc_logf: -+ case LibFunc_logl: - return Intrinsic::log; -- case LibFunc::log10: -- case LibFunc::log10f: -- case LibFunc::log10l: -+ case LibFunc_log10: -+ case LibFunc_log10f: -+ case LibFunc_log10l: - return Intrinsic::log10; -- case LibFunc::log2: -- case LibFunc::log2f: -- case LibFunc::log2l: -+ case LibFunc_log2: -+ case LibFunc_log2f: -+ case LibFunc_log2l: - return Intrinsic::log2; -- case LibFunc::fabs: -- case LibFunc::fabsf: -- case LibFunc::fabsl: -+ case LibFunc_fabs: -+ case LibFunc_fabsf: -+ case LibFunc_fabsl: - return Intrinsic::fabs; -- case LibFunc::fmin: -- case LibFunc::fminf: -- case LibFunc::fminl: -+ case LibFunc_fmin: -+ case LibFunc_fminf: -+ case LibFunc_fminl: - return Intrinsic::minnum; -- case LibFunc::fmax: -- case LibFunc::fmaxf: -- case LibFunc::fmaxl: -+ case LibFunc_fmax: -+ case LibFunc_fmaxf: -+ case LibFunc_fmaxl: - return Intrinsic::maxnum; -- case LibFunc::copysign: -- case LibFunc::copysignf: -- case LibFunc::copysignl: -+ case LibFunc_copysign: -+ case LibFunc_copysignf: -+ case LibFunc_copysignl: - return Intrinsic::copysign; -- case LibFunc::floor: -- case LibFunc::floorf: -- case LibFunc::floorl: -+ case LibFunc_floor: -+ case LibFunc_floorf: -+ case LibFunc_floorl: - return Intrinsic::floor; -- case LibFunc::ceil: -- case LibFunc::ceilf: -- case LibFunc::ceill: -+ case LibFunc_ceil: -+ case LibFunc_ceilf: -+ case LibFunc_ceill: - return Intrinsic::ceil; -- case LibFunc::trunc: -- case LibFunc::truncf: -- case LibFunc::truncl: -+ case LibFunc_trunc: -+ case LibFunc_truncf: -+ case LibFunc_truncl: - return Intrinsic::trunc; -- case LibFunc::rint: -- case LibFunc::rintf: -- case LibFunc::rintl: -+ case LibFunc_rint: -+ case LibFunc_rintf: -+ case LibFunc_rintl: - return Intrinsic::rint; -- case LibFunc::nearbyint: -- case LibFunc::nearbyintf: -- case LibFunc::nearbyintl: -+ case LibFunc_nearbyint: -+ case LibFunc_nearbyintf: -+ case LibFunc_nearbyintl: - return Intrinsic::nearbyint; -- case LibFunc::round: -- case LibFunc::roundf: -- case LibFunc::roundl: -+ case LibFunc_round: -+ case LibFunc_roundf: -+ case LibFunc_roundl: - return Intrinsic::round; -- case LibFunc::pow: -- case LibFunc::powf: -- case LibFunc::powl: -+ case LibFunc_pow: -+ case LibFunc_powf: -+ case LibFunc_powl: - return Intrinsic::pow; -- case LibFunc::sqrt: -- case LibFunc::sqrtf: -- case LibFunc::sqrtl: -+ case LibFunc_sqrt: -+ case LibFunc_sqrtf: -+ case LibFunc_sqrtl: - if (ICS->hasNoNaNs()) - return Intrinsic::sqrt; - return Intrinsic::not_intrinsic; -diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp -index b10da002fcf..35ee744b943 100644 ---- a/lib/CodeGen/SelectionDAG/FastISel.cpp -+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp -@@ -1383,7 +1383,7 @@ bool FastISel::selectInstruction(const Instruction *I) { - - if (const auto *Call = dyn_cast(I)) { - const Function *F = Call->getCalledFunction(); -- LibFunc::Func Func; -+ LibFunc Func; - - // As a special case, don't handle calls to builtin library functions that - // may be translated directly to target instructions. -diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp -index e03282cad6b..d96677e7795 100644 ---- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp -+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp -@@ -6222,15 +6222,15 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) { - // Check for well-known libc/libm calls. If the function is internal, it - // can't be a library call. Don't do the check if marked as nobuiltin for - // some reason. -- LibFunc::Func Func; -+ LibFunc Func; - if (!I.isNoBuiltin() && !F->hasLocalLinkage() && F->hasName() && - LibInfo->getLibFunc(F->getName(), Func) && - LibInfo->hasOptimizedCodeGen(Func)) { - switch (Func) { - default: break; -- case LibFunc::copysign: -- case LibFunc::copysignf: -- case LibFunc::copysignl: -+ case LibFunc_copysign: -+ case LibFunc_copysignf: -+ case LibFunc_copysignl: - if (I.getNumArgOperands() == 2 && // Basic sanity checks. - I.getArgOperand(0)->getType()->isFloatingPointTy() && - I.getType() == I.getArgOperand(0)->getType() && -@@ -6243,118 +6243,118 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) { - return; - } - break; -- case LibFunc::fabs: -- case LibFunc::fabsf: -- case LibFunc::fabsl: -+ case LibFunc_fabs: -+ case LibFunc_fabsf: -+ case LibFunc_fabsl: - if (visitUnaryFloatCall(I, ISD::FABS)) - return; - break; -- case LibFunc::fmin: -- case LibFunc::fminf: -- case LibFunc::fminl: -+ case LibFunc_fmin: -+ case LibFunc_fminf: -+ case LibFunc_fminl: - if (visitBinaryFloatCall(I, ISD::FMINNUM)) - return; - break; -- case LibFunc::fmax: -- case LibFunc::fmaxf: -- case LibFunc::fmaxl: -+ case LibFunc_fmax: -+ case LibFunc_fmaxf: -+ case LibFunc_fmaxl: - if (visitBinaryFloatCall(I, ISD::FMAXNUM)) - return; - break; -- case LibFunc::sin: -- case LibFunc::sinf: -- case LibFunc::sinl: -+ case LibFunc_sin: -+ case LibFunc_sinf: -+ case LibFunc_sinl: - if (visitUnaryFloatCall(I, ISD::FSIN)) - return; - break; -- case LibFunc::cos: -- case LibFunc::cosf: -- case LibFunc::cosl: -+ case LibFunc_cos: -+ case LibFunc_cosf: -+ case LibFunc_cosl: - if (visitUnaryFloatCall(I, ISD::FCOS)) - return; - break; -- case LibFunc::sqrt: -- case LibFunc::sqrtf: -- case LibFunc::sqrtl: -- case LibFunc::sqrt_finite: -- case LibFunc::sqrtf_finite: -- case LibFunc::sqrtl_finite: -+ case LibFunc_sqrt: -+ case LibFunc_sqrtf: -+ case LibFunc_sqrtl: -+ case LibFunc_sqrt_finite: -+ case LibFunc_sqrtf_finite: -+ case LibFunc_sqrtl_finite: - if (visitUnaryFloatCall(I, ISD::FSQRT)) - return; - break; -- case LibFunc::floor: -- case LibFunc::floorf: -- case LibFunc::floorl: -+ case LibFunc_floor: -+ case LibFunc_floorf: -+ case LibFunc_floorl: - if (visitUnaryFloatCall(I, ISD::FFLOOR)) - return; - break; -- case LibFunc::nearbyint: -- case LibFunc::nearbyintf: -- case LibFunc::nearbyintl: -+ case LibFunc_nearbyint: -+ case LibFunc_nearbyintf: -+ case LibFunc_nearbyintl: - if (visitUnaryFloatCall(I, ISD::FNEARBYINT)) - return; - break; -- case LibFunc::ceil: -- case LibFunc::ceilf: -- case LibFunc::ceill: -+ case LibFunc_ceil: -+ case LibFunc_ceilf: -+ case LibFunc_ceill: - if (visitUnaryFloatCall(I, ISD::FCEIL)) - return; - break; -- case LibFunc::rint: -- case LibFunc::rintf: -- case LibFunc::rintl: -+ case LibFunc_rint: -+ case LibFunc_rintf: -+ case LibFunc_rintl: - if (visitUnaryFloatCall(I, ISD::FRINT)) - return; - break; -- case LibFunc::round: -- case LibFunc::roundf: -- case LibFunc::roundl: -+ case LibFunc_round: -+ case LibFunc_roundf: -+ case LibFunc_roundl: - if (visitUnaryFloatCall(I, ISD::FROUND)) - return; - break; -- case LibFunc::trunc: -- case LibFunc::truncf: -- case LibFunc::truncl: -+ case LibFunc_trunc: -+ case LibFunc_truncf: -+ case LibFunc_truncl: - if (visitUnaryFloatCall(I, ISD::FTRUNC)) - return; - break; -- case LibFunc::log2: -- case LibFunc::log2f: -- case LibFunc::log2l: -+ case LibFunc_log2: -+ case LibFunc_log2f: -+ case LibFunc_log2l: - if (visitUnaryFloatCall(I, ISD::FLOG2)) - return; - break; -- case LibFunc::exp2: -- case LibFunc::exp2f: -- case LibFunc::exp2l: -+ case LibFunc_exp2: -+ case LibFunc_exp2f: -+ case LibFunc_exp2l: - if (visitUnaryFloatCall(I, ISD::FEXP2)) - return; - break; -- case LibFunc::memcmp: -+ case LibFunc_memcmp: - if (visitMemCmpCall(I)) - return; - break; -- case LibFunc::memchr: -+ case LibFunc_memchr: - if (visitMemChrCall(I)) - return; - break; -- case LibFunc::strcpy: -+ case LibFunc_strcpy: - if (visitStrCpyCall(I, false)) - return; - break; -- case LibFunc::stpcpy: -+ case LibFunc_stpcpy: - if (visitStrCpyCall(I, true)) - return; - break; -- case LibFunc::strcmp: -+ case LibFunc_strcmp: - if (visitStrCmpCall(I)) - return; - break; -- case LibFunc::strlen: -+ case LibFunc_strlen: - if (visitStrLenCall(I)) - return; - break; -- case LibFunc::strnlen: -+ case LibFunc_strnlen: - if (visitStrNLenCall(I)) - return; - break; -diff --git a/lib/LTO/UpdateCompilerUsed.cpp b/lib/LTO/UpdateCompilerUsed.cpp -index a574db6fb5a..3af239b7549 100644 ---- a/lib/LTO/UpdateCompilerUsed.cpp -+++ b/lib/LTO/UpdateCompilerUsed.cpp -@@ -64,7 +64,7 @@ private: - // target. - for (unsigned I = 0, E = static_cast(LibFunc::NumLibFuncs); - I != E; ++I) { -- LibFunc::Func F = static_cast(I); -+ LibFunc F = static_cast(I); - if (TLI.has(F)) - Libcalls.insert(TLI.getName(F)); - } -diff --git a/lib/Target/PowerPC/PPCCTRLoops.cpp b/lib/Target/PowerPC/PPCCTRLoops.cpp -index 87522663591..ad7bcd9d752 100644 ---- a/lib/Target/PowerPC/PPCCTRLoops.cpp -+++ b/lib/Target/PowerPC/PPCCTRLoops.cpp -@@ -315,7 +315,7 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) { - // (i.e. soft float or atomics). If adapting for targets that do, - // additional care is required here. - -- LibFunc::Func Func; -+ LibFunc Func; - if (!F->hasLocalLinkage() && F->hasName() && LibInfo && - LibInfo->getLibFunc(F->getName(), Func) && - LibInfo->hasOptimizedCodeGen(Func)) { -@@ -329,50 +329,50 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) { - - switch (Func) { - default: return true; -- case LibFunc::copysign: -- case LibFunc::copysignf: -+ case LibFunc_copysign: -+ case LibFunc_copysignf: - continue; // ISD::FCOPYSIGN is never a library call. -- case LibFunc::copysignl: -+ case LibFunc_copysignl: - return true; -- case LibFunc::fabs: -- case LibFunc::fabsf: -- case LibFunc::fabsl: -+ case LibFunc_fabs: -+ case LibFunc_fabsf: -+ case LibFunc_fabsl: - continue; // ISD::FABS is never a library call. -- case LibFunc::sqrt: -- case LibFunc::sqrtf: -- case LibFunc::sqrtl: -+ case LibFunc_sqrt: -+ case LibFunc_sqrtf: -+ case LibFunc_sqrtl: - Opcode = ISD::FSQRT; break; -- case LibFunc::floor: -- case LibFunc::floorf: -- case LibFunc::floorl: -+ case LibFunc_floor: -+ case LibFunc_floorf: -+ case LibFunc_floorl: - Opcode = ISD::FFLOOR; break; -- case LibFunc::nearbyint: -- case LibFunc::nearbyintf: -- case LibFunc::nearbyintl: -+ case LibFunc_nearbyint: -+ case LibFunc_nearbyintf: -+ case LibFunc_nearbyintl: - Opcode = ISD::FNEARBYINT; break; -- case LibFunc::ceil: -- case LibFunc::ceilf: -- case LibFunc::ceill: -+ case LibFunc_ceil: -+ case LibFunc_ceilf: -+ case LibFunc_ceill: - Opcode = ISD::FCEIL; break; -- case LibFunc::rint: -- case LibFunc::rintf: -- case LibFunc::rintl: -+ case LibFunc_rint: -+ case LibFunc_rintf: -+ case LibFunc_rintl: - Opcode = ISD::FRINT; break; -- case LibFunc::round: -- case LibFunc::roundf: -- case LibFunc::roundl: -+ case LibFunc_round: -+ case LibFunc_roundf: -+ case LibFunc_roundl: - Opcode = ISD::FROUND; break; -- case LibFunc::trunc: -- case LibFunc::truncf: -- case LibFunc::truncl: -+ case LibFunc_trunc: -+ case LibFunc_truncf: -+ case LibFunc_truncl: - Opcode = ISD::FTRUNC; break; -- case LibFunc::fmin: -- case LibFunc::fminf: -- case LibFunc::fminl: -+ case LibFunc_fmin: -+ case LibFunc_fminf: -+ case LibFunc_fminl: - Opcode = ISD::FMINNUM; break; -- case LibFunc::fmax: -- case LibFunc::fmaxf: -- case LibFunc::fmaxl: -+ case LibFunc_fmax: -+ case LibFunc_fmaxf: -+ case LibFunc_fmaxl: - Opcode = ISD::FMAXNUM; break; - } - } -diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp -index 99b12d4db0d..3fd706f4914 100644 ---- a/lib/Transforms/IPO/GlobalOpt.cpp -+++ b/lib/Transforms/IPO/GlobalOpt.cpp -@@ -2403,7 +2403,7 @@ OptimizeGlobalAliases(Module &M, - } - - static Function *FindCXAAtExit(Module &M, TargetLibraryInfo *TLI) { -- LibFunc::Func F = LibFunc::cxa_atexit; -+ LibFunc F = LibFunc_cxa_atexit; - if (!TLI->has(F)) - return nullptr; - -@@ -2412,7 +2412,7 @@ static Function *FindCXAAtExit(Module &M, TargetLibraryInfo *TLI) { - return nullptr; - - // Make sure that the function has the correct prototype. -- if (!TLI->getLibFunc(*Fn, F) || F != LibFunc::cxa_atexit) -+ if (!TLI->getLibFunc(*Fn, F) || F != LibFunc_cxa_atexit) - return nullptr; - - return Fn; -diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp -index ed58a87ae1a..c2052042253 100644 ---- a/lib/Transforms/Scalar/DeadStoreElimination.cpp -+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp -@@ -130,13 +130,13 @@ static bool hasMemoryWrite(Instruction *I, const TargetLibraryInfo &TLI) { - if (auto CS = CallSite(I)) { - if (Function *F = CS.getCalledFunction()) { - StringRef FnName = F->getName(); -- if (TLI.has(LibFunc::strcpy) && FnName == TLI.getName(LibFunc::strcpy)) -+ if (TLI.has(LibFunc_strcpy) && FnName == TLI.getName(LibFunc_strcpy)) - return true; -- if (TLI.has(LibFunc::strncpy) && FnName == TLI.getName(LibFunc::strncpy)) -+ if (TLI.has(LibFunc_strncpy) && FnName == TLI.getName(LibFunc_strncpy)) - return true; -- if (TLI.has(LibFunc::strcat) && FnName == TLI.getName(LibFunc::strcat)) -+ if (TLI.has(LibFunc_strcat) && FnName == TLI.getName(LibFunc_strcat)) - return true; -- if (TLI.has(LibFunc::strncat) && FnName == TLI.getName(LibFunc::strncat)) -+ if (TLI.has(LibFunc_strncat) && FnName == TLI.getName(LibFunc_strncat)) - return true; - } - } -diff --git a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp -index 1468676a354..43c33ec7a52 100644 ---- a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp -+++ b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp -@@ -229,9 +229,9 @@ bool LoopIdiomRecognize::runOnLoop(Loop *L) { - if (Name == "memset" || Name == "memcpy") - return false; - -- HasMemset = TLI->has(LibFunc::memset); -- HasMemsetPattern = TLI->has(LibFunc::memset_pattern16); -- HasMemcpy = TLI->has(LibFunc::memcpy); -+ HasMemset = TLI->has(LibFunc_memset); -+ HasMemsetPattern = TLI->has(LibFunc_memset_pattern16); -+ HasMemcpy = TLI->has(LibFunc_memcpy); - - if (HasMemset || HasMemsetPattern || HasMemcpy) - if (SE->hasLoopInvariantBackedgeTakenCount(L)) -diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp -index d64c658f843..6c45e9e1e2b 100644 ---- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp -+++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp -@@ -1233,7 +1233,7 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M) { - bool MemCpyOptPass::processMemMove(MemMoveInst *M) { - AliasAnalysis &AA = LookupAliasAnalysis(); - -- if (!TLI->has(LibFunc::memmove)) -+ if (!TLI->has(LibFunc_memmove)) - return false; - - // See if the pointers alias. -@@ -1407,7 +1407,7 @@ bool MemCpyOptPass::runImpl( - // If we don't have at least memset and memcpy, there is little point of doing - // anything here. These are required by a freestanding implementation, so if - // even they are disabled, there is no point in trying hard. -- if (!TLI->has(LibFunc::memset) || !TLI->has(LibFunc::memcpy)) -+ if (!TLI->has(LibFunc_memset) || !TLI->has(LibFunc_memcpy)) - return false; - - while (1) { -diff --git a/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp b/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp -index c4b3e3464f4..b66859d9eee 100644 ---- a/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp -+++ b/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp -@@ -98,14 +98,14 @@ static bool runPartiallyInlineLibCalls(Function &F, TargetLibraryInfo *TLI, - - // Skip if function either has local linkage or is not a known library - // function. -- LibFunc::Func LibFunc; -+ LibFunc LF; - if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() || -- !TLI->getLibFunc(CalledFunc->getName(), LibFunc)) -+ !TLI->getLibFunc(CalledFunc->getName(), LF)) - continue; - -- switch (LibFunc) { -- case LibFunc::sqrtf: -- case LibFunc::sqrt: -+ switch (LF) { -+ case LibFunc_sqrtf: -+ case LibFunc_sqrt: - if (TTI->haveFastSqrt(Call->getType()) && - optimizeSQRT(Call, CalledFunc, *CurrBB, BB)) - break; -diff --git a/lib/Transforms/Utils/BuildLibCalls.cpp b/lib/Transforms/Utils/BuildLibCalls.cpp -index f4260a9ff98..740fb31c1de 100644 ---- a/lib/Transforms/Utils/BuildLibCalls.cpp -+++ b/lib/Transforms/Utils/BuildLibCalls.cpp -@@ -107,254 +107,254 @@ static bool setNonNull(Function &F, unsigned n) { - } - - bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { -- LibFunc::Func TheLibFunc; -+ LibFunc TheLibFunc; - if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc))) - return false; - - bool Changed = false; - switch (TheLibFunc) { -- case LibFunc::strlen: -+ case LibFunc_strlen: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::strchr: -- case LibFunc::strrchr: -+ case LibFunc_strchr: -+ case LibFunc_strrchr: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - return Changed; -- case LibFunc::strtol: -- case LibFunc::strtod: -- case LibFunc::strtof: -- case LibFunc::strtoul: -- case LibFunc::strtoll: -- case LibFunc::strtold: -- case LibFunc::strtoull: -+ case LibFunc_strtol: -+ case LibFunc_strtod: -+ case LibFunc_strtof: -+ case LibFunc_strtoul: -+ case LibFunc_strtoll: -+ case LibFunc_strtold: -+ case LibFunc_strtoull: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::strcpy: -- case LibFunc::stpcpy: -- case LibFunc::strcat: -- case LibFunc::strncat: -- case LibFunc::strncpy: -- case LibFunc::stpncpy: -+ case LibFunc_strcpy: -+ case LibFunc_stpcpy: -+ case LibFunc_strcat: -+ case LibFunc_strncat: -+ case LibFunc_strncpy: -+ case LibFunc_stpncpy: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::strxfrm: -+ case LibFunc_strxfrm: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::strcmp: // 0,1 -- case LibFunc::strspn: // 0,1 -- case LibFunc::strncmp: // 0,1 -- case LibFunc::strcspn: // 0,1 -- case LibFunc::strcoll: // 0,1 -- case LibFunc::strcasecmp: // 0,1 -- case LibFunc::strncasecmp: // -+ case LibFunc_strcmp: // 0,1 -+ case LibFunc_strspn: // 0,1 -+ case LibFunc_strncmp: // 0,1 -+ case LibFunc_strcspn: // 0,1 -+ case LibFunc_strcoll: // 0,1 -+ case LibFunc_strcasecmp: // 0,1 -+ case LibFunc_strncasecmp: // - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::strstr: -- case LibFunc::strpbrk: -+ case LibFunc_strstr: -+ case LibFunc_strpbrk: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::strtok: -- case LibFunc::strtok_r: -+ case LibFunc_strtok: -+ case LibFunc_strtok_r: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::scanf: -+ case LibFunc_scanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::setbuf: -- case LibFunc::setvbuf: -+ case LibFunc_setbuf: -+ case LibFunc_setvbuf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::strdup: -- case LibFunc::strndup: -+ case LibFunc_strdup: -+ case LibFunc_strndup: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::stat: -- case LibFunc::statvfs: -+ case LibFunc_stat: -+ case LibFunc_statvfs: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::sscanf: -+ case LibFunc_sscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::sprintf: -+ case LibFunc_sprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::snprintf: -+ case LibFunc_snprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 3); - Changed |= setOnlyReadsMemory(F, 3); - return Changed; -- case LibFunc::setitimer: -+ case LibFunc_setitimer: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setDoesNotCapture(F, 3); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::system: -+ case LibFunc_system: - // May throw; "system" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::malloc: -+ case LibFunc_malloc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::memcmp: -+ case LibFunc_memcmp: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::memchr: -- case LibFunc::memrchr: -+ case LibFunc_memchr: -+ case LibFunc_memrchr: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - return Changed; -- case LibFunc::modf: -- case LibFunc::modff: -- case LibFunc::modfl: -+ case LibFunc_modf: -+ case LibFunc_modff: -+ case LibFunc_modfl: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::memcpy: -- case LibFunc::memccpy: -- case LibFunc::memmove: -+ case LibFunc_memcpy: -+ case LibFunc_memccpy: -+ case LibFunc_memmove: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::memcpy_chk: -+ case LibFunc_memcpy_chk: - Changed |= setDoesNotThrow(F); - return Changed; -- case LibFunc::memalign: -+ case LibFunc_memalign: - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::mkdir: -+ case LibFunc_mkdir: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::mktime: -+ case LibFunc_mktime: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::realloc: -+ case LibFunc_realloc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::read: -+ case LibFunc_read: - // May throw; "read" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::rewind: -+ case LibFunc_rewind: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::rmdir: -- case LibFunc::remove: -- case LibFunc::realpath: -+ case LibFunc_rmdir: -+ case LibFunc_remove: -+ case LibFunc_realpath: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::rename: -+ case LibFunc_rename: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::readlink: -+ case LibFunc_readlink: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::write: -+ case LibFunc_write: - // May throw; "write" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::bcopy: -+ case LibFunc_bcopy: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::bcmp: -+ case LibFunc_bcmp: - Changed |= setDoesNotThrow(F); - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::bzero: -+ case LibFunc_bzero: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::calloc: -+ case LibFunc_calloc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::chmod: -- case LibFunc::chown: -+ case LibFunc_chmod: -+ case LibFunc_chown: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::ctermid: -- case LibFunc::clearerr: -- case LibFunc::closedir: -+ case LibFunc_ctermid: -+ case LibFunc_clearerr: -+ case LibFunc_closedir: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::atoi: -- case LibFunc::atol: -- case LibFunc::atof: -- case LibFunc::atoll: -+ case LibFunc_atoi: -+ case LibFunc_atol: -+ case LibFunc_atof: -+ case LibFunc_atoll: - Changed |= setDoesNotThrow(F); - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::access: -+ case LibFunc_access: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::fopen: -+ case LibFunc_fopen: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); -@@ -362,150 +362,150 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::fdopen: -+ case LibFunc_fdopen: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::feof: -- case LibFunc::free: -- case LibFunc::fseek: -- case LibFunc::ftell: -- case LibFunc::fgetc: -- case LibFunc::fseeko: -- case LibFunc::ftello: -- case LibFunc::fileno: -- case LibFunc::fflush: -- case LibFunc::fclose: -- case LibFunc::fsetpos: -- case LibFunc::flockfile: -- case LibFunc::funlockfile: -- case LibFunc::ftrylockfile: -+ case LibFunc_feof: -+ case LibFunc_free: -+ case LibFunc_fseek: -+ case LibFunc_ftell: -+ case LibFunc_fgetc: -+ case LibFunc_fseeko: -+ case LibFunc_ftello: -+ case LibFunc_fileno: -+ case LibFunc_fflush: -+ case LibFunc_fclose: -+ case LibFunc_fsetpos: -+ case LibFunc_flockfile: -+ case LibFunc_funlockfile: -+ case LibFunc_ftrylockfile: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::ferror: -+ case LibFunc_ferror: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F); - return Changed; -- case LibFunc::fputc: -- case LibFunc::fstat: -- case LibFunc::frexp: -- case LibFunc::frexpf: -- case LibFunc::frexpl: -- case LibFunc::fstatvfs: -+ case LibFunc_fputc: -+ case LibFunc_fstat: -+ case LibFunc_frexp: -+ case LibFunc_frexpf: -+ case LibFunc_frexpl: -+ case LibFunc_fstatvfs: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::fgets: -+ case LibFunc_fgets: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 3); - return Changed; -- case LibFunc::fread: -+ case LibFunc_fread: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 4); - return Changed; -- case LibFunc::fwrite: -+ case LibFunc_fwrite: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 4); - // FIXME: readonly #1? - return Changed; -- case LibFunc::fputs: -+ case LibFunc_fputs: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::fscanf: -- case LibFunc::fprintf: -+ case LibFunc_fscanf: -+ case LibFunc_fprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::fgetpos: -+ case LibFunc_fgetpos: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::getc: -- case LibFunc::getlogin_r: -- case LibFunc::getc_unlocked: -+ case LibFunc_getc: -+ case LibFunc_getlogin_r: -+ case LibFunc_getc_unlocked: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::getenv: -+ case LibFunc_getenv: - Changed |= setDoesNotThrow(F); - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::gets: -- case LibFunc::getchar: -+ case LibFunc_gets: -+ case LibFunc_getchar: - Changed |= setDoesNotThrow(F); - return Changed; -- case LibFunc::getitimer: -+ case LibFunc_getitimer: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::getpwnam: -+ case LibFunc_getpwnam: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::ungetc: -+ case LibFunc_ungetc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::uname: -+ case LibFunc_uname: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::unlink: -+ case LibFunc_unlink: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::unsetenv: -+ case LibFunc_unsetenv: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::utime: -- case LibFunc::utimes: -+ case LibFunc_utime: -+ case LibFunc_utimes: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::putc: -+ case LibFunc_putc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::puts: -- case LibFunc::printf: -- case LibFunc::perror: -+ case LibFunc_puts: -+ case LibFunc_printf: -+ case LibFunc_perror: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::pread: -+ case LibFunc_pread: - // May throw; "pread" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::pwrite: -+ case LibFunc_pwrite: - // May throw; "pwrite" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::putchar: -+ case LibFunc_putchar: - Changed |= setDoesNotThrow(F); - return Changed; -- case LibFunc::popen: -+ case LibFunc_popen: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); -@@ -513,132 +513,132 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::pclose: -+ case LibFunc_pclose: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::vscanf: -+ case LibFunc_vscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::vsscanf: -+ case LibFunc_vsscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::vfscanf: -+ case LibFunc_vfscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::valloc: -+ case LibFunc_valloc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::vprintf: -+ case LibFunc_vprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::vfprintf: -- case LibFunc::vsprintf: -+ case LibFunc_vfprintf: -+ case LibFunc_vsprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::vsnprintf: -+ case LibFunc_vsnprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 3); - Changed |= setOnlyReadsMemory(F, 3); - return Changed; -- case LibFunc::open: -+ case LibFunc_open: - // May throw; "open" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::opendir: -+ case LibFunc_opendir: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::tmpfile: -+ case LibFunc_tmpfile: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::times: -+ case LibFunc_times: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::htonl: -- case LibFunc::htons: -- case LibFunc::ntohl: -- case LibFunc::ntohs: -+ case LibFunc_htonl: -+ case LibFunc_htons: -+ case LibFunc_ntohl: -+ case LibFunc_ntohs: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAccessMemory(F); - return Changed; -- case LibFunc::lstat: -+ case LibFunc_lstat: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::lchown: -+ case LibFunc_lchown: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::qsort: -+ case LibFunc_qsort: - // May throw; places call through function pointer. - Changed |= setDoesNotCapture(F, 4); - return Changed; -- case LibFunc::dunder_strdup: -- case LibFunc::dunder_strndup: -+ case LibFunc_dunder_strdup: -+ case LibFunc_dunder_strndup: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::dunder_strtok_r: -+ case LibFunc_dunder_strtok_r: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::under_IO_getc: -+ case LibFunc_under_IO_getc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::under_IO_putc: -+ case LibFunc_under_IO_putc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::dunder_isoc99_scanf: -+ case LibFunc_dunder_isoc99_scanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::stat64: -- case LibFunc::lstat64: -- case LibFunc::statvfs64: -+ case LibFunc_stat64: -+ case LibFunc_lstat64: -+ case LibFunc_statvfs64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::dunder_isoc99_sscanf: -+ case LibFunc_dunder_isoc99_sscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::fopen64: -+ case LibFunc_fopen64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); -@@ -646,26 +646,26 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::fseeko64: -- case LibFunc::ftello64: -+ case LibFunc_fseeko64: -+ case LibFunc_ftello64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::tmpfile64: -+ case LibFunc_tmpfile64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::fstat64: -- case LibFunc::fstatvfs64: -+ case LibFunc_fstat64: -+ case LibFunc_fstatvfs64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::open64: -+ case LibFunc_open64: - // May throw; "open" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::gettimeofday: -+ case LibFunc_gettimeofday: - // Currently some platforms have the restrict keyword on the arguments to - // gettimeofday. To be conservative, do not add noalias to gettimeofday's - // arguments. -@@ -673,29 +673,29 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::Znwj: // new(unsigned int) -- case LibFunc::Znwm: // new(unsigned long) -- case LibFunc::Znaj: // new[](unsigned int) -- case LibFunc::Znam: // new[](unsigned long) -- case LibFunc::msvc_new_int: // new(unsigned int) -- case LibFunc::msvc_new_longlong: // new(unsigned long long) -- case LibFunc::msvc_new_array_int: // new[](unsigned int) -- case LibFunc::msvc_new_array_longlong: // new[](unsigned long long) -+ case LibFunc_Znwj: // new(unsigned int) -+ case LibFunc_Znwm: // new(unsigned long) -+ case LibFunc_Znaj: // new[](unsigned int) -+ case LibFunc_Znam: // new[](unsigned long) -+ case LibFunc_msvc_new_int: // new(unsigned int) -+ case LibFunc_msvc_new_longlong: // new(unsigned long long) -+ case LibFunc_msvc_new_array_int: // new[](unsigned int) -+ case LibFunc_msvc_new_array_longlong: // new[](unsigned long long) - // Operator new always returns a nonnull noalias pointer - Changed |= setNonNull(F, AttributeSet::ReturnIndex); - Changed |= setDoesNotAlias(F, AttributeSet::ReturnIndex); - return Changed; - //TODO: add LibFunc entries for: -- //case LibFunc::memset_pattern4: -- //case LibFunc::memset_pattern8: -- case LibFunc::memset_pattern16: -+ //case LibFunc_memset_pattern4: -+ //case LibFunc_memset_pattern8: -+ case LibFunc_memset_pattern16: - Changed |= setOnlyAccessesArgMemory(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; - // int __nvvm_reflect(const char *) -- case LibFunc::nvvm_reflect: -+ case LibFunc_nvvm_reflect: - Changed |= setDoesNotAccessMemory(F); - Changed |= setDoesNotThrow(F); - return Changed; -@@ -716,7 +716,7 @@ Value *llvm::castToCStr(Value *V, IRBuilder<> &B) { - - Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::strlen)) -+ if (!TLI->has(LibFunc_strlen)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -733,7 +733,7 @@ Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL, - - Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::strchr)) -+ if (!TLI->has(LibFunc_strchr)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -751,7 +751,7 @@ Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B, - - Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::strncmp)) -+ if (!TLI->has(LibFunc_strncmp)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -771,7 +771,7 @@ Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - - Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, - const TargetLibraryInfo *TLI, StringRef Name) { -- if (!TLI->has(LibFunc::strcpy)) -+ if (!TLI->has(LibFunc_strcpy)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -787,7 +787,7 @@ Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, - - Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, - const TargetLibraryInfo *TLI, StringRef Name) { -- if (!TLI->has(LibFunc::strncpy)) -+ if (!TLI->has(LibFunc_strncpy)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -805,7 +805,7 @@ Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, - Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, - IRBuilder<> &B, const DataLayout &DL, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::memcpy_chk)) -+ if (!TLI->has(LibFunc_memcpy_chk)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -827,7 +827,7 @@ Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, - - Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::memchr)) -+ if (!TLI->has(LibFunc_memchr)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -846,7 +846,7 @@ Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, - - Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::memcmp)) -+ if (!TLI->has(LibFunc_memcmp)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -913,7 +913,7 @@ Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name, - - Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::putchar)) -+ if (!TLI->has(LibFunc_putchar)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -933,7 +933,7 @@ Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B, - - Value *llvm::emitPutS(Value *Str, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::puts)) -+ if (!TLI->has(LibFunc_puts)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -948,7 +948,7 @@ Value *llvm::emitPutS(Value *Str, IRBuilder<> &B, - - Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::fputc)) -+ if (!TLI->has(LibFunc_fputc)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -967,11 +967,11 @@ Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B, - - Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::fputs)) -+ if (!TLI->has(LibFunc_fputs)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -- StringRef FPutsName = TLI->getName(LibFunc::fputs); -+ StringRef FPutsName = TLI->getName(LibFunc_fputs); - Constant *F = M->getOrInsertFunction( - FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType(), nullptr); - if (File->getType()->isPointerTy()) -@@ -985,12 +985,12 @@ Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B, - - Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::fwrite)) -+ if (!TLI->has(LibFunc_fwrite)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - LLVMContext &Context = B.GetInsertBlock()->getContext(); -- StringRef FWriteName = TLI->getName(LibFunc::fwrite); -+ StringRef FWriteName = TLI->getName(LibFunc_fwrite); - Constant *F = M->getOrInsertFunction( - FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(), - DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType(), -diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp -index f1838d89146..7667312bb0e 100644 ---- a/lib/Transforms/Utils/Local.cpp -+++ b/lib/Transforms/Utils/Local.cpp -@@ -1957,19 +1957,19 @@ bool llvm::recognizeBSwapOrBitReverseIdiom( - void llvm::maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, - const TargetLibraryInfo *TLI) { - Function *F = CI->getCalledFunction(); -- LibFunc::Func Func; -+ LibFunc Func; - if (!F || F->hasLocalLinkage() || !F->hasName() || - !TLI->getLibFunc(F->getName(), Func)) - return; - switch (Func) { - default: break; -- case LibFunc::memcmp: -- case LibFunc::memchr: -- case LibFunc::strcpy: -- case LibFunc::stpcpy: -- case LibFunc::strcmp: -- case LibFunc::strlen: -- case LibFunc::strnlen: -+ case LibFunc_memcmp: -+ case LibFunc_memchr: -+ case LibFunc_strcpy: -+ case LibFunc_stpcpy: -+ case LibFunc_strcmp: -+ case LibFunc_strlen: -+ case LibFunc_strnlen: - CI->addAttribute(AttributeSet::FunctionIndex, Attribute::NoBuiltin); - break; - } -diff --git a/lib/Transforms/Utils/SimplifyLibCalls.cpp b/lib/Transforms/Utils/SimplifyLibCalls.cpp -index c2986951e48..69ac831fcfd 100644 ---- a/lib/Transforms/Utils/SimplifyLibCalls.cpp -+++ b/lib/Transforms/Utils/SimplifyLibCalls.cpp -@@ -51,9 +51,9 @@ static cl::opt - // Helper Functions - //===----------------------------------------------------------------------===// - --static bool ignoreCallingConv(LibFunc::Func Func) { -- return Func == LibFunc::abs || Func == LibFunc::labs || -- Func == LibFunc::llabs || Func == LibFunc::strlen; -+static bool ignoreCallingConv(LibFunc Func) { -+ return Func == LibFunc_abs || Func == LibFunc_labs || -+ Func == LibFunc_llabs || Func == LibFunc_strlen; - } - - /// Return true if it only matters that the value is equal or not-equal to zero. -@@ -91,8 +91,8 @@ static bool callHasFloatingPointArgument(const CallInst *CI) { - /// \brief Check whether the overloaded unary floating point function - /// corresponding to \a Ty is available. - static bool hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty, -- LibFunc::Func DoubleFn, LibFunc::Func FloatFn, -- LibFunc::Func LongDoubleFn) { -+ LibFunc DoubleFn, LibFunc FloatFn, -+ LibFunc LongDoubleFn) { - switch (Ty->getTypeID()) { - case Type::FloatTyID: - return TLI->has(FloatFn); -@@ -779,7 +779,7 @@ Value *LibCallSimplifier::optimizeMemMove(CallInst *CI, IRBuilder<> &B) { - // functions be moved here? - static Value *emitCalloc(Value *Num, Value *Size, const AttributeSet &Attrs, - IRBuilder<> &B, const TargetLibraryInfo &TLI) { -- LibFunc::Func Func; -+ LibFunc Func; - if (!TLI.getLibFunc("calloc", Func) || !TLI.has(Func)) - return nullptr; - -@@ -814,9 +814,9 @@ static Value *foldMallocMemset(CallInst *Memset, IRBuilder<> &B, - - // Is the inner call really malloc()? - Function *InnerCallee = Malloc->getCalledFunction(); -- LibFunc::Func Func; -+ LibFunc Func; - if (!TLI.getLibFunc(*InnerCallee, Func) || !TLI.has(Func) || -- Func != LibFunc::malloc) -+ Func != LibFunc_malloc) - return nullptr; - - // The memset must cover the same number of bytes that are malloc'd. -@@ -999,15 +999,15 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { - return Op1C; - // pow(2.0, x) -> exp2(x) - if (Op1C->isExactlyValue(2.0) && -- hasUnaryFloatFn(TLI, Op1->getType(), LibFunc::exp2, LibFunc::exp2f, -- LibFunc::exp2l)) -- return emitUnaryFloatFnCall(Op2, TLI->getName(LibFunc::exp2), B, -+ hasUnaryFloatFn(TLI, Op1->getType(), LibFunc_exp2, LibFunc_exp2f, -+ LibFunc_exp2l)) -+ return emitUnaryFloatFnCall(Op2, TLI->getName(LibFunc_exp2), B, - Callee->getAttributes()); - // pow(10.0, x) -> exp10(x) - if (Op1C->isExactlyValue(10.0) && -- hasUnaryFloatFn(TLI, Op1->getType(), LibFunc::exp10, LibFunc::exp10f, -- LibFunc::exp10l)) -- return emitUnaryFloatFnCall(Op2, TLI->getName(LibFunc::exp10), B, -+ hasUnaryFloatFn(TLI, Op1->getType(), LibFunc_exp10, LibFunc_exp10f, -+ LibFunc_exp10l)) -+ return emitUnaryFloatFnCall(Op2, TLI->getName(LibFunc_exp10), B, - Callee->getAttributes()); - } - -@@ -1019,10 +1019,10 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { - // pow(exp(x), y) = pow(inf, 0.001) = inf, whereas exp(x*y) = exp(1). - auto *OpC = dyn_cast(Op1); - if (OpC && OpC->hasUnsafeAlgebra() && CI->hasUnsafeAlgebra()) { -- LibFunc::Func Func; -+ LibFunc Func; - Function *OpCCallee = OpC->getCalledFunction(); - if (OpCCallee && TLI->getLibFunc(OpCCallee->getName(), Func) && -- TLI->has(Func) && (Func == LibFunc::exp || Func == LibFunc::exp2)) { -+ TLI->has(Func) && (Func == LibFunc_exp || Func == LibFunc_exp2)) { - IRBuilder<>::FastMathFlagGuard Guard(B); - B.setFastMathFlags(CI->getFastMathFlags()); - Value *FMul = B.CreateFMul(OpC->getArgOperand(0), Op2, "mul"); -@@ -1039,16 +1039,16 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { - return ConstantFP::get(CI->getType(), 1.0); - - if (Op2C->isExactlyValue(0.5) && -- hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf, -- LibFunc::sqrtl) && -- hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::fabs, LibFunc::fabsf, -- LibFunc::fabsl)) { -+ hasUnaryFloatFn(TLI, Op2->getType(), LibFunc_sqrt, LibFunc_sqrtf, -+ LibFunc_sqrtl) && -+ hasUnaryFloatFn(TLI, Op2->getType(), LibFunc_fabs, LibFunc_fabsf, -+ LibFunc_fabsl)) { - - // In -ffast-math, pow(x, 0.5) -> sqrt(x). - if (CI->hasUnsafeAlgebra()) { - IRBuilder<>::FastMathFlagGuard Guard(B); - B.setFastMathFlags(CI->getFastMathFlags()); -- return emitUnaryFloatFnCall(Op1, TLI->getName(LibFunc::sqrt), B, -+ return emitUnaryFloatFnCall(Op1, TLI->getName(LibFunc_sqrt), B, - Callee->getAttributes()); - } - -@@ -1113,11 +1113,11 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilder<> &B) { - Value *Op = CI->getArgOperand(0); - // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32 - // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32 -- LibFunc::Func LdExp = LibFunc::ldexpl; -+ LibFunc LdExp = LibFunc_ldexpl; - if (Op->getType()->isFloatTy()) -- LdExp = LibFunc::ldexpf; -+ LdExp = LibFunc_ldexpf; - else if (Op->getType()->isDoubleTy()) -- LdExp = LibFunc::ldexp; -+ LdExp = LibFunc_ldexp; - - if (TLI->has(LdExp)) { - Value *LdExpArg = nullptr; -@@ -1228,17 +1228,17 @@ Value *LibCallSimplifier::optimizeLog(CallInst *CI, IRBuilder<> &B) { - FMF.setUnsafeAlgebra(); - B.setFastMathFlags(FMF); - -- LibFunc::Func Func; -+ LibFunc Func; - Function *F = OpC->getCalledFunction(); - if (F && ((TLI->getLibFunc(F->getName(), Func) && TLI->has(Func) && -- Func == LibFunc::pow) || F->getIntrinsicID() == Intrinsic::pow)) -+ Func == LibFunc_pow) || F->getIntrinsicID() == Intrinsic::pow)) - return B.CreateFMul(OpC->getArgOperand(1), - emitUnaryFloatFnCall(OpC->getOperand(0), Callee->getName(), B, - Callee->getAttributes()), "mul"); - - // log(exp2(y)) -> y*log(2) - if (F && Name == "log" && TLI->getLibFunc(F->getName(), Func) && -- TLI->has(Func) && Func == LibFunc::exp2) -+ TLI->has(Func) && Func == LibFunc_exp2) - return B.CreateFMul( - OpC->getArgOperand(0), - emitUnaryFloatFnCall(ConstantFP::get(CI->getType(), 2.0), -@@ -1250,8 +1250,8 @@ Value *LibCallSimplifier::optimizeLog(CallInst *CI, IRBuilder<> &B) { - Value *LibCallSimplifier::optimizeSqrt(CallInst *CI, IRBuilder<> &B) { - Function *Callee = CI->getCalledFunction(); - Value *Ret = nullptr; -- if (TLI->has(LibFunc::sqrtf) && (Callee->getName() == "sqrt" || -- Callee->getIntrinsicID() == Intrinsic::sqrt)) -+ if (TLI->has(LibFunc_sqrtf) && (Callee->getName() == "sqrt" || -+ Callee->getIntrinsicID() == Intrinsic::sqrt)) - Ret = optimizeUnaryDoubleFP(CI, B, true); - - if (!CI->hasUnsafeAlgebra()) -@@ -1333,12 +1333,12 @@ Value *LibCallSimplifier::optimizeTan(CallInst *CI, IRBuilder<> &B) { - // tan(atan(x)) -> x - // tanf(atanf(x)) -> x - // tanl(atanl(x)) -> x -- LibFunc::Func Func; -+ LibFunc Func; - Function *F = OpC->getCalledFunction(); - if (F && TLI->getLibFunc(F->getName(), Func) && TLI->has(Func) && -- ((Func == LibFunc::atan && Callee->getName() == "tan") || -- (Func == LibFunc::atanf && Callee->getName() == "tanf") || -- (Func == LibFunc::atanl && Callee->getName() == "tanl"))) -+ ((Func == LibFunc_atan && Callee->getName() == "tan") || -+ (Func == LibFunc_atanf && Callee->getName() == "tanf") || -+ (Func == LibFunc_atanl && Callee->getName() == "tanl"))) - Ret = OpC->getArgOperand(0); - return Ret; - } -@@ -1450,24 +1450,24 @@ void LibCallSimplifier::classifyArgUse( - return; - - Function *Callee = CI->getCalledFunction(); -- LibFunc::Func Func; -+ LibFunc Func; - if (!Callee || !TLI->getLibFunc(*Callee, Func) || !TLI->has(Func) || - !isTrigLibCall(CI)) - return; - - if (IsFloat) { -- if (Func == LibFunc::sinpif) -+ if (Func == LibFunc_sinpif) - SinCalls.push_back(CI); -- else if (Func == LibFunc::cospif) -+ else if (Func == LibFunc_cospif) - CosCalls.push_back(CI); -- else if (Func == LibFunc::sincospif_stret) -+ else if (Func == LibFunc_sincospif_stret) - SinCosCalls.push_back(CI); - } else { -- if (Func == LibFunc::sinpi) -+ if (Func == LibFunc_sinpi) - SinCalls.push_back(CI); -- else if (Func == LibFunc::cospi) -+ else if (Func == LibFunc_cospi) - CosCalls.push_back(CI); -- else if (Func == LibFunc::sincospi_stret) -+ else if (Func == LibFunc_sincospi_stret) - SinCosCalls.push_back(CI); - } - } -@@ -1645,7 +1645,7 @@ Value *LibCallSimplifier::optimizePrintF(CallInst *CI, IRBuilder<> &B) { - - // printf(format, ...) -> iprintf(format, ...) if no floating point - // arguments. -- if (TLI->has(LibFunc::iprintf) && !callHasFloatingPointArgument(CI)) { -+ if (TLI->has(LibFunc_iprintf) && !callHasFloatingPointArgument(CI)) { - Module *M = B.GetInsertBlock()->getParent()->getParent(); - Constant *IPrintFFn = - M->getOrInsertFunction("iprintf", FT, Callee->getAttributes()); -@@ -1726,7 +1726,7 @@ Value *LibCallSimplifier::optimizeSPrintF(CallInst *CI, IRBuilder<> &B) { - - // sprintf(str, format, ...) -> siprintf(str, format, ...) if no floating - // point arguments. -- if (TLI->has(LibFunc::siprintf) && !callHasFloatingPointArgument(CI)) { -+ if (TLI->has(LibFunc_siprintf) && !callHasFloatingPointArgument(CI)) { - Module *M = B.GetInsertBlock()->getParent()->getParent(); - Constant *SIPrintFFn = - M->getOrInsertFunction("siprintf", FT, Callee->getAttributes()); -@@ -1796,7 +1796,7 @@ Value *LibCallSimplifier::optimizeFPrintF(CallInst *CI, IRBuilder<> &B) { - - // fprintf(stream, format, ...) -> fiprintf(stream, format, ...) if no - // floating point arguments. -- if (TLI->has(LibFunc::fiprintf) && !callHasFloatingPointArgument(CI)) { -+ if (TLI->has(LibFunc_fiprintf) && !callHasFloatingPointArgument(CI)) { - Module *M = B.GetInsertBlock()->getParent()->getParent(); - Constant *FIPrintFFn = - M->getOrInsertFunction("fiprintf", FT, Callee->getAttributes()); -@@ -1875,7 +1875,7 @@ Value *LibCallSimplifier::optimizePuts(CallInst *CI, IRBuilder<> &B) { - } - - bool LibCallSimplifier::hasFloatVersion(StringRef FuncName) { -- LibFunc::Func Func; -+ LibFunc Func; - SmallString<20> FloatFuncName = FuncName; - FloatFuncName += 'f'; - if (TLI->getLibFunc(FloatFuncName, Func)) -@@ -1885,7 +1885,7 @@ bool LibCallSimplifier::hasFloatVersion(StringRef FuncName) { - - Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI, - IRBuilder<> &Builder) { -- LibFunc::Func Func; -+ LibFunc Func; - Function *Callee = CI->getCalledFunction(); - // Check for string/memory library functions. - if (TLI->getLibFunc(*Callee, Func) && TLI->has(Func)) { -@@ -1894,51 +1894,51 @@ Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI, - CI->getCallingConv() == llvm::CallingConv::C) && - "Optimizing string/memory libcall would change the calling convention"); - switch (Func) { -- case LibFunc::strcat: -+ case LibFunc_strcat: - return optimizeStrCat(CI, Builder); -- case LibFunc::strncat: -+ case LibFunc_strncat: - return optimizeStrNCat(CI, Builder); -- case LibFunc::strchr: -+ case LibFunc_strchr: - return optimizeStrChr(CI, Builder); -- case LibFunc::strrchr: -+ case LibFunc_strrchr: - return optimizeStrRChr(CI, Builder); -- case LibFunc::strcmp: -+ case LibFunc_strcmp: - return optimizeStrCmp(CI, Builder); -- case LibFunc::strncmp: -+ case LibFunc_strncmp: - return optimizeStrNCmp(CI, Builder); -- case LibFunc::strcpy: -+ case LibFunc_strcpy: - return optimizeStrCpy(CI, Builder); -- case LibFunc::stpcpy: -+ case LibFunc_stpcpy: - return optimizeStpCpy(CI, Builder); -- case LibFunc::strncpy: -+ case LibFunc_strncpy: - return optimizeStrNCpy(CI, Builder); -- case LibFunc::strlen: -+ case LibFunc_strlen: - return optimizeStrLen(CI, Builder); -- case LibFunc::strpbrk: -+ case LibFunc_strpbrk: - return optimizeStrPBrk(CI, Builder); -- case LibFunc::strtol: -- case LibFunc::strtod: -- case LibFunc::strtof: -- case LibFunc::strtoul: -- case LibFunc::strtoll: -- case LibFunc::strtold: -- case LibFunc::strtoull: -+ case LibFunc_strtol: -+ case LibFunc_strtod: -+ case LibFunc_strtof: -+ case LibFunc_strtoul: -+ case LibFunc_strtoll: -+ case LibFunc_strtold: -+ case LibFunc_strtoull: - return optimizeStrTo(CI, Builder); -- case LibFunc::strspn: -+ case LibFunc_strspn: - return optimizeStrSpn(CI, Builder); -- case LibFunc::strcspn: -+ case LibFunc_strcspn: - return optimizeStrCSpn(CI, Builder); -- case LibFunc::strstr: -+ case LibFunc_strstr: - return optimizeStrStr(CI, Builder); -- case LibFunc::memchr: -+ case LibFunc_memchr: - return optimizeMemChr(CI, Builder); -- case LibFunc::memcmp: -+ case LibFunc_memcmp: - return optimizeMemCmp(CI, Builder); -- case LibFunc::memcpy: -+ case LibFunc_memcpy: - return optimizeMemCpy(CI, Builder); -- case LibFunc::memmove: -+ case LibFunc_memmove: - return optimizeMemMove(CI, Builder); -- case LibFunc::memset: -+ case LibFunc_memset: - return optimizeMemSet(CI, Builder); - default: - break; -@@ -1951,7 +1951,7 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { - if (CI->isNoBuiltin()) - return nullptr; - -- LibFunc::Func Func; -+ LibFunc Func; - Function *Callee = CI->getCalledFunction(); - StringRef FuncName = Callee->getName(); - -@@ -2013,110 +2013,110 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { - if (Value *V = optimizeStringMemoryLibCall(CI, Builder)) - return V; - switch (Func) { -- case LibFunc::cosf: -- case LibFunc::cos: -- case LibFunc::cosl: -+ case LibFunc_cosf: -+ case LibFunc_cos: -+ case LibFunc_cosl: - return optimizeCos(CI, Builder); -- case LibFunc::sinpif: -- case LibFunc::sinpi: -- case LibFunc::cospif: -- case LibFunc::cospi: -+ case LibFunc_sinpif: -+ case LibFunc_sinpi: -+ case LibFunc_cospif: -+ case LibFunc_cospi: - return optimizeSinCosPi(CI, Builder); -- case LibFunc::powf: -- case LibFunc::pow: -- case LibFunc::powl: -+ case LibFunc_powf: -+ case LibFunc_pow: -+ case LibFunc_powl: - return optimizePow(CI, Builder); -- case LibFunc::exp2l: -- case LibFunc::exp2: -- case LibFunc::exp2f: -+ case LibFunc_exp2l: -+ case LibFunc_exp2: -+ case LibFunc_exp2f: - return optimizeExp2(CI, Builder); -- case LibFunc::fabsf: -- case LibFunc::fabs: -- case LibFunc::fabsl: -+ case LibFunc_fabsf: -+ case LibFunc_fabs: -+ case LibFunc_fabsl: - return optimizeFabs(CI, Builder); -- case LibFunc::sqrtf: -- case LibFunc::sqrt: -- case LibFunc::sqrtl: -+ case LibFunc_sqrtf: -+ case LibFunc_sqrt: -+ case LibFunc_sqrtl: - return optimizeSqrt(CI, Builder); -- case LibFunc::ffs: -- case LibFunc::ffsl: -- case LibFunc::ffsll: -+ case LibFunc_ffs: -+ case LibFunc_ffsl: -+ case LibFunc_ffsll: - return optimizeFFS(CI, Builder); -- case LibFunc::abs: -- case LibFunc::labs: -- case LibFunc::llabs: -+ case LibFunc_abs: -+ case LibFunc_labs: -+ case LibFunc_llabs: - return optimizeAbs(CI, Builder); -- case LibFunc::isdigit: -+ case LibFunc_isdigit: - return optimizeIsDigit(CI, Builder); -- case LibFunc::isascii: -+ case LibFunc_isascii: - return optimizeIsAscii(CI, Builder); -- case LibFunc::toascii: -+ case LibFunc_toascii: - return optimizeToAscii(CI, Builder); -- case LibFunc::printf: -+ case LibFunc_printf: - return optimizePrintF(CI, Builder); -- case LibFunc::sprintf: -+ case LibFunc_sprintf: - return optimizeSPrintF(CI, Builder); -- case LibFunc::fprintf: -+ case LibFunc_fprintf: - return optimizeFPrintF(CI, Builder); -- case LibFunc::fwrite: -+ case LibFunc_fwrite: - return optimizeFWrite(CI, Builder); -- case LibFunc::fputs: -+ case LibFunc_fputs: - return optimizeFPuts(CI, Builder); -- case LibFunc::log: -- case LibFunc::log10: -- case LibFunc::log1p: -- case LibFunc::log2: -- case LibFunc::logb: -+ case LibFunc_log: -+ case LibFunc_log10: -+ case LibFunc_log1p: -+ case LibFunc_log2: -+ case LibFunc_logb: - return optimizeLog(CI, Builder); -- case LibFunc::puts: -+ case LibFunc_puts: - return optimizePuts(CI, Builder); -- case LibFunc::tan: -- case LibFunc::tanf: -- case LibFunc::tanl: -+ case LibFunc_tan: -+ case LibFunc_tanf: -+ case LibFunc_tanl: - return optimizeTan(CI, Builder); -- case LibFunc::perror: -+ case LibFunc_perror: - return optimizeErrorReporting(CI, Builder); -- case LibFunc::vfprintf: -- case LibFunc::fiprintf: -+ case LibFunc_vfprintf: -+ case LibFunc_fiprintf: - return optimizeErrorReporting(CI, Builder, 0); -- case LibFunc::fputc: -+ case LibFunc_fputc: - return optimizeErrorReporting(CI, Builder, 1); -- case LibFunc::ceil: -- case LibFunc::floor: -- case LibFunc::rint: -- case LibFunc::round: -- case LibFunc::nearbyint: -- case LibFunc::trunc: -+ case LibFunc_ceil: -+ case LibFunc_floor: -+ case LibFunc_rint: -+ case LibFunc_round: -+ case LibFunc_nearbyint: -+ case LibFunc_trunc: - if (hasFloatVersion(FuncName)) - return optimizeUnaryDoubleFP(CI, Builder, false); - return nullptr; -- case LibFunc::acos: -- case LibFunc::acosh: -- case LibFunc::asin: -- case LibFunc::asinh: -- case LibFunc::atan: -- case LibFunc::atanh: -- case LibFunc::cbrt: -- case LibFunc::cosh: -- case LibFunc::exp: -- case LibFunc::exp10: -- case LibFunc::expm1: -- case LibFunc::sin: -- case LibFunc::sinh: -- case LibFunc::tanh: -+ case LibFunc_acos: -+ case LibFunc_acosh: -+ case LibFunc_asin: -+ case LibFunc_asinh: -+ case LibFunc_atan: -+ case LibFunc_atanh: -+ case LibFunc_cbrt: -+ case LibFunc_cosh: -+ case LibFunc_exp: -+ case LibFunc_exp10: -+ case LibFunc_expm1: -+ case LibFunc_sin: -+ case LibFunc_sinh: -+ case LibFunc_tanh: - if (UnsafeFPShrink && hasFloatVersion(FuncName)) - return optimizeUnaryDoubleFP(CI, Builder, true); - return nullptr; -- case LibFunc::copysign: -+ case LibFunc_copysign: - if (hasFloatVersion(FuncName)) - return optimizeBinaryDoubleFP(CI, Builder); - return nullptr; -- case LibFunc::fminf: -- case LibFunc::fmin: -- case LibFunc::fminl: -- case LibFunc::fmaxf: -- case LibFunc::fmax: -- case LibFunc::fmaxl: -+ case LibFunc_fminf: -+ case LibFunc_fmin: -+ case LibFunc_fminl: -+ case LibFunc_fmaxf: -+ case LibFunc_fmax: -+ case LibFunc_fmaxl: - return optimizeFMinFMax(CI, Builder); - default: - return nullptr; -@@ -2242,7 +2242,7 @@ Value *FortifiedLibCallSimplifier::optimizeMemSetChk(CallInst *CI, - - Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI, - IRBuilder<> &B, -- LibFunc::Func Func) { -+ LibFunc Func) { - Function *Callee = CI->getCalledFunction(); - StringRef Name = Callee->getName(); - const DataLayout &DL = CI->getModule()->getDataLayout(); -@@ -2250,7 +2250,7 @@ Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI, - *ObjSize = CI->getArgOperand(2); - - // __stpcpy_chk(x,x,...) -> x+strlen(x) -- if (Func == LibFunc::stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) { -+ if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) { - Value *StrLen = emitStrLen(Src, B, DL, TLI); - return StrLen ? B.CreateInBoundsGEP(B.getInt8Ty(), Dst, StrLen) : nullptr; - } -@@ -2276,14 +2276,14 @@ Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI, - Value *Ret = emitMemCpyChk(Dst, Src, LenV, ObjSize, B, DL, TLI); - // If the function was an __stpcpy_chk, and we were able to fold it into - // a __memcpy_chk, we still need to return the correct end pointer. -- if (Ret && Func == LibFunc::stpcpy_chk) -+ if (Ret && Func == LibFunc_stpcpy_chk) - return B.CreateGEP(B.getInt8Ty(), Dst, ConstantInt::get(SizeTTy, Len - 1)); - return Ret; - } - - Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(CallInst *CI, - IRBuilder<> &B, -- LibFunc::Func Func) { -+ LibFunc Func) { - Function *Callee = CI->getCalledFunction(); - StringRef Name = Callee->getName(); - if (isFortifiedCallFoldable(CI, 3, 2, false)) { -@@ -2308,7 +2308,7 @@ Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI) { - // - // PR23093. - -- LibFunc::Func Func; -+ LibFunc Func; - Function *Callee = CI->getCalledFunction(); - - SmallVector OpBundles; -@@ -2326,17 +2326,17 @@ Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI) { - return nullptr; - - switch (Func) { -- case LibFunc::memcpy_chk: -+ case LibFunc_memcpy_chk: - return optimizeMemCpyChk(CI, Builder); -- case LibFunc::memmove_chk: -+ case LibFunc_memmove_chk: - return optimizeMemMoveChk(CI, Builder); -- case LibFunc::memset_chk: -+ case LibFunc_memset_chk: - return optimizeMemSetChk(CI, Builder); -- case LibFunc::stpcpy_chk: -- case LibFunc::strcpy_chk: -+ case LibFunc_stpcpy_chk: -+ case LibFunc_strcpy_chk: - return optimizeStrpCpyChk(CI, Builder, Func); -- case LibFunc::stpncpy_chk: -- case LibFunc::strncpy_chk: -+ case LibFunc_stpncpy_chk: -+ case LibFunc_strncpy_chk: - return optimizeStrpNCpyChk(CI, Builder, Func); - default: - break; diff --git a/deps/patches/llvm-D28476-musl-targetlibraryinfo_4.0.patch b/deps/patches/llvm-D28476-musl-targetlibraryinfo_4.0.patch deleted file mode 100644 index 96da9b768d134..0000000000000 --- a/deps/patches/llvm-D28476-musl-targetlibraryinfo_4.0.patch +++ /dev/null @@ -1,4480 +0,0 @@ -commit fb2d72885243ce2c1c4b7db559d1ae72fa85b792 -Author: David L. Jones -Date: Mon Jan 23 23:16:46 2017 +0000 - - [Analysis] Add LibFunc_ prefix to enums in TargetLibraryInfo. (NFC) - - Summary: - The LibFunc::Func enum holds enumerators named for libc functions. - Unfortunately, there are real situations, including libc implementations, where - function names are actually macros (musl uses "#define fopen64 fopen", for - example; any other transitively visible macro would have similar effects). - - Strictly speaking, a conforming C++ Standard Library should provide any such - macros as functions instead (via ). However, there are some "library" - functions which are not part of the standard, and thus not subject to this - rule (fopen64, for example). So, in order to be both portable and consistent, - the enum should not use the bare function names. - - The old enum naming used a namespace LibFunc and an enum Func, with bare - enumerators. This patch changes LibFunc to be an enum with enumerators prefixed - with "LibFFunc_". (Unfortunately, a scoped enum is not sufficient to override - macros.) - - There are additional changes required in clang. - - Reviewers: rsmith - - Subscribers: mehdi_amini, mzolotukhin, nemanjai, llvm-commits - - Differential Revision: https://reviews.llvm.org/D28476 - - git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292848 91177308-0d34-0410-b5e6-96231b3b80d8 - -diff --git a/include/llvm/Analysis/TargetLibraryInfo.def b/include/llvm/Analysis/TargetLibraryInfo.def -index 5d5e5b127e6..637fc7ed30d 100644 ---- a/include/llvm/Analysis/TargetLibraryInfo.def -+++ b/include/llvm/Analysis/TargetLibraryInfo.def -@@ -20,7 +20,7 @@ - // One of TLI_DEFINE_ENUM/STRING are defined. - - #if defined(TLI_DEFINE_ENUM) --#define TLI_DEFINE_ENUM_INTERNAL(enum_variant) enum_variant, -+#define TLI_DEFINE_ENUM_INTERNAL(enum_variant) LibFunc_##enum_variant, - #define TLI_DEFINE_STRING_INTERNAL(string_repr) - #else - #define TLI_DEFINE_ENUM_INTERNAL(enum_variant) -diff --git a/include/llvm/Analysis/TargetLibraryInfo.h b/include/llvm/Analysis/TargetLibraryInfo.h -index 8675882431d..944250cfd6a 100644 ---- a/include/llvm/Analysis/TargetLibraryInfo.h -+++ b/include/llvm/Analysis/TargetLibraryInfo.h -@@ -30,14 +30,12 @@ struct VecDesc { - unsigned VectorizationFactor; - }; - -- namespace LibFunc { -- enum Func { -+ enum LibFunc { - #define TLI_DEFINE_ENUM - #include "llvm/Analysis/TargetLibraryInfo.def" - -- NumLibFuncs -- }; -- } -+ NumLibFuncs -+ }; - - /// Implementation of the target library information. - /// -@@ -48,9 +46,9 @@ struct VecDesc { - class TargetLibraryInfoImpl { - friend class TargetLibraryInfo; - -- unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4]; -+ unsigned char AvailableArray[(NumLibFuncs+3)/4]; - llvm::DenseMap CustomNames; -- static StringRef const StandardNames[LibFunc::NumLibFuncs]; -+ static StringRef const StandardNames[NumLibFuncs]; - bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param; - - enum AvailabilityState { -@@ -58,11 +56,11 @@ class TargetLibraryInfoImpl { - CustomName = 1, - Unavailable = 0 // (memset to all zeros) - }; -- void setState(LibFunc::Func F, AvailabilityState State) { -+ void setState(LibFunc F, AvailabilityState State) { - AvailableArray[F/4] &= ~(3 << 2*(F&3)); - AvailableArray[F/4] |= State << 2*(F&3); - } -- AvailabilityState getState(LibFunc::Func F) const { -+ AvailabilityState getState(LibFunc F) const { - return static_cast((AvailableArray[F/4] >> 2*(F&3)) & 3); - } - -@@ -74,7 +72,7 @@ class TargetLibraryInfoImpl { - - /// Return true if the function type FTy is valid for the library function - /// F, regardless of whether the function is available. -- bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc::Func F, -+ bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, - const DataLayout *DL) const; - - public: -@@ -104,28 +102,28 @@ public: - /// - /// If it is one of the known library functions, return true and set F to the - /// corresponding value. -- bool getLibFunc(StringRef funcName, LibFunc::Func &F) const; -+ bool getLibFunc(StringRef funcName, LibFunc &F) const; - - /// Searches for a particular function name, also checking that its type is - /// valid for the library function matching that name. - /// - /// If it is one of the known library functions, return true and set F to the - /// corresponding value. -- bool getLibFunc(const Function &FDecl, LibFunc::Func &F) const; -+ bool getLibFunc(const Function &FDecl, LibFunc &F) const; - - /// Forces a function to be marked as unavailable. -- void setUnavailable(LibFunc::Func F) { -+ void setUnavailable(LibFunc F) { - setState(F, Unavailable); - } - - /// Forces a function to be marked as available. -- void setAvailable(LibFunc::Func F) { -+ void setAvailable(LibFunc F) { - setState(F, StandardName); - } - - /// Forces a function to be marked as available and provide an alternate name - /// that must be used. -- void setAvailableWithName(LibFunc::Func F, StringRef Name) { -+ void setAvailableWithName(LibFunc F, StringRef Name) { - if (StandardNames[F] != Name) { - setState(F, CustomName); - CustomNames[F] = Name; -@@ -225,16 +223,16 @@ public: - /// - /// If it is one of the known library functions, return true and set F to the - /// corresponding value. -- bool getLibFunc(StringRef funcName, LibFunc::Func &F) const { -+ bool getLibFunc(StringRef funcName, LibFunc &F) const { - return Impl->getLibFunc(funcName, F); - } - -- bool getLibFunc(const Function &FDecl, LibFunc::Func &F) const { -+ bool getLibFunc(const Function &FDecl, LibFunc &F) const { - return Impl->getLibFunc(FDecl, F); - } - - /// Tests whether a library function is available. -- bool has(LibFunc::Func F) const { -+ bool has(LibFunc F) const { - return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable; - } - bool isFunctionVectorizable(StringRef F, unsigned VF) const { -@@ -249,37 +247,37 @@ public: - - /// Tests if the function is both available and a candidate for optimized code - /// generation. -- bool hasOptimizedCodeGen(LibFunc::Func F) const { -+ bool hasOptimizedCodeGen(LibFunc F) const { - if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable) - return false; - switch (F) { - default: break; -- case LibFunc::copysign: case LibFunc::copysignf: case LibFunc::copysignl: -- case LibFunc::fabs: case LibFunc::fabsf: case LibFunc::fabsl: -- case LibFunc::sin: case LibFunc::sinf: case LibFunc::sinl: -- case LibFunc::cos: case LibFunc::cosf: case LibFunc::cosl: -- case LibFunc::sqrt: case LibFunc::sqrtf: case LibFunc::sqrtl: -- case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite: -- case LibFunc::sqrtl_finite: -- case LibFunc::fmax: case LibFunc::fmaxf: case LibFunc::fmaxl: -- case LibFunc::fmin: case LibFunc::fminf: case LibFunc::fminl: -- case LibFunc::floor: case LibFunc::floorf: case LibFunc::floorl: -- case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl: -- case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill: -- case LibFunc::rint: case LibFunc::rintf: case LibFunc::rintl: -- case LibFunc::round: case LibFunc::roundf: case LibFunc::roundl: -- case LibFunc::trunc: case LibFunc::truncf: case LibFunc::truncl: -- case LibFunc::log2: case LibFunc::log2f: case LibFunc::log2l: -- case LibFunc::exp2: case LibFunc::exp2f: case LibFunc::exp2l: -- case LibFunc::memcmp: case LibFunc::strcmp: case LibFunc::strcpy: -- case LibFunc::stpcpy: case LibFunc::strlen: case LibFunc::strnlen: -- case LibFunc::memchr: case LibFunc::mempcpy: -+ case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl: -+ case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl: -+ case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl: -+ case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl: -+ case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl: -+ case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite: -+ case LibFunc_sqrtl_finite: -+ case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl: -+ case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl: -+ case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl: -+ case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl: -+ case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill: -+ case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl: -+ case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl: -+ case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl: -+ case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l: -+ case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l: -+ case LibFunc_memcmp: case LibFunc_strcmp: case LibFunc_strcpy: -+ case LibFunc_stpcpy: case LibFunc_strlen: case LibFunc_strnlen: -+ case LibFunc_memchr: case LibFunc_mempcpy: - return true; - } - return false; - } - -- StringRef getName(LibFunc::Func F) const { -+ StringRef getName(LibFunc F) const { - auto State = Impl->getState(F); - if (State == TargetLibraryInfoImpl::Unavailable) - return StringRef(); -diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h -index 5e217adf198..fbeea5bd95e 100644 ---- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h -+++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h -@@ -56,8 +56,8 @@ private: - Value *optimizeMemSetChk(CallInst *CI, IRBuilder<> &B); - - // Str/Stp cpy are similar enough to be handled in the same functions. -- Value *optimizeStrpCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc::Func Func); -- Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc::Func Func); -+ Value *optimizeStrpCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc Func); -+ Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc Func); - - /// \brief Checks whether the call \p CI to a fortified libcall is foldable - /// to the non-fortified version. -diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp -index c8d05794949..55f40a34839 100644 ---- a/lib/Analysis/BasicAliasAnalysis.cpp -+++ b/lib/Analysis/BasicAliasAnalysis.cpp -@@ -644,9 +644,9 @@ static bool isWriteOnlyParam(ImmutableCallSite CS, unsigned ArgIdx, - // whenever possible. - // FIXME Consider handling this in InferFunctionAttr.cpp together with other - // attributes. -- LibFunc::Func F; -+ LibFunc F; - if (CS.getCalledFunction() && TLI.getLibFunc(*CS.getCalledFunction(), F) && -- F == LibFunc::memset_pattern16 && TLI.has(F)) -+ F == LibFunc_memset_pattern16 && TLI.has(F)) - if (ArgIdx == 0) - return true; - -diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp -index 73867279abe..1bd51f62a43 100644 ---- a/lib/Analysis/ConstantFolding.cpp -+++ b/lib/Analysis/ConstantFolding.cpp -@@ -1637,51 +1637,51 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty, - - switch (Name[0]) { - case 'a': -- if ((Name == "acos" && TLI->has(LibFunc::acos)) || -- (Name == "acosf" && TLI->has(LibFunc::acosf))) -+ if ((Name == "acos" && TLI->has(LibFunc_acos)) || -+ (Name == "acosf" && TLI->has(LibFunc_acosf))) - return ConstantFoldFP(acos, V, Ty); -- else if ((Name == "asin" && TLI->has(LibFunc::asin)) || -- (Name == "asinf" && TLI->has(LibFunc::asinf))) -+ else if ((Name == "asin" && TLI->has(LibFunc_asin)) || -+ (Name == "asinf" && TLI->has(LibFunc_asinf))) - return ConstantFoldFP(asin, V, Ty); -- else if ((Name == "atan" && TLI->has(LibFunc::atan)) || -- (Name == "atanf" && TLI->has(LibFunc::atanf))) -+ else if ((Name == "atan" && TLI->has(LibFunc_atan)) || -+ (Name == "atanf" && TLI->has(LibFunc_atanf))) - return ConstantFoldFP(atan, V, Ty); - break; - case 'c': -- if ((Name == "ceil" && TLI->has(LibFunc::ceil)) || -- (Name == "ceilf" && TLI->has(LibFunc::ceilf))) -+ if ((Name == "ceil" && TLI->has(LibFunc_ceil)) || -+ (Name == "ceilf" && TLI->has(LibFunc_ceilf))) - return ConstantFoldFP(ceil, V, Ty); -- else if ((Name == "cos" && TLI->has(LibFunc::cos)) || -- (Name == "cosf" && TLI->has(LibFunc::cosf))) -+ else if ((Name == "cos" && TLI->has(LibFunc_cos)) || -+ (Name == "cosf" && TLI->has(LibFunc_cosf))) - return ConstantFoldFP(cos, V, Ty); -- else if ((Name == "cosh" && TLI->has(LibFunc::cosh)) || -- (Name == "coshf" && TLI->has(LibFunc::coshf))) -+ else if ((Name == "cosh" && TLI->has(LibFunc_cosh)) || -+ (Name == "coshf" && TLI->has(LibFunc_coshf))) - return ConstantFoldFP(cosh, V, Ty); - break; - case 'e': -- if ((Name == "exp" && TLI->has(LibFunc::exp)) || -- (Name == "expf" && TLI->has(LibFunc::expf))) -+ if ((Name == "exp" && TLI->has(LibFunc_exp)) || -+ (Name == "expf" && TLI->has(LibFunc_expf))) - return ConstantFoldFP(exp, V, Ty); -- if ((Name == "exp2" && TLI->has(LibFunc::exp2)) || -- (Name == "exp2f" && TLI->has(LibFunc::exp2f))) -+ if ((Name == "exp2" && TLI->has(LibFunc_exp2)) || -+ (Name == "exp2f" && TLI->has(LibFunc_exp2f))) - // Constant fold exp2(x) as pow(2,x) in case the host doesn't have a - // C99 library. - return ConstantFoldBinaryFP(pow, 2.0, V, Ty); - break; - case 'f': -- if ((Name == "fabs" && TLI->has(LibFunc::fabs)) || -- (Name == "fabsf" && TLI->has(LibFunc::fabsf))) -+ if ((Name == "fabs" && TLI->has(LibFunc_fabs)) || -+ (Name == "fabsf" && TLI->has(LibFunc_fabsf))) - return ConstantFoldFP(fabs, V, Ty); -- else if ((Name == "floor" && TLI->has(LibFunc::floor)) || -- (Name == "floorf" && TLI->has(LibFunc::floorf))) -+ else if ((Name == "floor" && TLI->has(LibFunc_floor)) || -+ (Name == "floorf" && TLI->has(LibFunc_floorf))) - return ConstantFoldFP(floor, V, Ty); - break; - case 'l': -- if ((Name == "log" && V > 0 && TLI->has(LibFunc::log)) || -- (Name == "logf" && V > 0 && TLI->has(LibFunc::logf))) -+ if ((Name == "log" && V > 0 && TLI->has(LibFunc_log)) || -+ (Name == "logf" && V > 0 && TLI->has(LibFunc_logf))) - return ConstantFoldFP(log, V, Ty); -- else if ((Name == "log10" && V > 0 && TLI->has(LibFunc::log10)) || -- (Name == "log10f" && V > 0 && TLI->has(LibFunc::log10f))) -+ else if ((Name == "log10" && V > 0 && TLI->has(LibFunc_log10)) || -+ (Name == "log10f" && V > 0 && TLI->has(LibFunc_log10f))) - return ConstantFoldFP(log10, V, Ty); - else if (IntrinsicID == Intrinsic::sqrt && - (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy())) { -@@ -1698,26 +1698,26 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty, - } - break; - case 'r': -- if ((Name == "round" && TLI->has(LibFunc::round)) || -- (Name == "roundf" && TLI->has(LibFunc::roundf))) -+ if ((Name == "round" && TLI->has(LibFunc_round)) || -+ (Name == "roundf" && TLI->has(LibFunc_roundf))) - return ConstantFoldFP(round, V, Ty); - case 's': -- if ((Name == "sin" && TLI->has(LibFunc::sin)) || -- (Name == "sinf" && TLI->has(LibFunc::sinf))) -+ if ((Name == "sin" && TLI->has(LibFunc_sin)) || -+ (Name == "sinf" && TLI->has(LibFunc_sinf))) - return ConstantFoldFP(sin, V, Ty); -- else if ((Name == "sinh" && TLI->has(LibFunc::sinh)) || -- (Name == "sinhf" && TLI->has(LibFunc::sinhf))) -+ else if ((Name == "sinh" && TLI->has(LibFunc_sinh)) || -+ (Name == "sinhf" && TLI->has(LibFunc_sinhf))) - return ConstantFoldFP(sinh, V, Ty); -- else if ((Name == "sqrt" && V >= 0 && TLI->has(LibFunc::sqrt)) || -- (Name == "sqrtf" && V >= 0 && TLI->has(LibFunc::sqrtf))) -+ else if ((Name == "sqrt" && V >= 0 && TLI->has(LibFunc_sqrt)) || -+ (Name == "sqrtf" && V >= 0 && TLI->has(LibFunc_sqrtf))) - return ConstantFoldFP(sqrt, V, Ty); - break; - case 't': -- if ((Name == "tan" && TLI->has(LibFunc::tan)) || -- (Name == "tanf" && TLI->has(LibFunc::tanf))) -+ if ((Name == "tan" && TLI->has(LibFunc_tan)) || -+ (Name == "tanf" && TLI->has(LibFunc_tanf))) - return ConstantFoldFP(tan, V, Ty); -- else if ((Name == "tanh" && TLI->has(LibFunc::tanh)) || -- (Name == "tanhf" && TLI->has(LibFunc::tanhf))) -+ else if ((Name == "tanh" && TLI->has(LibFunc_tanh)) || -+ (Name == "tanhf" && TLI->has(LibFunc_tanhf))) - return ConstantFoldFP(tanh, V, Ty); - break; - default: -@@ -1822,14 +1822,14 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty, - - if (!TLI) - return nullptr; -- if ((Name == "pow" && TLI->has(LibFunc::pow)) || -- (Name == "powf" && TLI->has(LibFunc::powf))) -+ if ((Name == "pow" && TLI->has(LibFunc_pow)) || -+ (Name == "powf" && TLI->has(LibFunc_powf))) - return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty); -- if ((Name == "fmod" && TLI->has(LibFunc::fmod)) || -- (Name == "fmodf" && TLI->has(LibFunc::fmodf))) -+ if ((Name == "fmod" && TLI->has(LibFunc_fmod)) || -+ (Name == "fmodf" && TLI->has(LibFunc_fmodf))) - return ConstantFoldBinaryFP(fmod, Op1V, Op2V, Ty); -- if ((Name == "atan2" && TLI->has(LibFunc::atan2)) || -- (Name == "atan2f" && TLI->has(LibFunc::atan2f))) -+ if ((Name == "atan2" && TLI->has(LibFunc_atan2)) || -+ (Name == "atan2f" && TLI->has(LibFunc_atan2f))) - return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty); - } else if (auto *Op2C = dyn_cast(Operands[1])) { - if (IntrinsicID == Intrinsic::powi && Ty->isHalfTy()) -@@ -2022,7 +2022,7 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) { - if (!F) - return false; - -- LibFunc::Func Func; -+ LibFunc Func; - if (!TLI || !TLI->getLibFunc(*F, Func)) - return false; - -@@ -2030,20 +2030,20 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) { - if (ConstantFP *OpC = dyn_cast(CS.getArgOperand(0))) { - const APFloat &Op = OpC->getValueAPF(); - switch (Func) { -- case LibFunc::logl: -- case LibFunc::log: -- case LibFunc::logf: -- case LibFunc::log2l: -- case LibFunc::log2: -- case LibFunc::log2f: -- case LibFunc::log10l: -- case LibFunc::log10: -- case LibFunc::log10f: -+ case LibFunc_logl: -+ case LibFunc_log: -+ case LibFunc_logf: -+ case LibFunc_log2l: -+ case LibFunc_log2: -+ case LibFunc_log2f: -+ case LibFunc_log10l: -+ case LibFunc_log10: -+ case LibFunc_log10f: - return Op.isNaN() || (!Op.isZero() && !Op.isNegative()); - -- case LibFunc::expl: -- case LibFunc::exp: -- case LibFunc::expf: -+ case LibFunc_expl: -+ case LibFunc_exp: -+ case LibFunc_expf: - // FIXME: These boundaries are slightly conservative. - if (OpC->getType()->isDoubleTy()) - return Op.compare(APFloat(-745.0)) != APFloat::cmpLessThan && -@@ -2053,9 +2053,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) { - Op.compare(APFloat(88.0f)) != APFloat::cmpGreaterThan; - break; - -- case LibFunc::exp2l: -- case LibFunc::exp2: -- case LibFunc::exp2f: -+ case LibFunc_exp2l: -+ case LibFunc_exp2: -+ case LibFunc_exp2f: - // FIXME: These boundaries are slightly conservative. - if (OpC->getType()->isDoubleTy()) - return Op.compare(APFloat(-1074.0)) != APFloat::cmpLessThan && -@@ -2065,17 +2065,17 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) { - Op.compare(APFloat(127.0f)) != APFloat::cmpGreaterThan; - break; - -- case LibFunc::sinl: -- case LibFunc::sin: -- case LibFunc::sinf: -- case LibFunc::cosl: -- case LibFunc::cos: -- case LibFunc::cosf: -+ case LibFunc_sinl: -+ case LibFunc_sin: -+ case LibFunc_sinf: -+ case LibFunc_cosl: -+ case LibFunc_cos: -+ case LibFunc_cosf: - return !Op.isInfinity(); - -- case LibFunc::tanl: -- case LibFunc::tan: -- case LibFunc::tanf: { -+ case LibFunc_tanl: -+ case LibFunc_tan: -+ case LibFunc_tanf: { - // FIXME: Stop using the host math library. - // FIXME: The computation isn't done in the right precision. - Type *Ty = OpC->getType(); -@@ -2086,23 +2086,23 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) { - break; - } - -- case LibFunc::asinl: -- case LibFunc::asin: -- case LibFunc::asinf: -- case LibFunc::acosl: -- case LibFunc::acos: -- case LibFunc::acosf: -+ case LibFunc_asinl: -+ case LibFunc_asin: -+ case LibFunc_asinf: -+ case LibFunc_acosl: -+ case LibFunc_acos: -+ case LibFunc_acosf: - return Op.compare(APFloat(Op.getSemantics(), "-1")) != - APFloat::cmpLessThan && - Op.compare(APFloat(Op.getSemantics(), "1")) != - APFloat::cmpGreaterThan; - -- case LibFunc::sinh: -- case LibFunc::cosh: -- case LibFunc::sinhf: -- case LibFunc::coshf: -- case LibFunc::sinhl: -- case LibFunc::coshl: -+ case LibFunc_sinh: -+ case LibFunc_cosh: -+ case LibFunc_sinhf: -+ case LibFunc_coshf: -+ case LibFunc_sinhl: -+ case LibFunc_coshl: - // FIXME: These boundaries are slightly conservative. - if (OpC->getType()->isDoubleTy()) - return Op.compare(APFloat(-710.0)) != APFloat::cmpLessThan && -@@ -2112,9 +2112,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) { - Op.compare(APFloat(89.0f)) != APFloat::cmpGreaterThan; - break; - -- case LibFunc::sqrtl: -- case LibFunc::sqrt: -- case LibFunc::sqrtf: -+ case LibFunc_sqrtl: -+ case LibFunc_sqrt: -+ case LibFunc_sqrtf: - return Op.isNaN() || Op.isZero() || !Op.isNegative(); - - // FIXME: Add more functions: sqrt_finite, atanh, expm1, log1p, -@@ -2133,9 +2133,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) { - const APFloat &Op1 = Op1C->getValueAPF(); - - switch (Func) { -- case LibFunc::powl: -- case LibFunc::pow: -- case LibFunc::powf: { -+ case LibFunc_powl: -+ case LibFunc_pow: -+ case LibFunc_powf: { - // FIXME: Stop using the host math library. - // FIXME: The computation isn't done in the right precision. - Type *Ty = Op0C->getType(); -@@ -2149,9 +2149,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) { - break; - } - -- case LibFunc::fmodl: -- case LibFunc::fmod: -- case LibFunc::fmodf: -+ case LibFunc_fmodl: -+ case LibFunc_fmod: -+ case LibFunc_fmodf: - return Op0.isNaN() || Op1.isNaN() || - (!Op0.isInfinity() && !Op1.isZero()); - -diff --git a/lib/Analysis/MemoryBuiltins.cpp b/lib/Analysis/MemoryBuiltins.cpp -index 2d8274040d3..e9d27b5e367 100644 ---- a/lib/Analysis/MemoryBuiltins.cpp -+++ b/lib/Analysis/MemoryBuiltins.cpp -@@ -50,30 +50,30 @@ struct AllocFnsTy { - - // FIXME: certain users need more information. E.g., SimplifyLibCalls needs to - // know which functions are nounwind, noalias, nocapture parameters, etc. --static const std::pair AllocationFnData[] = { -- {LibFunc::malloc, {MallocLike, 1, 0, -1}}, -- {LibFunc::valloc, {MallocLike, 1, 0, -1}}, -- {LibFunc::Znwj, {OpNewLike, 1, 0, -1}}, // new(unsigned int) -- {LibFunc::ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow) -- {LibFunc::Znwm, {OpNewLike, 1, 0, -1}}, // new(unsigned long) -- {LibFunc::ZnwmRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned long, nothrow) -- {LibFunc::Znaj, {OpNewLike, 1, 0, -1}}, // new[](unsigned int) -- {LibFunc::ZnajRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow) -- {LibFunc::Znam, {OpNewLike, 1, 0, -1}}, // new[](unsigned long) -- {LibFunc::ZnamRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned long, nothrow) -- {LibFunc::msvc_new_int, {OpNewLike, 1, 0, -1}}, // new(unsigned int) -- {LibFunc::msvc_new_int_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow) -- {LibFunc::msvc_new_longlong, {OpNewLike, 1, 0, -1}}, // new(unsigned long long) -- {LibFunc::msvc_new_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned long long, nothrow) -- {LibFunc::msvc_new_array_int, {OpNewLike, 1, 0, -1}}, // new[](unsigned int) -- {LibFunc::msvc_new_array_int_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow) -- {LibFunc::msvc_new_array_longlong, {OpNewLike, 1, 0, -1}}, // new[](unsigned long long) -- {LibFunc::msvc_new_array_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned long long, nothrow) -- {LibFunc::calloc, {CallocLike, 2, 0, 1}}, -- {LibFunc::realloc, {ReallocLike, 2, 1, -1}}, -- {LibFunc::reallocf, {ReallocLike, 2, 1, -1}}, -- {LibFunc::strdup, {StrDupLike, 1, -1, -1}}, -- {LibFunc::strndup, {StrDupLike, 2, 1, -1}} -+static const std::pair AllocationFnData[] = { -+ {LibFunc_malloc, {MallocLike, 1, 0, -1}}, -+ {LibFunc_valloc, {MallocLike, 1, 0, -1}}, -+ {LibFunc_Znwj, {OpNewLike, 1, 0, -1}}, // new(unsigned int) -+ {LibFunc_ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow) -+ {LibFunc_Znwm, {OpNewLike, 1, 0, -1}}, // new(unsigned long) -+ {LibFunc_ZnwmRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned long, nothrow) -+ {LibFunc_Znaj, {OpNewLike, 1, 0, -1}}, // new[](unsigned int) -+ {LibFunc_ZnajRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow) -+ {LibFunc_Znam, {OpNewLike, 1, 0, -1}}, // new[](unsigned long) -+ {LibFunc_ZnamRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned long, nothrow) -+ {LibFunc_msvc_new_int, {OpNewLike, 1, 0, -1}}, // new(unsigned int) -+ {LibFunc_msvc_new_int_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow) -+ {LibFunc_msvc_new_longlong, {OpNewLike, 1, 0, -1}}, // new(unsigned long long) -+ {LibFunc_msvc_new_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned long long, nothrow) -+ {LibFunc_msvc_new_array_int, {OpNewLike, 1, 0, -1}}, // new[](unsigned int) -+ {LibFunc_msvc_new_array_int_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow) -+ {LibFunc_msvc_new_array_longlong, {OpNewLike, 1, 0, -1}}, // new[](unsigned long long) -+ {LibFunc_msvc_new_array_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned long long, nothrow) -+ {LibFunc_calloc, {CallocLike, 2, 0, 1}}, -+ {LibFunc_realloc, {ReallocLike, 2, 1, -1}}, -+ {LibFunc_reallocf, {ReallocLike, 2, 1, -1}}, -+ {LibFunc_strdup, {StrDupLike, 1, -1, -1}}, -+ {LibFunc_strndup, {StrDupLike, 2, 1, -1}} - // TODO: Handle "int posix_memalign(void **, size_t, size_t)" - }; - -@@ -106,12 +106,12 @@ getAllocationDataForFunction(const Function *Callee, AllocType AllocTy, - const TargetLibraryInfo *TLI) { - // Make sure that the function is available. - StringRef FnName = Callee->getName(); -- LibFunc::Func TLIFn; -+ LibFunc TLIFn; - if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn)) - return None; - - const auto *Iter = find_if( -- AllocationFnData, [TLIFn](const std::pair &P) { -+ AllocationFnData, [TLIFn](const std::pair &P) { - return P.first == TLIFn; - }); - -@@ -333,33 +333,33 @@ const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) { - return nullptr; - - StringRef FnName = Callee->getName(); -- LibFunc::Func TLIFn; -+ LibFunc TLIFn; - if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn)) - return nullptr; - - unsigned ExpectedNumParams; -- if (TLIFn == LibFunc::free || -- TLIFn == LibFunc::ZdlPv || // operator delete(void*) -- TLIFn == LibFunc::ZdaPv || // operator delete[](void*) -- TLIFn == LibFunc::msvc_delete_ptr32 || // operator delete(void*) -- TLIFn == LibFunc::msvc_delete_ptr64 || // operator delete(void*) -- TLIFn == LibFunc::msvc_delete_array_ptr32 || // operator delete[](void*) -- TLIFn == LibFunc::msvc_delete_array_ptr64) // operator delete[](void*) -+ if (TLIFn == LibFunc_free || -+ TLIFn == LibFunc_ZdlPv || // operator delete(void*) -+ TLIFn == LibFunc_ZdaPv || // operator delete[](void*) -+ TLIFn == LibFunc_msvc_delete_ptr32 || // operator delete(void*) -+ TLIFn == LibFunc_msvc_delete_ptr64 || // operator delete(void*) -+ TLIFn == LibFunc_msvc_delete_array_ptr32 || // operator delete[](void*) -+ TLIFn == LibFunc_msvc_delete_array_ptr64) // operator delete[](void*) - ExpectedNumParams = 1; -- else if (TLIFn == LibFunc::ZdlPvj || // delete(void*, uint) -- TLIFn == LibFunc::ZdlPvm || // delete(void*, ulong) -- TLIFn == LibFunc::ZdlPvRKSt9nothrow_t || // delete(void*, nothrow) -- TLIFn == LibFunc::ZdaPvj || // delete[](void*, uint) -- TLIFn == LibFunc::ZdaPvm || // delete[](void*, ulong) -- TLIFn == LibFunc::ZdaPvRKSt9nothrow_t || // delete[](void*, nothrow) -- TLIFn == LibFunc::msvc_delete_ptr32_int || // delete(void*, uint) -- TLIFn == LibFunc::msvc_delete_ptr64_longlong || // delete(void*, ulonglong) -- TLIFn == LibFunc::msvc_delete_ptr32_nothrow || // delete(void*, nothrow) -- TLIFn == LibFunc::msvc_delete_ptr64_nothrow || // delete(void*, nothrow) -- TLIFn == LibFunc::msvc_delete_array_ptr32_int || // delete[](void*, uint) -- TLIFn == LibFunc::msvc_delete_array_ptr64_longlong || // delete[](void*, ulonglong) -- TLIFn == LibFunc::msvc_delete_array_ptr32_nothrow || // delete[](void*, nothrow) -- TLIFn == LibFunc::msvc_delete_array_ptr64_nothrow) // delete[](void*, nothrow) -+ else if (TLIFn == LibFunc_ZdlPvj || // delete(void*, uint) -+ TLIFn == LibFunc_ZdlPvm || // delete(void*, ulong) -+ TLIFn == LibFunc_ZdlPvRKSt9nothrow_t || // delete(void*, nothrow) -+ TLIFn == LibFunc_ZdaPvj || // delete[](void*, uint) -+ TLIFn == LibFunc_ZdaPvm || // delete[](void*, ulong) -+ TLIFn == LibFunc_ZdaPvRKSt9nothrow_t || // delete[](void*, nothrow) -+ TLIFn == LibFunc_msvc_delete_ptr32_int || // delete(void*, uint) -+ TLIFn == LibFunc_msvc_delete_ptr64_longlong || // delete(void*, ulonglong) -+ TLIFn == LibFunc_msvc_delete_ptr32_nothrow || // delete(void*, nothrow) -+ TLIFn == LibFunc_msvc_delete_ptr64_nothrow || // delete(void*, nothrow) -+ TLIFn == LibFunc_msvc_delete_array_ptr32_int || // delete[](void*, uint) -+ TLIFn == LibFunc_msvc_delete_array_ptr64_longlong || // delete[](void*, ulonglong) -+ TLIFn == LibFunc_msvc_delete_array_ptr32_nothrow || // delete[](void*, nothrow) -+ TLIFn == LibFunc_msvc_delete_array_ptr64_nothrow) // delete[](void*, nothrow) - ExpectedNumParams = 2; - else - return nullptr; -diff --git a/lib/Analysis/MemoryLocation.cpp b/lib/Analysis/MemoryLocation.cpp -index a0ae72f1415..9db6c499129 100644 ---- a/lib/Analysis/MemoryLocation.cpp -+++ b/lib/Analysis/MemoryLocation.cpp -@@ -142,9 +142,9 @@ MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS, - // for memcpy/memset. This is particularly important because the - // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 - // whenever possible. -- LibFunc::Func F; -+ LibFunc F; - if (CS.getCalledFunction() && TLI.getLibFunc(*CS.getCalledFunction(), F) && -- F == LibFunc::memset_pattern16 && TLI.has(F)) { -+ F == LibFunc_memset_pattern16 && TLI.has(F)) { - assert((ArgIdx == 0 || ArgIdx == 1) && - "Invalid argument index for memset_pattern16"); - if (ArgIdx == 1) -diff --git a/lib/Analysis/TargetLibraryInfo.cpp b/lib/Analysis/TargetLibraryInfo.cpp -index 450901aca7d..775abfd18c1 100644 ---- a/lib/Analysis/TargetLibraryInfo.cpp -+++ b/lib/Analysis/TargetLibraryInfo.cpp -@@ -82,24 +82,24 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - - if (T.getArch() == Triple::r600 || - T.getArch() == Triple::amdgcn) { -- TLI.setUnavailable(LibFunc::ldexp); -- TLI.setUnavailable(LibFunc::ldexpf); -- TLI.setUnavailable(LibFunc::ldexpl); -- TLI.setUnavailable(LibFunc::exp10); -- TLI.setUnavailable(LibFunc::exp10f); -- TLI.setUnavailable(LibFunc::exp10l); -- TLI.setUnavailable(LibFunc::log10); -- TLI.setUnavailable(LibFunc::log10f); -- TLI.setUnavailable(LibFunc::log10l); -+ TLI.setUnavailable(LibFunc_ldexp); -+ TLI.setUnavailable(LibFunc_ldexpf); -+ TLI.setUnavailable(LibFunc_ldexpl); -+ TLI.setUnavailable(LibFunc_exp10); -+ TLI.setUnavailable(LibFunc_exp10f); -+ TLI.setUnavailable(LibFunc_exp10l); -+ TLI.setUnavailable(LibFunc_log10); -+ TLI.setUnavailable(LibFunc_log10f); -+ TLI.setUnavailable(LibFunc_log10l); - } - - // There are no library implementations of mempcy and memset for AMD gpus and - // these can be difficult to lower in the backend. - if (T.getArch() == Triple::r600 || - T.getArch() == Triple::amdgcn) { -- TLI.setUnavailable(LibFunc::memcpy); -- TLI.setUnavailable(LibFunc::memset); -- TLI.setUnavailable(LibFunc::memset_pattern16); -+ TLI.setUnavailable(LibFunc_memcpy); -+ TLI.setUnavailable(LibFunc_memset); -+ TLI.setUnavailable(LibFunc_memset_pattern16); - return; - } - -@@ -107,21 +107,21 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // All versions of watchOS support it. - if (T.isMacOSX()) { - if (T.isMacOSXVersionLT(10, 5)) -- TLI.setUnavailable(LibFunc::memset_pattern16); -+ TLI.setUnavailable(LibFunc_memset_pattern16); - } else if (T.isiOS()) { - if (T.isOSVersionLT(3, 0)) -- TLI.setUnavailable(LibFunc::memset_pattern16); -+ TLI.setUnavailable(LibFunc_memset_pattern16); - } else if (!T.isWatchOS()) { -- TLI.setUnavailable(LibFunc::memset_pattern16); -+ TLI.setUnavailable(LibFunc_memset_pattern16); - } - - if (!hasSinCosPiStret(T)) { -- TLI.setUnavailable(LibFunc::sinpi); -- TLI.setUnavailable(LibFunc::sinpif); -- TLI.setUnavailable(LibFunc::cospi); -- TLI.setUnavailable(LibFunc::cospif); -- TLI.setUnavailable(LibFunc::sincospi_stret); -- TLI.setUnavailable(LibFunc::sincospif_stret); -+ TLI.setUnavailable(LibFunc_sinpi); -+ TLI.setUnavailable(LibFunc_sinpif); -+ TLI.setUnavailable(LibFunc_cospi); -+ TLI.setUnavailable(LibFunc_cospif); -+ TLI.setUnavailable(LibFunc_sincospi_stret); -+ TLI.setUnavailable(LibFunc_sincospif_stret); - } - - if (T.isMacOSX() && T.getArch() == Triple::x86 && -@@ -131,179 +131,179 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // has a $UNIX2003 suffix. The two implementations are identical except - // for the return value in some edge cases. However, we don't want to - // generate code that depends on the old symbols. -- TLI.setAvailableWithName(LibFunc::fwrite, "fwrite$UNIX2003"); -- TLI.setAvailableWithName(LibFunc::fputs, "fputs$UNIX2003"); -+ TLI.setAvailableWithName(LibFunc_fwrite, "fwrite$UNIX2003"); -+ TLI.setAvailableWithName(LibFunc_fputs, "fputs$UNIX2003"); - } - - // iprintf and friends are only available on XCore and TCE. - if (T.getArch() != Triple::xcore && T.getArch() != Triple::tce) { -- TLI.setUnavailable(LibFunc::iprintf); -- TLI.setUnavailable(LibFunc::siprintf); -- TLI.setUnavailable(LibFunc::fiprintf); -+ TLI.setUnavailable(LibFunc_iprintf); -+ TLI.setUnavailable(LibFunc_siprintf); -+ TLI.setUnavailable(LibFunc_fiprintf); - } - - if (T.isOSWindows() && !T.isOSCygMing()) { - // Win32 does not support long double -- TLI.setUnavailable(LibFunc::acosl); -- TLI.setUnavailable(LibFunc::asinl); -- TLI.setUnavailable(LibFunc::atanl); -- TLI.setUnavailable(LibFunc::atan2l); -- TLI.setUnavailable(LibFunc::ceill); -- TLI.setUnavailable(LibFunc::copysignl); -- TLI.setUnavailable(LibFunc::cosl); -- TLI.setUnavailable(LibFunc::coshl); -- TLI.setUnavailable(LibFunc::expl); -- TLI.setUnavailable(LibFunc::fabsf); // Win32 and Win64 both lack fabsf -- TLI.setUnavailable(LibFunc::fabsl); -- TLI.setUnavailable(LibFunc::floorl); -- TLI.setUnavailable(LibFunc::fmaxl); -- TLI.setUnavailable(LibFunc::fminl); -- TLI.setUnavailable(LibFunc::fmodl); -- TLI.setUnavailable(LibFunc::frexpl); -- TLI.setUnavailable(LibFunc::ldexpf); -- TLI.setUnavailable(LibFunc::ldexpl); -- TLI.setUnavailable(LibFunc::logl); -- TLI.setUnavailable(LibFunc::modfl); -- TLI.setUnavailable(LibFunc::powl); -- TLI.setUnavailable(LibFunc::sinl); -- TLI.setUnavailable(LibFunc::sinhl); -- TLI.setUnavailable(LibFunc::sqrtl); -- TLI.setUnavailable(LibFunc::tanl); -- TLI.setUnavailable(LibFunc::tanhl); -+ TLI.setUnavailable(LibFunc_acosl); -+ TLI.setUnavailable(LibFunc_asinl); -+ TLI.setUnavailable(LibFunc_atanl); -+ TLI.setUnavailable(LibFunc_atan2l); -+ TLI.setUnavailable(LibFunc_ceill); -+ TLI.setUnavailable(LibFunc_copysignl); -+ TLI.setUnavailable(LibFunc_cosl); -+ TLI.setUnavailable(LibFunc_coshl); -+ TLI.setUnavailable(LibFunc_expl); -+ TLI.setUnavailable(LibFunc_fabsf); // Win32 and Win64 both lack fabsf -+ TLI.setUnavailable(LibFunc_fabsl); -+ TLI.setUnavailable(LibFunc_floorl); -+ TLI.setUnavailable(LibFunc_fmaxl); -+ TLI.setUnavailable(LibFunc_fminl); -+ TLI.setUnavailable(LibFunc_fmodl); -+ TLI.setUnavailable(LibFunc_frexpl); -+ TLI.setUnavailable(LibFunc_ldexpf); -+ TLI.setUnavailable(LibFunc_ldexpl); -+ TLI.setUnavailable(LibFunc_logl); -+ TLI.setUnavailable(LibFunc_modfl); -+ TLI.setUnavailable(LibFunc_powl); -+ TLI.setUnavailable(LibFunc_sinl); -+ TLI.setUnavailable(LibFunc_sinhl); -+ TLI.setUnavailable(LibFunc_sqrtl); -+ TLI.setUnavailable(LibFunc_tanl); -+ TLI.setUnavailable(LibFunc_tanhl); - - // Win32 only has C89 math -- TLI.setUnavailable(LibFunc::acosh); -- TLI.setUnavailable(LibFunc::acoshf); -- TLI.setUnavailable(LibFunc::acoshl); -- TLI.setUnavailable(LibFunc::asinh); -- TLI.setUnavailable(LibFunc::asinhf); -- TLI.setUnavailable(LibFunc::asinhl); -- TLI.setUnavailable(LibFunc::atanh); -- TLI.setUnavailable(LibFunc::atanhf); -- TLI.setUnavailable(LibFunc::atanhl); -- TLI.setUnavailable(LibFunc::cbrt); -- TLI.setUnavailable(LibFunc::cbrtf); -- TLI.setUnavailable(LibFunc::cbrtl); -- TLI.setUnavailable(LibFunc::exp2); -- TLI.setUnavailable(LibFunc::exp2f); -- TLI.setUnavailable(LibFunc::exp2l); -- TLI.setUnavailable(LibFunc::expm1); -- TLI.setUnavailable(LibFunc::expm1f); -- TLI.setUnavailable(LibFunc::expm1l); -- TLI.setUnavailable(LibFunc::log2); -- TLI.setUnavailable(LibFunc::log2f); -- TLI.setUnavailable(LibFunc::log2l); -- TLI.setUnavailable(LibFunc::log1p); -- TLI.setUnavailable(LibFunc::log1pf); -- TLI.setUnavailable(LibFunc::log1pl); -- TLI.setUnavailable(LibFunc::logb); -- TLI.setUnavailable(LibFunc::logbf); -- TLI.setUnavailable(LibFunc::logbl); -- TLI.setUnavailable(LibFunc::nearbyint); -- TLI.setUnavailable(LibFunc::nearbyintf); -- TLI.setUnavailable(LibFunc::nearbyintl); -- TLI.setUnavailable(LibFunc::rint); -- TLI.setUnavailable(LibFunc::rintf); -- TLI.setUnavailable(LibFunc::rintl); -- TLI.setUnavailable(LibFunc::round); -- TLI.setUnavailable(LibFunc::roundf); -- TLI.setUnavailable(LibFunc::roundl); -- TLI.setUnavailable(LibFunc::trunc); -- TLI.setUnavailable(LibFunc::truncf); -- TLI.setUnavailable(LibFunc::truncl); -+ TLI.setUnavailable(LibFunc_acosh); -+ TLI.setUnavailable(LibFunc_acoshf); -+ TLI.setUnavailable(LibFunc_acoshl); -+ TLI.setUnavailable(LibFunc_asinh); -+ TLI.setUnavailable(LibFunc_asinhf); -+ TLI.setUnavailable(LibFunc_asinhl); -+ TLI.setUnavailable(LibFunc_atanh); -+ TLI.setUnavailable(LibFunc_atanhf); -+ TLI.setUnavailable(LibFunc_atanhl); -+ TLI.setUnavailable(LibFunc_cbrt); -+ TLI.setUnavailable(LibFunc_cbrtf); -+ TLI.setUnavailable(LibFunc_cbrtl); -+ TLI.setUnavailable(LibFunc_exp2); -+ TLI.setUnavailable(LibFunc_exp2f); -+ TLI.setUnavailable(LibFunc_exp2l); -+ TLI.setUnavailable(LibFunc_expm1); -+ TLI.setUnavailable(LibFunc_expm1f); -+ TLI.setUnavailable(LibFunc_expm1l); -+ TLI.setUnavailable(LibFunc_log2); -+ TLI.setUnavailable(LibFunc_log2f); -+ TLI.setUnavailable(LibFunc_log2l); -+ TLI.setUnavailable(LibFunc_log1p); -+ TLI.setUnavailable(LibFunc_log1pf); -+ TLI.setUnavailable(LibFunc_log1pl); -+ TLI.setUnavailable(LibFunc_logb); -+ TLI.setUnavailable(LibFunc_logbf); -+ TLI.setUnavailable(LibFunc_logbl); -+ TLI.setUnavailable(LibFunc_nearbyint); -+ TLI.setUnavailable(LibFunc_nearbyintf); -+ TLI.setUnavailable(LibFunc_nearbyintl); -+ TLI.setUnavailable(LibFunc_rint); -+ TLI.setUnavailable(LibFunc_rintf); -+ TLI.setUnavailable(LibFunc_rintl); -+ TLI.setUnavailable(LibFunc_round); -+ TLI.setUnavailable(LibFunc_roundf); -+ TLI.setUnavailable(LibFunc_roundl); -+ TLI.setUnavailable(LibFunc_trunc); -+ TLI.setUnavailable(LibFunc_truncf); -+ TLI.setUnavailable(LibFunc_truncl); - - // Win32 provides some C99 math with mangled names -- TLI.setAvailableWithName(LibFunc::copysign, "_copysign"); -+ TLI.setAvailableWithName(LibFunc_copysign, "_copysign"); - - if (T.getArch() == Triple::x86) { - // Win32 on x86 implements single-precision math functions as macros -- TLI.setUnavailable(LibFunc::acosf); -- TLI.setUnavailable(LibFunc::asinf); -- TLI.setUnavailable(LibFunc::atanf); -- TLI.setUnavailable(LibFunc::atan2f); -- TLI.setUnavailable(LibFunc::ceilf); -- TLI.setUnavailable(LibFunc::copysignf); -- TLI.setUnavailable(LibFunc::cosf); -- TLI.setUnavailable(LibFunc::coshf); -- TLI.setUnavailable(LibFunc::expf); -- TLI.setUnavailable(LibFunc::floorf); -- TLI.setUnavailable(LibFunc::fminf); -- TLI.setUnavailable(LibFunc::fmaxf); -- TLI.setUnavailable(LibFunc::fmodf); -- TLI.setUnavailable(LibFunc::logf); -- TLI.setUnavailable(LibFunc::log10f); -- TLI.setUnavailable(LibFunc::modff); -- TLI.setUnavailable(LibFunc::powf); -- TLI.setUnavailable(LibFunc::sinf); -- TLI.setUnavailable(LibFunc::sinhf); -- TLI.setUnavailable(LibFunc::sqrtf); -- TLI.setUnavailable(LibFunc::tanf); -- TLI.setUnavailable(LibFunc::tanhf); -+ TLI.setUnavailable(LibFunc_acosf); -+ TLI.setUnavailable(LibFunc_asinf); -+ TLI.setUnavailable(LibFunc_atanf); -+ TLI.setUnavailable(LibFunc_atan2f); -+ TLI.setUnavailable(LibFunc_ceilf); -+ TLI.setUnavailable(LibFunc_copysignf); -+ TLI.setUnavailable(LibFunc_cosf); -+ TLI.setUnavailable(LibFunc_coshf); -+ TLI.setUnavailable(LibFunc_expf); -+ TLI.setUnavailable(LibFunc_floorf); -+ TLI.setUnavailable(LibFunc_fminf); -+ TLI.setUnavailable(LibFunc_fmaxf); -+ TLI.setUnavailable(LibFunc_fmodf); -+ TLI.setUnavailable(LibFunc_logf); -+ TLI.setUnavailable(LibFunc_log10f); -+ TLI.setUnavailable(LibFunc_modff); -+ TLI.setUnavailable(LibFunc_powf); -+ TLI.setUnavailable(LibFunc_sinf); -+ TLI.setUnavailable(LibFunc_sinhf); -+ TLI.setUnavailable(LibFunc_sqrtf); -+ TLI.setUnavailable(LibFunc_tanf); -+ TLI.setUnavailable(LibFunc_tanhf); - } - - // Win32 does *not* provide provide these functions, but they are - // generally available on POSIX-compliant systems: -- TLI.setUnavailable(LibFunc::access); -- TLI.setUnavailable(LibFunc::bcmp); -- TLI.setUnavailable(LibFunc::bcopy); -- TLI.setUnavailable(LibFunc::bzero); -- TLI.setUnavailable(LibFunc::chmod); -- TLI.setUnavailable(LibFunc::chown); -- TLI.setUnavailable(LibFunc::closedir); -- TLI.setUnavailable(LibFunc::ctermid); -- TLI.setUnavailable(LibFunc::fdopen); -- TLI.setUnavailable(LibFunc::ffs); -- TLI.setUnavailable(LibFunc::fileno); -- TLI.setUnavailable(LibFunc::flockfile); -- TLI.setUnavailable(LibFunc::fseeko); -- TLI.setUnavailable(LibFunc::fstat); -- TLI.setUnavailable(LibFunc::fstatvfs); -- TLI.setUnavailable(LibFunc::ftello); -- TLI.setUnavailable(LibFunc::ftrylockfile); -- TLI.setUnavailable(LibFunc::funlockfile); -- TLI.setUnavailable(LibFunc::getc_unlocked); -- TLI.setUnavailable(LibFunc::getitimer); -- TLI.setUnavailable(LibFunc::getlogin_r); -- TLI.setUnavailable(LibFunc::getpwnam); -- TLI.setUnavailable(LibFunc::gettimeofday); -- TLI.setUnavailable(LibFunc::htonl); -- TLI.setUnavailable(LibFunc::htons); -- TLI.setUnavailable(LibFunc::lchown); -- TLI.setUnavailable(LibFunc::lstat); -- TLI.setUnavailable(LibFunc::memccpy); -- TLI.setUnavailable(LibFunc::mkdir); -- TLI.setUnavailable(LibFunc::ntohl); -- TLI.setUnavailable(LibFunc::ntohs); -- TLI.setUnavailable(LibFunc::open); -- TLI.setUnavailable(LibFunc::opendir); -- TLI.setUnavailable(LibFunc::pclose); -- TLI.setUnavailable(LibFunc::popen); -- TLI.setUnavailable(LibFunc::pread); -- TLI.setUnavailable(LibFunc::pwrite); -- TLI.setUnavailable(LibFunc::read); -- TLI.setUnavailable(LibFunc::readlink); -- TLI.setUnavailable(LibFunc::realpath); -- TLI.setUnavailable(LibFunc::rmdir); -- TLI.setUnavailable(LibFunc::setitimer); -- TLI.setUnavailable(LibFunc::stat); -- TLI.setUnavailable(LibFunc::statvfs); -- TLI.setUnavailable(LibFunc::stpcpy); -- TLI.setUnavailable(LibFunc::stpncpy); -- TLI.setUnavailable(LibFunc::strcasecmp); -- TLI.setUnavailable(LibFunc::strncasecmp); -- TLI.setUnavailable(LibFunc::times); -- TLI.setUnavailable(LibFunc::uname); -- TLI.setUnavailable(LibFunc::unlink); -- TLI.setUnavailable(LibFunc::unsetenv); -- TLI.setUnavailable(LibFunc::utime); -- TLI.setUnavailable(LibFunc::utimes); -- TLI.setUnavailable(LibFunc::write); -+ TLI.setUnavailable(LibFunc_access); -+ TLI.setUnavailable(LibFunc_bcmp); -+ TLI.setUnavailable(LibFunc_bcopy); -+ TLI.setUnavailable(LibFunc_bzero); -+ TLI.setUnavailable(LibFunc_chmod); -+ TLI.setUnavailable(LibFunc_chown); -+ TLI.setUnavailable(LibFunc_closedir); -+ TLI.setUnavailable(LibFunc_ctermid); -+ TLI.setUnavailable(LibFunc_fdopen); -+ TLI.setUnavailable(LibFunc_ffs); -+ TLI.setUnavailable(LibFunc_fileno); -+ TLI.setUnavailable(LibFunc_flockfile); -+ TLI.setUnavailable(LibFunc_fseeko); -+ TLI.setUnavailable(LibFunc_fstat); -+ TLI.setUnavailable(LibFunc_fstatvfs); -+ TLI.setUnavailable(LibFunc_ftello); -+ TLI.setUnavailable(LibFunc_ftrylockfile); -+ TLI.setUnavailable(LibFunc_funlockfile); -+ TLI.setUnavailable(LibFunc_getc_unlocked); -+ TLI.setUnavailable(LibFunc_getitimer); -+ TLI.setUnavailable(LibFunc_getlogin_r); -+ TLI.setUnavailable(LibFunc_getpwnam); -+ TLI.setUnavailable(LibFunc_gettimeofday); -+ TLI.setUnavailable(LibFunc_htonl); -+ TLI.setUnavailable(LibFunc_htons); -+ TLI.setUnavailable(LibFunc_lchown); -+ TLI.setUnavailable(LibFunc_lstat); -+ TLI.setUnavailable(LibFunc_memccpy); -+ TLI.setUnavailable(LibFunc_mkdir); -+ TLI.setUnavailable(LibFunc_ntohl); -+ TLI.setUnavailable(LibFunc_ntohs); -+ TLI.setUnavailable(LibFunc_open); -+ TLI.setUnavailable(LibFunc_opendir); -+ TLI.setUnavailable(LibFunc_pclose); -+ TLI.setUnavailable(LibFunc_popen); -+ TLI.setUnavailable(LibFunc_pread); -+ TLI.setUnavailable(LibFunc_pwrite); -+ TLI.setUnavailable(LibFunc_read); -+ TLI.setUnavailable(LibFunc_readlink); -+ TLI.setUnavailable(LibFunc_realpath); -+ TLI.setUnavailable(LibFunc_rmdir); -+ TLI.setUnavailable(LibFunc_setitimer); -+ TLI.setUnavailable(LibFunc_stat); -+ TLI.setUnavailable(LibFunc_statvfs); -+ TLI.setUnavailable(LibFunc_stpcpy); -+ TLI.setUnavailable(LibFunc_stpncpy); -+ TLI.setUnavailable(LibFunc_strcasecmp); -+ TLI.setUnavailable(LibFunc_strncasecmp); -+ TLI.setUnavailable(LibFunc_times); -+ TLI.setUnavailable(LibFunc_uname); -+ TLI.setUnavailable(LibFunc_unlink); -+ TLI.setUnavailable(LibFunc_unsetenv); -+ TLI.setUnavailable(LibFunc_utime); -+ TLI.setUnavailable(LibFunc_utimes); -+ TLI.setUnavailable(LibFunc_write); - - // Win32 does *not* provide provide these functions, but they are - // specified by C99: -- TLI.setUnavailable(LibFunc::atoll); -- TLI.setUnavailable(LibFunc::frexpf); -- TLI.setUnavailable(LibFunc::llabs); -+ TLI.setUnavailable(LibFunc_atoll); -+ TLI.setUnavailable(LibFunc_frexpf); -+ TLI.setUnavailable(LibFunc_llabs); - } - - switch (T.getOS()) { -@@ -311,28 +311,28 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // exp10 and exp10f are not available on OS X until 10.9 and iOS until 7.0 - // and their names are __exp10 and __exp10f. exp10l is not available on - // OS X or iOS. -- TLI.setUnavailable(LibFunc::exp10l); -+ TLI.setUnavailable(LibFunc_exp10l); - if (T.isMacOSXVersionLT(10, 9)) { -- TLI.setUnavailable(LibFunc::exp10); -- TLI.setUnavailable(LibFunc::exp10f); -+ TLI.setUnavailable(LibFunc_exp10); -+ TLI.setUnavailable(LibFunc_exp10f); - } else { -- TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); -- TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); -+ TLI.setAvailableWithName(LibFunc_exp10, "__exp10"); -+ TLI.setAvailableWithName(LibFunc_exp10f, "__exp10f"); - } - break; - case Triple::IOS: - case Triple::TvOS: - case Triple::WatchOS: -- TLI.setUnavailable(LibFunc::exp10l); -+ TLI.setUnavailable(LibFunc_exp10l); - if (!T.isWatchOS() && (T.isOSVersionLT(7, 0) || - (T.isOSVersionLT(9, 0) && - (T.getArch() == Triple::x86 || - T.getArch() == Triple::x86_64)))) { -- TLI.setUnavailable(LibFunc::exp10); -- TLI.setUnavailable(LibFunc::exp10f); -+ TLI.setUnavailable(LibFunc_exp10); -+ TLI.setUnavailable(LibFunc_exp10f); - } else { -- TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); -- TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); -+ TLI.setAvailableWithName(LibFunc_exp10, "__exp10"); -+ TLI.setAvailableWithName(LibFunc_exp10f, "__exp10f"); - } - break; - case Triple::Linux: -@@ -344,9 +344,9 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // Fall through to disable all of them. - LLVM_FALLTHROUGH; - default: -- TLI.setUnavailable(LibFunc::exp10); -- TLI.setUnavailable(LibFunc::exp10f); -- TLI.setUnavailable(LibFunc::exp10l); -+ TLI.setUnavailable(LibFunc_exp10); -+ TLI.setUnavailable(LibFunc_exp10f); -+ TLI.setUnavailable(LibFunc_exp10l); - } - - // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and -@@ -364,7 +364,7 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - case Triple::Linux: - break; - default: -- TLI.setUnavailable(LibFunc::ffsl); -+ TLI.setUnavailable(LibFunc_ffsl); - } - - // ffsll is available on at least FreeBSD and Linux (GLIBC): -@@ -380,7 +380,7 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - case Triple::Linux: - break; - default: -- TLI.setUnavailable(LibFunc::ffsll); -+ TLI.setUnavailable(LibFunc_ffsll); - } - - // The following functions are available on at least FreeBSD: -@@ -388,30 +388,30 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // http://svn.freebsd.org/base/head/lib/libc/string/flsl.c - // http://svn.freebsd.org/base/head/lib/libc/string/flsll.c - if (!T.isOSFreeBSD()) { -- TLI.setUnavailable(LibFunc::fls); -- TLI.setUnavailable(LibFunc::flsl); -- TLI.setUnavailable(LibFunc::flsll); -+ TLI.setUnavailable(LibFunc_fls); -+ TLI.setUnavailable(LibFunc_flsl); -+ TLI.setUnavailable(LibFunc_flsll); - } - - // The following functions are available on at least Linux: - if (!T.isOSLinux()) { -- TLI.setUnavailable(LibFunc::dunder_strdup); -- TLI.setUnavailable(LibFunc::dunder_strtok_r); -- TLI.setUnavailable(LibFunc::dunder_isoc99_scanf); -- TLI.setUnavailable(LibFunc::dunder_isoc99_sscanf); -- TLI.setUnavailable(LibFunc::under_IO_getc); -- TLI.setUnavailable(LibFunc::under_IO_putc); -- TLI.setUnavailable(LibFunc::memalign); -- TLI.setUnavailable(LibFunc::fopen64); -- TLI.setUnavailable(LibFunc::fseeko64); -- TLI.setUnavailable(LibFunc::fstat64); -- TLI.setUnavailable(LibFunc::fstatvfs64); -- TLI.setUnavailable(LibFunc::ftello64); -- TLI.setUnavailable(LibFunc::lstat64); -- TLI.setUnavailable(LibFunc::open64); -- TLI.setUnavailable(LibFunc::stat64); -- TLI.setUnavailable(LibFunc::statvfs64); -- TLI.setUnavailable(LibFunc::tmpfile64); -+ TLI.setUnavailable(LibFunc_dunder_strdup); -+ TLI.setUnavailable(LibFunc_dunder_strtok_r); -+ TLI.setUnavailable(LibFunc_dunder_isoc99_scanf); -+ TLI.setUnavailable(LibFunc_dunder_isoc99_sscanf); -+ TLI.setUnavailable(LibFunc_under_IO_getc); -+ TLI.setUnavailable(LibFunc_under_IO_putc); -+ TLI.setUnavailable(LibFunc_memalign); -+ TLI.setUnavailable(LibFunc_fopen64); -+ TLI.setUnavailable(LibFunc_fseeko64); -+ TLI.setUnavailable(LibFunc_fstat64); -+ TLI.setUnavailable(LibFunc_fstatvfs64); -+ TLI.setUnavailable(LibFunc_ftello64); -+ TLI.setUnavailable(LibFunc_lstat64); -+ TLI.setUnavailable(LibFunc_open64); -+ TLI.setUnavailable(LibFunc_stat64); -+ TLI.setUnavailable(LibFunc_statvfs64); -+ TLI.setUnavailable(LibFunc_tmpfile64); - } - - // As currently implemented in clang, NVPTX code has no standard library to -@@ -427,9 +427,9 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - // optimizations, so this situation should be fixed. - if (T.isNVPTX()) { - TLI.disableAllFunctions(); -- TLI.setAvailable(LibFunc::nvvm_reflect); -+ TLI.setAvailable(LibFunc_nvvm_reflect); - } else { -- TLI.setUnavailable(LibFunc::nvvm_reflect); -+ TLI.setUnavailable(LibFunc_nvvm_reflect); - } - - TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary); -@@ -500,9 +500,9 @@ static StringRef sanitizeFunctionName(StringRef funcName) { - } - - bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, -- LibFunc::Func &F) const { -+ LibFunc &F) const { - StringRef const *Start = &StandardNames[0]; -- StringRef const *End = &StandardNames[LibFunc::NumLibFuncs]; -+ StringRef const *End = &StandardNames[NumLibFuncs]; - - funcName = sanitizeFunctionName(funcName); - if (funcName.empty()) -@@ -513,14 +513,14 @@ bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, - return LHS < RHS; - }); - if (I != End && *I == funcName) { -- F = (LibFunc::Func)(I - Start); -+ F = (LibFunc)(I - Start); - return true; - } - return false; - } - - bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, -- LibFunc::Func F, -+ LibFunc F, - const DataLayout *DL) const { - LLVMContext &Ctx = FTy.getContext(); - Type *PCharTy = Type::getInt8PtrTy(Ctx); -@@ -531,493 +531,493 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, - unsigned NumParams = FTy.getNumParams(); - - switch (F) { -- case LibFunc::strlen: -+ case LibFunc_strlen: - return (NumParams == 1 && FTy.getParamType(0)->isPointerTy() && - FTy.getReturnType()->isIntegerTy()); - -- case LibFunc::strchr: -- case LibFunc::strrchr: -+ case LibFunc_strchr: -+ case LibFunc_strrchr: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0) == FTy.getReturnType() && - FTy.getParamType(1)->isIntegerTy()); - -- case LibFunc::strtol: -- case LibFunc::strtod: -- case LibFunc::strtof: -- case LibFunc::strtoul: -- case LibFunc::strtoll: -- case LibFunc::strtold: -- case LibFunc::strtoull: -+ case LibFunc_strtol: -+ case LibFunc_strtod: -+ case LibFunc_strtof: -+ case LibFunc_strtoul: -+ case LibFunc_strtoll: -+ case LibFunc_strtold: -+ case LibFunc_strtoull: - return ((NumParams == 2 || NumParams == 3) && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::strcat: -+ case LibFunc_strcat: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0) == FTy.getReturnType() && - FTy.getParamType(1) == FTy.getReturnType()); - -- case LibFunc::strncat: -+ case LibFunc_strncat: - return (NumParams == 3 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0) == FTy.getReturnType() && - FTy.getParamType(1) == FTy.getReturnType() && - FTy.getParamType(2)->isIntegerTy()); - -- case LibFunc::strcpy_chk: -- case LibFunc::stpcpy_chk: -+ case LibFunc_strcpy_chk: -+ case LibFunc_stpcpy_chk: - --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) - return false; - LLVM_FALLTHROUGH; -- case LibFunc::strcpy: -- case LibFunc::stpcpy: -+ case LibFunc_strcpy: -+ case LibFunc_stpcpy: - return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(0) && - FTy.getParamType(0) == FTy.getParamType(1) && - FTy.getParamType(0) == PCharTy); - -- case LibFunc::strncpy_chk: -- case LibFunc::stpncpy_chk: -+ case LibFunc_strncpy_chk: -+ case LibFunc_stpncpy_chk: - --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) - return false; - LLVM_FALLTHROUGH; -- case LibFunc::strncpy: -- case LibFunc::stpncpy: -+ case LibFunc_strncpy: -+ case LibFunc_stpncpy: - return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && - FTy.getParamType(0) == FTy.getParamType(1) && - FTy.getParamType(0) == PCharTy && - FTy.getParamType(2)->isIntegerTy()); - -- case LibFunc::strxfrm: -+ case LibFunc_strxfrm: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); - -- case LibFunc::strcmp: -+ case LibFunc_strcmp: - return (NumParams == 2 && FTy.getReturnType()->isIntegerTy(32) && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(0) == FTy.getParamType(1)); - -- case LibFunc::strncmp: -+ case LibFunc_strncmp: - return (NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(0) == FTy.getParamType(1) && - FTy.getParamType(2)->isIntegerTy()); - -- case LibFunc::strspn: -- case LibFunc::strcspn: -+ case LibFunc_strspn: -+ case LibFunc_strcspn: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(0) == FTy.getParamType(1) && - FTy.getReturnType()->isIntegerTy()); - -- case LibFunc::strcoll: -- case LibFunc::strcasecmp: -- case LibFunc::strncasecmp: -+ case LibFunc_strcoll: -+ case LibFunc_strcasecmp: -+ case LibFunc_strncasecmp: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); - -- case LibFunc::strstr: -+ case LibFunc_strstr: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); - -- case LibFunc::strpbrk: -+ case LibFunc_strpbrk: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getReturnType() == FTy.getParamType(0) && - FTy.getParamType(0) == FTy.getParamType(1)); - -- case LibFunc::strtok: -- case LibFunc::strtok_r: -+ case LibFunc_strtok: -+ case LibFunc_strtok_r: - return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::scanf: -- case LibFunc::setbuf: -- case LibFunc::setvbuf: -+ case LibFunc_scanf: -+ case LibFunc_setbuf: -+ case LibFunc_setvbuf: - return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::strdup: -- case LibFunc::strndup: -+ case LibFunc_strdup: -+ case LibFunc_strndup: - return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy()); -- case LibFunc::sscanf: -- case LibFunc::stat: -- case LibFunc::statvfs: -- case LibFunc::sprintf: -+ case LibFunc_sscanf: -+ case LibFunc_stat: -+ case LibFunc_statvfs: -+ case LibFunc_sprintf: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::snprintf: -+ case LibFunc_snprintf: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::setitimer: -+ case LibFunc_setitimer: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::system: -+ case LibFunc_system: - return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::malloc: -+ case LibFunc_malloc: - return (NumParams == 1 && FTy.getReturnType()->isPointerTy()); -- case LibFunc::memcmp: -+ case LibFunc_memcmp: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy() && - FTy.getReturnType()->isIntegerTy(32)); - -- case LibFunc::memchr: -- case LibFunc::memrchr: -+ case LibFunc_memchr: -+ case LibFunc_memrchr: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isIntegerTy(32) && - FTy.getParamType(2)->isIntegerTy() && - FTy.getReturnType()->isPointerTy()); -- case LibFunc::modf: -- case LibFunc::modff: -- case LibFunc::modfl: -+ case LibFunc_modf: -+ case LibFunc_modff: -+ case LibFunc_modfl: - return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); - -- case LibFunc::memcpy_chk: -- case LibFunc::memmove_chk: -+ case LibFunc_memcpy_chk: -+ case LibFunc_memmove_chk: - --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) - return false; - LLVM_FALLTHROUGH; -- case LibFunc::memcpy: -- case LibFunc::mempcpy: -- case LibFunc::memmove: -+ case LibFunc_memcpy: -+ case LibFunc_mempcpy: -+ case LibFunc_memmove: - return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy() && - IsSizeTTy(FTy.getParamType(2))); - -- case LibFunc::memset_chk: -+ case LibFunc_memset_chk: - --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) - return false; - LLVM_FALLTHROUGH; -- case LibFunc::memset: -+ case LibFunc_memset: - return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isIntegerTy() && - IsSizeTTy(FTy.getParamType(2))); - -- case LibFunc::memccpy: -+ case LibFunc_memccpy: - return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::memalign: -+ case LibFunc_memalign: - return (FTy.getReturnType()->isPointerTy()); -- case LibFunc::realloc: -+ case LibFunc_realloc: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getReturnType()->isPointerTy()); -- case LibFunc::read: -+ case LibFunc_read: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::rewind: -- case LibFunc::rmdir: -- case LibFunc::remove: -- case LibFunc::realpath: -+ case LibFunc_rewind: -+ case LibFunc_rmdir: -+ case LibFunc_remove: -+ case LibFunc_realpath: - return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::rename: -+ case LibFunc_rename: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::readlink: -+ case LibFunc_readlink: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::write: -+ case LibFunc_write: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::bcopy: -- case LibFunc::bcmp: -+ case LibFunc_bcopy: -+ case LibFunc_bcmp: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::bzero: -+ case LibFunc_bzero: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::calloc: -+ case LibFunc_calloc: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy()); - -- case LibFunc::atof: -- case LibFunc::atoi: -- case LibFunc::atol: -- case LibFunc::atoll: -- case LibFunc::ferror: -- case LibFunc::getenv: -- case LibFunc::getpwnam: -- case LibFunc::pclose: -- case LibFunc::perror: -- case LibFunc::printf: -- case LibFunc::puts: -- case LibFunc::uname: -- case LibFunc::under_IO_getc: -- case LibFunc::unlink: -- case LibFunc::unsetenv: -+ case LibFunc_atof: -+ case LibFunc_atoi: -+ case LibFunc_atol: -+ case LibFunc_atoll: -+ case LibFunc_ferror: -+ case LibFunc_getenv: -+ case LibFunc_getpwnam: -+ case LibFunc_pclose: -+ case LibFunc_perror: -+ case LibFunc_printf: -+ case LibFunc_puts: -+ case LibFunc_uname: -+ case LibFunc_under_IO_getc: -+ case LibFunc_unlink: -+ case LibFunc_unsetenv: - return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); - -- case LibFunc::chmod: -- case LibFunc::chown: -- case LibFunc::clearerr: -- case LibFunc::closedir: -- case LibFunc::ctermid: -- case LibFunc::fclose: -- case LibFunc::feof: -- case LibFunc::fflush: -- case LibFunc::fgetc: -- case LibFunc::fileno: -- case LibFunc::flockfile: -- case LibFunc::free: -- case LibFunc::fseek: -- case LibFunc::fseeko64: -- case LibFunc::fseeko: -- case LibFunc::fsetpos: -- case LibFunc::ftell: -- case LibFunc::ftello64: -- case LibFunc::ftello: -- case LibFunc::ftrylockfile: -- case LibFunc::funlockfile: -- case LibFunc::getc: -- case LibFunc::getc_unlocked: -- case LibFunc::getlogin_r: -- case LibFunc::mkdir: -- case LibFunc::mktime: -- case LibFunc::times: -+ case LibFunc_chmod: -+ case LibFunc_chown: -+ case LibFunc_clearerr: -+ case LibFunc_closedir: -+ case LibFunc_ctermid: -+ case LibFunc_fclose: -+ case LibFunc_feof: -+ case LibFunc_fflush: -+ case LibFunc_fgetc: -+ case LibFunc_fileno: -+ case LibFunc_flockfile: -+ case LibFunc_free: -+ case LibFunc_fseek: -+ case LibFunc_fseeko64: -+ case LibFunc_fseeko: -+ case LibFunc_fsetpos: -+ case LibFunc_ftell: -+ case LibFunc_ftello64: -+ case LibFunc_ftello: -+ case LibFunc_ftrylockfile: -+ case LibFunc_funlockfile: -+ case LibFunc_getc: -+ case LibFunc_getc_unlocked: -+ case LibFunc_getlogin_r: -+ case LibFunc_mkdir: -+ case LibFunc_mktime: -+ case LibFunc_times: - return (NumParams != 0 && FTy.getParamType(0)->isPointerTy()); - -- case LibFunc::access: -+ case LibFunc_access: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::fopen: -+ case LibFunc_fopen: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fdopen: -+ case LibFunc_fdopen: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fputc: -- case LibFunc::fstat: -- case LibFunc::frexp: -- case LibFunc::frexpf: -- case LibFunc::frexpl: -- case LibFunc::fstatvfs: -+ case LibFunc_fputc: -+ case LibFunc_fstat: -+ case LibFunc_frexp: -+ case LibFunc_frexpf: -+ case LibFunc_frexpl: -+ case LibFunc_fstatvfs: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fgets: -+ case LibFunc_fgets: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::fread: -+ case LibFunc_fread: - return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(3)->isPointerTy()); -- case LibFunc::fwrite: -+ case LibFunc_fwrite: - return (NumParams == 4 && FTy.getReturnType()->isIntegerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isIntegerTy() && - FTy.getParamType(2)->isIntegerTy() && - FTy.getParamType(3)->isPointerTy()); -- case LibFunc::fputs: -+ case LibFunc_fputs: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fscanf: -- case LibFunc::fprintf: -+ case LibFunc_fscanf: -+ case LibFunc_fprintf: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fgetpos: -+ case LibFunc_fgetpos: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::gets: -- case LibFunc::getchar: -- case LibFunc::getitimer: -+ case LibFunc_gets: -+ case LibFunc_getchar: -+ case LibFunc_getitimer: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::ungetc: -+ case LibFunc_ungetc: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::utime: -- case LibFunc::utimes: -+ case LibFunc_utime: -+ case LibFunc_utimes: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::putc: -+ case LibFunc_putc: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::pread: -- case LibFunc::pwrite: -+ case LibFunc_pread: -+ case LibFunc_pwrite: - return (NumParams == 4 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::popen: -+ case LibFunc_popen: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::vscanf: -+ case LibFunc_vscanf: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::vsscanf: -+ case LibFunc_vsscanf: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::vfscanf: -+ case LibFunc_vfscanf: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::valloc: -+ case LibFunc_valloc: - return (FTy.getReturnType()->isPointerTy()); -- case LibFunc::vprintf: -+ case LibFunc_vprintf: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::vfprintf: -- case LibFunc::vsprintf: -+ case LibFunc_vfprintf: -+ case LibFunc_vsprintf: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::vsnprintf: -+ case LibFunc_vsnprintf: - return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); -- case LibFunc::open: -+ case LibFunc_open: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::opendir: -+ case LibFunc_opendir: - return (NumParams == 1 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy()); -- case LibFunc::tmpfile: -+ case LibFunc_tmpfile: - return (FTy.getReturnType()->isPointerTy()); -- case LibFunc::htonl: -- case LibFunc::htons: -- case LibFunc::ntohl: -- case LibFunc::ntohs: -- case LibFunc::lstat: -+ case LibFunc_htonl: -+ case LibFunc_htons: -+ case LibFunc_ntohl: -+ case LibFunc_ntohs: -+ case LibFunc_lstat: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::lchown: -+ case LibFunc_lchown: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::qsort: -+ case LibFunc_qsort: - return (NumParams == 4 && FTy.getParamType(3)->isPointerTy()); -- case LibFunc::dunder_strdup: -- case LibFunc::dunder_strndup: -+ case LibFunc_dunder_strdup: -+ case LibFunc_dunder_strndup: - return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy()); -- case LibFunc::dunder_strtok_r: -+ case LibFunc_dunder_strtok_r: - return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::under_IO_putc: -+ case LibFunc_under_IO_putc: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::dunder_isoc99_scanf: -+ case LibFunc_dunder_isoc99_scanf: - return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::stat64: -- case LibFunc::lstat64: -- case LibFunc::statvfs64: -+ case LibFunc_stat64: -+ case LibFunc_lstat64: -+ case LibFunc_statvfs64: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::dunder_isoc99_sscanf: -+ case LibFunc_dunder_isoc99_sscanf: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::fopen64: -+ case LibFunc_fopen64: - return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); -- case LibFunc::tmpfile64: -+ case LibFunc_tmpfile64: - return (FTy.getReturnType()->isPointerTy()); -- case LibFunc::fstat64: -- case LibFunc::fstatvfs64: -+ case LibFunc_fstat64: -+ case LibFunc_fstatvfs64: - return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); -- case LibFunc::open64: -+ case LibFunc_open64: - return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); -- case LibFunc::gettimeofday: -+ case LibFunc_gettimeofday: - return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy()); - -- case LibFunc::Znwj: // new(unsigned int); -- case LibFunc::Znwm: // new(unsigned long); -- case LibFunc::Znaj: // new[](unsigned int); -- case LibFunc::Znam: // new[](unsigned long); -- case LibFunc::msvc_new_int: // new(unsigned int); -- case LibFunc::msvc_new_longlong: // new(unsigned long long); -- case LibFunc::msvc_new_array_int: // new[](unsigned int); -- case LibFunc::msvc_new_array_longlong: // new[](unsigned long long); -+ case LibFunc_Znwj: // new(unsigned int); -+ case LibFunc_Znwm: // new(unsigned long); -+ case LibFunc_Znaj: // new[](unsigned int); -+ case LibFunc_Znam: // new[](unsigned long); -+ case LibFunc_msvc_new_int: // new(unsigned int); -+ case LibFunc_msvc_new_longlong: // new(unsigned long long); -+ case LibFunc_msvc_new_array_int: // new[](unsigned int); -+ case LibFunc_msvc_new_array_longlong: // new[](unsigned long long); - return (NumParams == 1); - -- case LibFunc::memset_pattern16: -+ case LibFunc_memset_pattern16: - return (!FTy.isVarArg() && NumParams == 3 && - isa(FTy.getParamType(0)) && - isa(FTy.getParamType(1)) && - isa(FTy.getParamType(2))); - - // int __nvvm_reflect(const char *); -- case LibFunc::nvvm_reflect: -+ case LibFunc_nvvm_reflect: - return (NumParams == 1 && isa(FTy.getParamType(0))); - -- case LibFunc::sin: -- case LibFunc::sinf: -- case LibFunc::sinl: -- case LibFunc::cos: -- case LibFunc::cosf: -- case LibFunc::cosl: -- case LibFunc::tan: -- case LibFunc::tanf: -- case LibFunc::tanl: -- case LibFunc::exp: -- case LibFunc::expf: -- case LibFunc::expl: -- case LibFunc::exp2: -- case LibFunc::exp2f: -- case LibFunc::exp2l: -- case LibFunc::log: -- case LibFunc::logf: -- case LibFunc::logl: -- case LibFunc::log10: -- case LibFunc::log10f: -- case LibFunc::log10l: -- case LibFunc::log1p: -- case LibFunc::log2: -- case LibFunc::log2f: -- case LibFunc::log2l: -- case LibFunc::fabs: -- case LibFunc::fabsf: -- case LibFunc::fabsl: -- case LibFunc::floor: -- case LibFunc::floorf: -- case LibFunc::floorl: -- case LibFunc::ceil: -- case LibFunc::ceilf: -- case LibFunc::ceill: -- case LibFunc::trunc: -- case LibFunc::truncf: -- case LibFunc::truncl: -- case LibFunc::rint: -- case LibFunc::rintf: -- case LibFunc::rintl: -- case LibFunc::nearbyint: -- case LibFunc::nearbyintf: -- case LibFunc::nearbyintl: -- case LibFunc::round: -- case LibFunc::roundf: -- case LibFunc::roundl: -- case LibFunc::sqrt: -- case LibFunc::sqrtf: -- case LibFunc::sqrtl: -+ case LibFunc_sin: -+ case LibFunc_sinf: -+ case LibFunc_sinl: -+ case LibFunc_cos: -+ case LibFunc_cosf: -+ case LibFunc_cosl: -+ case LibFunc_tan: -+ case LibFunc_tanf: -+ case LibFunc_tanl: -+ case LibFunc_exp: -+ case LibFunc_expf: -+ case LibFunc_expl: -+ case LibFunc_exp2: -+ case LibFunc_exp2f: -+ case LibFunc_exp2l: -+ case LibFunc_log: -+ case LibFunc_logf: -+ case LibFunc_logl: -+ case LibFunc_log10: -+ case LibFunc_log10f: -+ case LibFunc_log10l: -+ case LibFunc_log1p: -+ case LibFunc_log2: -+ case LibFunc_log2f: -+ case LibFunc_log2l: -+ case LibFunc_fabs: -+ case LibFunc_fabsf: -+ case LibFunc_fabsl: -+ case LibFunc_floor: -+ case LibFunc_floorf: -+ case LibFunc_floorl: -+ case LibFunc_ceil: -+ case LibFunc_ceilf: -+ case LibFunc_ceill: -+ case LibFunc_trunc: -+ case LibFunc_truncf: -+ case LibFunc_truncl: -+ case LibFunc_rint: -+ case LibFunc_rintf: -+ case LibFunc_rintl: -+ case LibFunc_nearbyint: -+ case LibFunc_nearbyintf: -+ case LibFunc_nearbyintl: -+ case LibFunc_round: -+ case LibFunc_roundf: -+ case LibFunc_roundl: -+ case LibFunc_sqrt: -+ case LibFunc_sqrtf: -+ case LibFunc_sqrtl: - return (NumParams == 1 && FTy.getReturnType()->isFloatingPointTy() && - FTy.getReturnType() == FTy.getParamType(0)); - -- case LibFunc::fmin: -- case LibFunc::fminf: -- case LibFunc::fminl: -- case LibFunc::fmax: -- case LibFunc::fmaxf: -- case LibFunc::fmaxl: -- case LibFunc::copysign: -- case LibFunc::copysignf: -- case LibFunc::copysignl: -- case LibFunc::pow: -- case LibFunc::powf: -- case LibFunc::powl: -+ case LibFunc_fmin: -+ case LibFunc_fminf: -+ case LibFunc_fminl: -+ case LibFunc_fmax: -+ case LibFunc_fmaxf: -+ case LibFunc_fmaxl: -+ case LibFunc_copysign: -+ case LibFunc_copysignf: -+ case LibFunc_copysignl: -+ case LibFunc_pow: -+ case LibFunc_powf: -+ case LibFunc_powl: - return (NumParams == 2 && FTy.getReturnType()->isFloatingPointTy() && - FTy.getReturnType() == FTy.getParamType(0) && - FTy.getReturnType() == FTy.getParamType(1)); - -- case LibFunc::ffs: -- case LibFunc::ffsl: -- case LibFunc::ffsll: -- case LibFunc::fls: -- case LibFunc::flsl: -- case LibFunc::flsll: -+ case LibFunc_ffs: -+ case LibFunc_ffsl: -+ case LibFunc_ffsll: -+ case LibFunc_fls: -+ case LibFunc_flsl: -+ case LibFunc_flsll: - return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) && - FTy.getParamType(0)->isIntegerTy()); - -- case LibFunc::isdigit: -- case LibFunc::isascii: -- case LibFunc::toascii: -+ case LibFunc_isdigit: -+ case LibFunc_isascii: -+ case LibFunc_toascii: - return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) && - FTy.getReturnType() == FTy.getParamType(0)); - -- case LibFunc::abs: -- case LibFunc::labs: -- case LibFunc::llabs: -+ case LibFunc_abs: -+ case LibFunc_labs: -+ case LibFunc_llabs: - return (NumParams == 1 && FTy.getReturnType()->isIntegerTy() && - FTy.getReturnType() == FTy.getParamType(0)); - -- case LibFunc::cxa_atexit: -+ case LibFunc_cxa_atexit: - return (NumParams == 3 && FTy.getReturnType()->isIntegerTy() && - FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy() && - FTy.getParamType(2)->isPointerTy()); - -- case LibFunc::sinpi: -- case LibFunc::cospi: -+ case LibFunc_sinpi: -+ case LibFunc_cospi: - return (NumParams == 1 && FTy.getReturnType()->isDoubleTy() && - FTy.getReturnType() == FTy.getParamType(0)); - -- case LibFunc::sinpif: -- case LibFunc::cospif: -+ case LibFunc_sinpif: -+ case LibFunc_cospif: - return (NumParams == 1 && FTy.getReturnType()->isFloatTy() && - FTy.getReturnType() == FTy.getParamType(0)); - -@@ -1029,7 +1029,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, - } - - bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl, -- LibFunc::Func &F) const { -+ LibFunc &F) const { - const DataLayout *DL = - FDecl.getParent() ? &FDecl.getParent()->getDataLayout() : nullptr; - return getLibFunc(FDecl.getName(), F) && -diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp -index b79370baad1..55f1e676a74 100644 ---- a/lib/Analysis/ValueTracking.cpp -+++ b/lib/Analysis/ValueTracking.cpp -@@ -2436,7 +2436,7 @@ Intrinsic::ID llvm::getIntrinsicForCallSite(ImmutableCallSite ICS, - if (!TLI) - return Intrinsic::not_intrinsic; - -- LibFunc::Func Func; -+ LibFunc Func; - // We're going to make assumptions on the semantics of the functions, check - // that the target knows that it's available in this environment and it does - // not have local linkage. -@@ -2451,81 +2451,81 @@ Intrinsic::ID llvm::getIntrinsicForCallSite(ImmutableCallSite ICS, - switch (Func) { - default: - break; -- case LibFunc::sin: -- case LibFunc::sinf: -- case LibFunc::sinl: -+ case LibFunc_sin: -+ case LibFunc_sinf: -+ case LibFunc_sinl: - return Intrinsic::sin; -- case LibFunc::cos: -- case LibFunc::cosf: -- case LibFunc::cosl: -+ case LibFunc_cos: -+ case LibFunc_cosf: -+ case LibFunc_cosl: - return Intrinsic::cos; -- case LibFunc::exp: -- case LibFunc::expf: -- case LibFunc::expl: -+ case LibFunc_exp: -+ case LibFunc_expf: -+ case LibFunc_expl: - return Intrinsic::exp; -- case LibFunc::exp2: -- case LibFunc::exp2f: -- case LibFunc::exp2l: -+ case LibFunc_exp2: -+ case LibFunc_exp2f: -+ case LibFunc_exp2l: - return Intrinsic::exp2; -- case LibFunc::log: -- case LibFunc::logf: -- case LibFunc::logl: -+ case LibFunc_log: -+ case LibFunc_logf: -+ case LibFunc_logl: - return Intrinsic::log; -- case LibFunc::log10: -- case LibFunc::log10f: -- case LibFunc::log10l: -+ case LibFunc_log10: -+ case LibFunc_log10f: -+ case LibFunc_log10l: - return Intrinsic::log10; -- case LibFunc::log2: -- case LibFunc::log2f: -- case LibFunc::log2l: -+ case LibFunc_log2: -+ case LibFunc_log2f: -+ case LibFunc_log2l: - return Intrinsic::log2; -- case LibFunc::fabs: -- case LibFunc::fabsf: -- case LibFunc::fabsl: -+ case LibFunc_fabs: -+ case LibFunc_fabsf: -+ case LibFunc_fabsl: - return Intrinsic::fabs; -- case LibFunc::fmin: -- case LibFunc::fminf: -- case LibFunc::fminl: -+ case LibFunc_fmin: -+ case LibFunc_fminf: -+ case LibFunc_fminl: - return Intrinsic::minnum; -- case LibFunc::fmax: -- case LibFunc::fmaxf: -- case LibFunc::fmaxl: -+ case LibFunc_fmax: -+ case LibFunc_fmaxf: -+ case LibFunc_fmaxl: - return Intrinsic::maxnum; -- case LibFunc::copysign: -- case LibFunc::copysignf: -- case LibFunc::copysignl: -+ case LibFunc_copysign: -+ case LibFunc_copysignf: -+ case LibFunc_copysignl: - return Intrinsic::copysign; -- case LibFunc::floor: -- case LibFunc::floorf: -- case LibFunc::floorl: -+ case LibFunc_floor: -+ case LibFunc_floorf: -+ case LibFunc_floorl: - return Intrinsic::floor; -- case LibFunc::ceil: -- case LibFunc::ceilf: -- case LibFunc::ceill: -+ case LibFunc_ceil: -+ case LibFunc_ceilf: -+ case LibFunc_ceill: - return Intrinsic::ceil; -- case LibFunc::trunc: -- case LibFunc::truncf: -- case LibFunc::truncl: -+ case LibFunc_trunc: -+ case LibFunc_truncf: -+ case LibFunc_truncl: - return Intrinsic::trunc; -- case LibFunc::rint: -- case LibFunc::rintf: -- case LibFunc::rintl: -+ case LibFunc_rint: -+ case LibFunc_rintf: -+ case LibFunc_rintl: - return Intrinsic::rint; -- case LibFunc::nearbyint: -- case LibFunc::nearbyintf: -- case LibFunc::nearbyintl: -+ case LibFunc_nearbyint: -+ case LibFunc_nearbyintf: -+ case LibFunc_nearbyintl: - return Intrinsic::nearbyint; -- case LibFunc::round: -- case LibFunc::roundf: -- case LibFunc::roundl: -+ case LibFunc_round: -+ case LibFunc_roundf: -+ case LibFunc_roundl: - return Intrinsic::round; -- case LibFunc::pow: -- case LibFunc::powf: -- case LibFunc::powl: -+ case LibFunc_pow: -+ case LibFunc_powf: -+ case LibFunc_powl: - return Intrinsic::pow; -- case LibFunc::sqrt: -- case LibFunc::sqrtf: -- case LibFunc::sqrtl: -+ case LibFunc_sqrt: -+ case LibFunc_sqrtf: -+ case LibFunc_sqrtl: - if (ICS->hasNoNaNs()) - return Intrinsic::sqrt; - return Intrinsic::not_intrinsic; -diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp -index 62de8bf2015..cb1a5ce8be1 100644 ---- a/lib/CodeGen/SelectionDAG/FastISel.cpp -+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp -@@ -1364,7 +1364,7 @@ bool FastISel::selectInstruction(const Instruction *I) { - - if (const auto *Call = dyn_cast(I)) { - const Function *F = Call->getCalledFunction(); -- LibFunc::Func Func; -+ LibFunc Func; - - // As a special case, don't handle calls to builtin library functions that - // may be translated directly to target instructions. -diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp -index 95e31a3eaf6..5dad37cd5a1 100644 ---- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp -+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp -@@ -6334,15 +6334,15 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) { - // Check for well-known libc/libm calls. If the function is internal, it - // can't be a library call. Don't do the check if marked as nobuiltin for - // some reason. -- LibFunc::Func Func; -+ LibFunc Func; - if (!I.isNoBuiltin() && !F->hasLocalLinkage() && F->hasName() && - LibInfo->getLibFunc(F->getName(), Func) && - LibInfo->hasOptimizedCodeGen(Func)) { - switch (Func) { - default: break; -- case LibFunc::copysign: -- case LibFunc::copysignf: -- case LibFunc::copysignl: -+ case LibFunc_copysign: -+ case LibFunc_copysignf: -+ case LibFunc_copysignl: - if (I.getNumArgOperands() == 2 && // Basic sanity checks. - I.getArgOperand(0)->getType()->isFloatingPointTy() && - I.getType() == I.getArgOperand(0)->getType() && -@@ -6355,122 +6355,122 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) { - return; - } - break; -- case LibFunc::fabs: -- case LibFunc::fabsf: -- case LibFunc::fabsl: -+ case LibFunc_fabs: -+ case LibFunc_fabsf: -+ case LibFunc_fabsl: - if (visitUnaryFloatCall(I, ISD::FABS)) - return; - break; -- case LibFunc::fmin: -- case LibFunc::fminf: -- case LibFunc::fminl: -+ case LibFunc_fmin: -+ case LibFunc_fminf: -+ case LibFunc_fminl: - if (visitBinaryFloatCall(I, ISD::FMINNUM)) - return; - break; -- case LibFunc::fmax: -- case LibFunc::fmaxf: -- case LibFunc::fmaxl: -+ case LibFunc_fmax: -+ case LibFunc_fmaxf: -+ case LibFunc_fmaxl: - if (visitBinaryFloatCall(I, ISD::FMAXNUM)) - return; - break; -- case LibFunc::sin: -- case LibFunc::sinf: -- case LibFunc::sinl: -+ case LibFunc_sin: -+ case LibFunc_sinf: -+ case LibFunc_sinl: - if (visitUnaryFloatCall(I, ISD::FSIN)) - return; - break; -- case LibFunc::cos: -- case LibFunc::cosf: -- case LibFunc::cosl: -+ case LibFunc_cos: -+ case LibFunc_cosf: -+ case LibFunc_cosl: - if (visitUnaryFloatCall(I, ISD::FCOS)) - return; - break; -- case LibFunc::sqrt: -- case LibFunc::sqrtf: -- case LibFunc::sqrtl: -- case LibFunc::sqrt_finite: -- case LibFunc::sqrtf_finite: -- case LibFunc::sqrtl_finite: -+ case LibFunc_sqrt: -+ case LibFunc_sqrtf: -+ case LibFunc_sqrtl: -+ case LibFunc_sqrt_finite: -+ case LibFunc_sqrtf_finite: -+ case LibFunc_sqrtl_finite: - if (visitUnaryFloatCall(I, ISD::FSQRT)) - return; - break; -- case LibFunc::floor: -- case LibFunc::floorf: -- case LibFunc::floorl: -+ case LibFunc_floor: -+ case LibFunc_floorf: -+ case LibFunc_floorl: - if (visitUnaryFloatCall(I, ISD::FFLOOR)) - return; - break; -- case LibFunc::nearbyint: -- case LibFunc::nearbyintf: -- case LibFunc::nearbyintl: -+ case LibFunc_nearbyint: -+ case LibFunc_nearbyintf: -+ case LibFunc_nearbyintl: - if (visitUnaryFloatCall(I, ISD::FNEARBYINT)) - return; - break; -- case LibFunc::ceil: -- case LibFunc::ceilf: -- case LibFunc::ceill: -+ case LibFunc_ceil: -+ case LibFunc_ceilf: -+ case LibFunc_ceill: - if (visitUnaryFloatCall(I, ISD::FCEIL)) - return; - break; -- case LibFunc::rint: -- case LibFunc::rintf: -- case LibFunc::rintl: -+ case LibFunc_rint: -+ case LibFunc_rintf: -+ case LibFunc_rintl: - if (visitUnaryFloatCall(I, ISD::FRINT)) - return; - break; -- case LibFunc::round: -- case LibFunc::roundf: -- case LibFunc::roundl: -+ case LibFunc_round: -+ case LibFunc_roundf: -+ case LibFunc_roundl: - if (visitUnaryFloatCall(I, ISD::FROUND)) - return; - break; -- case LibFunc::trunc: -- case LibFunc::truncf: -- case LibFunc::truncl: -+ case LibFunc_trunc: -+ case LibFunc_truncf: -+ case LibFunc_truncl: - if (visitUnaryFloatCall(I, ISD::FTRUNC)) - return; - break; -- case LibFunc::log2: -- case LibFunc::log2f: -- case LibFunc::log2l: -+ case LibFunc_log2: -+ case LibFunc_log2f: -+ case LibFunc_log2l: - if (visitUnaryFloatCall(I, ISD::FLOG2)) - return; - break; -- case LibFunc::exp2: -- case LibFunc::exp2f: -- case LibFunc::exp2l: -+ case LibFunc_exp2: -+ case LibFunc_exp2f: -+ case LibFunc_exp2l: - if (visitUnaryFloatCall(I, ISD::FEXP2)) - return; - break; -- case LibFunc::memcmp: -+ case LibFunc_memcmp: - if (visitMemCmpCall(I)) - return; - break; -- case LibFunc::mempcpy: -+ case LibFunc_mempcpy: - if (visitMemPCpyCall(I)) - return; - break; -- case LibFunc::memchr: -+ case LibFunc_memchr: - if (visitMemChrCall(I)) - return; - break; -- case LibFunc::strcpy: -+ case LibFunc_strcpy: - if (visitStrCpyCall(I, false)) - return; - break; -- case LibFunc::stpcpy: -+ case LibFunc_stpcpy: - if (visitStrCpyCall(I, true)) - return; - break; -- case LibFunc::strcmp: -+ case LibFunc_strcmp: - if (visitStrCmpCall(I)) - return; - break; -- case LibFunc::strlen: -+ case LibFunc_strlen: - if (visitStrLenCall(I)) - return; - break; -- case LibFunc::strnlen: -+ case LibFunc_strnlen: - if (visitStrNLenCall(I)) - return; - break; -diff --git a/lib/LTO/UpdateCompilerUsed.cpp b/lib/LTO/UpdateCompilerUsed.cpp -index b67d9ea5989..5165cc96503 100644 ---- a/lib/LTO/UpdateCompilerUsed.cpp -+++ b/lib/LTO/UpdateCompilerUsed.cpp -@@ -65,7 +65,7 @@ private: - // target. - for (unsigned I = 0, E = static_cast(LibFunc::NumLibFuncs); - I != E; ++I) { -- LibFunc::Func F = static_cast(I); -+ LibFunc F = static_cast(I); - if (TLI.has(F)) - Libcalls.insert(TLI.getName(F)); - } -diff --git a/lib/Target/PowerPC/PPCCTRLoops.cpp b/lib/Target/PowerPC/PPCCTRLoops.cpp -index 2c62a0f1d90..197be8b7db9 100644 ---- a/lib/Target/PowerPC/PPCCTRLoops.cpp -+++ b/lib/Target/PowerPC/PPCCTRLoops.cpp -@@ -315,7 +315,7 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) { - // (i.e. soft float or atomics). If adapting for targets that do, - // additional care is required here. - -- LibFunc::Func Func; -+ LibFunc Func; - if (!F->hasLocalLinkage() && F->hasName() && LibInfo && - LibInfo->getLibFunc(F->getName(), Func) && - LibInfo->hasOptimizedCodeGen(Func)) { -@@ -329,50 +329,50 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) { - - switch (Func) { - default: return true; -- case LibFunc::copysign: -- case LibFunc::copysignf: -+ case LibFunc_copysign: -+ case LibFunc_copysignf: - continue; // ISD::FCOPYSIGN is never a library call. -- case LibFunc::copysignl: -+ case LibFunc_copysignl: - return true; -- case LibFunc::fabs: -- case LibFunc::fabsf: -- case LibFunc::fabsl: -+ case LibFunc_fabs: -+ case LibFunc_fabsf: -+ case LibFunc_fabsl: - continue; // ISD::FABS is never a library call. -- case LibFunc::sqrt: -- case LibFunc::sqrtf: -- case LibFunc::sqrtl: -+ case LibFunc_sqrt: -+ case LibFunc_sqrtf: -+ case LibFunc_sqrtl: - Opcode = ISD::FSQRT; break; -- case LibFunc::floor: -- case LibFunc::floorf: -- case LibFunc::floorl: -+ case LibFunc_floor: -+ case LibFunc_floorf: -+ case LibFunc_floorl: - Opcode = ISD::FFLOOR; break; -- case LibFunc::nearbyint: -- case LibFunc::nearbyintf: -- case LibFunc::nearbyintl: -+ case LibFunc_nearbyint: -+ case LibFunc_nearbyintf: -+ case LibFunc_nearbyintl: - Opcode = ISD::FNEARBYINT; break; -- case LibFunc::ceil: -- case LibFunc::ceilf: -- case LibFunc::ceill: -+ case LibFunc_ceil: -+ case LibFunc_ceilf: -+ case LibFunc_ceill: - Opcode = ISD::FCEIL; break; -- case LibFunc::rint: -- case LibFunc::rintf: -- case LibFunc::rintl: -+ case LibFunc_rint: -+ case LibFunc_rintf: -+ case LibFunc_rintl: - Opcode = ISD::FRINT; break; -- case LibFunc::round: -- case LibFunc::roundf: -- case LibFunc::roundl: -+ case LibFunc_round: -+ case LibFunc_roundf: -+ case LibFunc_roundl: - Opcode = ISD::FROUND; break; -- case LibFunc::trunc: -- case LibFunc::truncf: -- case LibFunc::truncl: -+ case LibFunc_trunc: -+ case LibFunc_truncf: -+ case LibFunc_truncl: - Opcode = ISD::FTRUNC; break; -- case LibFunc::fmin: -- case LibFunc::fminf: -- case LibFunc::fminl: -+ case LibFunc_fmin: -+ case LibFunc_fminf: -+ case LibFunc_fminl: - Opcode = ISD::FMINNUM; break; -- case LibFunc::fmax: -- case LibFunc::fmaxf: -- case LibFunc::fmaxl: -+ case LibFunc_fmax: -+ case LibFunc_fmaxf: -+ case LibFunc_fmaxl: - Opcode = ISD::FMAXNUM; break; - } - } -diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp -index 5b0d5e3bc01..484fdbed0cb 100644 ---- a/lib/Transforms/IPO/GlobalOpt.cpp -+++ b/lib/Transforms/IPO/GlobalOpt.cpp -@@ -2387,7 +2387,7 @@ OptimizeGlobalAliases(Module &M, - } - - static Function *FindCXAAtExit(Module &M, TargetLibraryInfo *TLI) { -- LibFunc::Func F = LibFunc::cxa_atexit; -+ LibFunc F = LibFunc_cxa_atexit; - if (!TLI->has(F)) - return nullptr; - -@@ -2396,7 +2396,7 @@ static Function *FindCXAAtExit(Module &M, TargetLibraryInfo *TLI) { - return nullptr; - - // Make sure that the function has the correct prototype. -- if (!TLI->getLibFunc(*Fn, F) || F != LibFunc::cxa_atexit) -+ if (!TLI->getLibFunc(*Fn, F) || F != LibFunc_cxa_atexit) - return nullptr; - - return Fn; -diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp -index 4d4c3baef3f..a1e995aca22 100644 ---- a/lib/Transforms/Scalar/DeadStoreElimination.cpp -+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp -@@ -135,13 +135,13 @@ static bool hasMemoryWrite(Instruction *I, const TargetLibraryInfo &TLI) { - if (auto CS = CallSite(I)) { - if (Function *F = CS.getCalledFunction()) { - StringRef FnName = F->getName(); -- if (TLI.has(LibFunc::strcpy) && FnName == TLI.getName(LibFunc::strcpy)) -+ if (TLI.has(LibFunc_strcpy) && FnName == TLI.getName(LibFunc_strcpy)) - return true; -- if (TLI.has(LibFunc::strncpy) && FnName == TLI.getName(LibFunc::strncpy)) -+ if (TLI.has(LibFunc_strncpy) && FnName == TLI.getName(LibFunc_strncpy)) - return true; -- if (TLI.has(LibFunc::strcat) && FnName == TLI.getName(LibFunc::strcat)) -+ if (TLI.has(LibFunc_strcat) && FnName == TLI.getName(LibFunc_strcat)) - return true; -- if (TLI.has(LibFunc::strncat) && FnName == TLI.getName(LibFunc::strncat)) -+ if (TLI.has(LibFunc_strncat) && FnName == TLI.getName(LibFunc_strncat)) - return true; - } - } -diff --git a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp -index 5fec51c095d..d509f2928b1 100644 ---- a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp -+++ b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp -@@ -236,9 +236,9 @@ bool LoopIdiomRecognize::runOnLoop(Loop *L) { - ApplyCodeSizeHeuristics = - L->getHeader()->getParent()->optForSize() && UseLIRCodeSizeHeurs; - -- HasMemset = TLI->has(LibFunc::memset); -- HasMemsetPattern = TLI->has(LibFunc::memset_pattern16); -- HasMemcpy = TLI->has(LibFunc::memcpy); -+ HasMemset = TLI->has(LibFunc_memset); -+ HasMemsetPattern = TLI->has(LibFunc_memset_pattern16); -+ HasMemcpy = TLI->has(LibFunc_memcpy); - - if (HasMemset || HasMemsetPattern || HasMemcpy) - if (SE->hasLoopInvariantBackedgeTakenCount(L)) -diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp -index 8355f952e31..b84f4780442 100644 ---- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp -+++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp -@@ -1240,7 +1240,7 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M) { - bool MemCpyOptPass::processMemMove(MemMoveInst *M) { - AliasAnalysis &AA = LookupAliasAnalysis(); - -- if (!TLI->has(LibFunc::memmove)) -+ if (!TLI->has(LibFunc_memmove)) - return false; - - // See if the pointers alias. -@@ -1419,7 +1419,7 @@ bool MemCpyOptPass::runImpl( - // If we don't have at least memset and memcpy, there is little point of doing - // anything here. These are required by a freestanding implementation, so if - // even they are disabled, there is no point in trying hard. -- if (!TLI->has(LibFunc::memset) || !TLI->has(LibFunc::memcpy)) -+ if (!TLI->has(LibFunc_memset) || !TLI->has(LibFunc_memcpy)) - return false; - - while (1) { -diff --git a/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp b/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp -index 1a7ddc9585b..5494356a60b 100644 ---- a/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp -+++ b/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp -@@ -98,14 +98,14 @@ static bool runPartiallyInlineLibCalls(Function &F, TargetLibraryInfo *TLI, - - // Skip if function either has local linkage or is not a known library - // function. -- LibFunc::Func LibFunc; -+ LibFunc LF; - if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() || -- !TLI->getLibFunc(CalledFunc->getName(), LibFunc)) -+ !TLI->getLibFunc(CalledFunc->getName(), LF)) - continue; - -- switch (LibFunc) { -- case LibFunc::sqrtf: -- case LibFunc::sqrt: -+ switch (LF) { -+ case LibFunc_sqrtf: -+ case LibFunc_sqrt: - if (TTI->haveFastSqrt(Call->getType()) && - optimizeSQRT(Call, CalledFunc, *CurrBB, BB)) - break; -diff --git a/lib/Transforms/Utils/BuildLibCalls.cpp b/lib/Transforms/Utils/BuildLibCalls.cpp -index e61b04fbdd5..4f6bfcfe524 100644 ---- a/lib/Transforms/Utils/BuildLibCalls.cpp -+++ b/lib/Transforms/Utils/BuildLibCalls.cpp -@@ -107,255 +107,255 @@ static bool setNonNull(Function &F, unsigned n) { - } - - bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { -- LibFunc::Func TheLibFunc; -+ LibFunc TheLibFunc; - if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc))) - return false; - - bool Changed = false; - switch (TheLibFunc) { -- case LibFunc::strlen: -+ case LibFunc_strlen: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::strchr: -- case LibFunc::strrchr: -+ case LibFunc_strchr: -+ case LibFunc_strrchr: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - return Changed; -- case LibFunc::strtol: -- case LibFunc::strtod: -- case LibFunc::strtof: -- case LibFunc::strtoul: -- case LibFunc::strtoll: -- case LibFunc::strtold: -- case LibFunc::strtoull: -+ case LibFunc_strtol: -+ case LibFunc_strtod: -+ case LibFunc_strtof: -+ case LibFunc_strtoul: -+ case LibFunc_strtoll: -+ case LibFunc_strtold: -+ case LibFunc_strtoull: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::strcpy: -- case LibFunc::stpcpy: -- case LibFunc::strcat: -- case LibFunc::strncat: -- case LibFunc::strncpy: -- case LibFunc::stpncpy: -+ case LibFunc_strcpy: -+ case LibFunc_stpcpy: -+ case LibFunc_strcat: -+ case LibFunc_strncat: -+ case LibFunc_strncpy: -+ case LibFunc_stpncpy: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::strxfrm: -+ case LibFunc_strxfrm: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::strcmp: // 0,1 -- case LibFunc::strspn: // 0,1 -- case LibFunc::strncmp: // 0,1 -- case LibFunc::strcspn: // 0,1 -- case LibFunc::strcoll: // 0,1 -- case LibFunc::strcasecmp: // 0,1 -- case LibFunc::strncasecmp: // -+ case LibFunc_strcmp: // 0,1 -+ case LibFunc_strspn: // 0,1 -+ case LibFunc_strncmp: // 0,1 -+ case LibFunc_strcspn: // 0,1 -+ case LibFunc_strcoll: // 0,1 -+ case LibFunc_strcasecmp: // 0,1 -+ case LibFunc_strncasecmp: // - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::strstr: -- case LibFunc::strpbrk: -+ case LibFunc_strstr: -+ case LibFunc_strpbrk: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::strtok: -- case LibFunc::strtok_r: -+ case LibFunc_strtok: -+ case LibFunc_strtok_r: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::scanf: -+ case LibFunc_scanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::setbuf: -- case LibFunc::setvbuf: -+ case LibFunc_setbuf: -+ case LibFunc_setvbuf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::strdup: -- case LibFunc::strndup: -+ case LibFunc_strdup: -+ case LibFunc_strndup: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::stat: -- case LibFunc::statvfs: -+ case LibFunc_stat: -+ case LibFunc_statvfs: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::sscanf: -+ case LibFunc_sscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::sprintf: -+ case LibFunc_sprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::snprintf: -+ case LibFunc_snprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 3); - Changed |= setOnlyReadsMemory(F, 3); - return Changed; -- case LibFunc::setitimer: -+ case LibFunc_setitimer: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setDoesNotCapture(F, 3); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::system: -+ case LibFunc_system: - // May throw; "system" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::malloc: -+ case LibFunc_malloc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::memcmp: -+ case LibFunc_memcmp: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::memchr: -- case LibFunc::memrchr: -+ case LibFunc_memchr: -+ case LibFunc_memrchr: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - return Changed; -- case LibFunc::modf: -- case LibFunc::modff: -- case LibFunc::modfl: -+ case LibFunc_modf: -+ case LibFunc_modff: -+ case LibFunc_modfl: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::memcpy: -- case LibFunc::mempcpy: -- case LibFunc::memccpy: -- case LibFunc::memmove: -+ case LibFunc_memcpy: -+ case LibFunc_mempcpy: -+ case LibFunc_memccpy: -+ case LibFunc_memmove: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::memcpy_chk: -+ case LibFunc_memcpy_chk: - Changed |= setDoesNotThrow(F); - return Changed; -- case LibFunc::memalign: -+ case LibFunc_memalign: - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::mkdir: -+ case LibFunc_mkdir: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::mktime: -+ case LibFunc_mktime: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::realloc: -+ case LibFunc_realloc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::read: -+ case LibFunc_read: - // May throw; "read" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::rewind: -+ case LibFunc_rewind: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::rmdir: -- case LibFunc::remove: -- case LibFunc::realpath: -+ case LibFunc_rmdir: -+ case LibFunc_remove: -+ case LibFunc_realpath: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::rename: -+ case LibFunc_rename: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::readlink: -+ case LibFunc_readlink: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::write: -+ case LibFunc_write: - // May throw; "write" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::bcopy: -+ case LibFunc_bcopy: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::bcmp: -+ case LibFunc_bcmp: - Changed |= setDoesNotThrow(F); - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::bzero: -+ case LibFunc_bzero: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::calloc: -+ case LibFunc_calloc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::chmod: -- case LibFunc::chown: -+ case LibFunc_chmod: -+ case LibFunc_chown: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::ctermid: -- case LibFunc::clearerr: -- case LibFunc::closedir: -+ case LibFunc_ctermid: -+ case LibFunc_clearerr: -+ case LibFunc_closedir: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::atoi: -- case LibFunc::atol: -- case LibFunc::atof: -- case LibFunc::atoll: -+ case LibFunc_atoi: -+ case LibFunc_atol: -+ case LibFunc_atof: -+ case LibFunc_atoll: - Changed |= setDoesNotThrow(F); - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::access: -+ case LibFunc_access: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::fopen: -+ case LibFunc_fopen: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); -@@ -363,150 +363,150 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::fdopen: -+ case LibFunc_fdopen: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::feof: -- case LibFunc::free: -- case LibFunc::fseek: -- case LibFunc::ftell: -- case LibFunc::fgetc: -- case LibFunc::fseeko: -- case LibFunc::ftello: -- case LibFunc::fileno: -- case LibFunc::fflush: -- case LibFunc::fclose: -- case LibFunc::fsetpos: -- case LibFunc::flockfile: -- case LibFunc::funlockfile: -- case LibFunc::ftrylockfile: -+ case LibFunc_feof: -+ case LibFunc_free: -+ case LibFunc_fseek: -+ case LibFunc_ftell: -+ case LibFunc_fgetc: -+ case LibFunc_fseeko: -+ case LibFunc_ftello: -+ case LibFunc_fileno: -+ case LibFunc_fflush: -+ case LibFunc_fclose: -+ case LibFunc_fsetpos: -+ case LibFunc_flockfile: -+ case LibFunc_funlockfile: -+ case LibFunc_ftrylockfile: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::ferror: -+ case LibFunc_ferror: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F); - return Changed; -- case LibFunc::fputc: -- case LibFunc::fstat: -- case LibFunc::frexp: -- case LibFunc::frexpf: -- case LibFunc::frexpl: -- case LibFunc::fstatvfs: -+ case LibFunc_fputc: -+ case LibFunc_fstat: -+ case LibFunc_frexp: -+ case LibFunc_frexpf: -+ case LibFunc_frexpl: -+ case LibFunc_fstatvfs: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::fgets: -+ case LibFunc_fgets: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 3); - return Changed; -- case LibFunc::fread: -+ case LibFunc_fread: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 4); - return Changed; -- case LibFunc::fwrite: -+ case LibFunc_fwrite: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 4); - // FIXME: readonly #1? - return Changed; -- case LibFunc::fputs: -+ case LibFunc_fputs: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::fscanf: -- case LibFunc::fprintf: -+ case LibFunc_fscanf: -+ case LibFunc_fprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::fgetpos: -+ case LibFunc_fgetpos: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::getc: -- case LibFunc::getlogin_r: -- case LibFunc::getc_unlocked: -+ case LibFunc_getc: -+ case LibFunc_getlogin_r: -+ case LibFunc_getc_unlocked: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::getenv: -+ case LibFunc_getenv: - Changed |= setDoesNotThrow(F); - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::gets: -- case LibFunc::getchar: -+ case LibFunc_gets: -+ case LibFunc_getchar: - Changed |= setDoesNotThrow(F); - return Changed; -- case LibFunc::getitimer: -+ case LibFunc_getitimer: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::getpwnam: -+ case LibFunc_getpwnam: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::ungetc: -+ case LibFunc_ungetc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::uname: -+ case LibFunc_uname: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::unlink: -+ case LibFunc_unlink: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::unsetenv: -+ case LibFunc_unsetenv: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::utime: -- case LibFunc::utimes: -+ case LibFunc_utime: -+ case LibFunc_utimes: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::putc: -+ case LibFunc_putc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::puts: -- case LibFunc::printf: -- case LibFunc::perror: -+ case LibFunc_puts: -+ case LibFunc_printf: -+ case LibFunc_perror: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::pread: -+ case LibFunc_pread: - // May throw; "pread" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::pwrite: -+ case LibFunc_pwrite: - // May throw; "pwrite" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::putchar: -+ case LibFunc_putchar: - Changed |= setDoesNotThrow(F); - return Changed; -- case LibFunc::popen: -+ case LibFunc_popen: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); -@@ -514,132 +514,132 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::pclose: -+ case LibFunc_pclose: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::vscanf: -+ case LibFunc_vscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::vsscanf: -+ case LibFunc_vsscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::vfscanf: -+ case LibFunc_vfscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::valloc: -+ case LibFunc_valloc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::vprintf: -+ case LibFunc_vprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::vfprintf: -- case LibFunc::vsprintf: -+ case LibFunc_vfprintf: -+ case LibFunc_vsprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::vsnprintf: -+ case LibFunc_vsnprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 3); - Changed |= setOnlyReadsMemory(F, 3); - return Changed; -- case LibFunc::open: -+ case LibFunc_open: - // May throw; "open" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::opendir: -+ case LibFunc_opendir: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::tmpfile: -+ case LibFunc_tmpfile: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::times: -+ case LibFunc_times: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::htonl: -- case LibFunc::htons: -- case LibFunc::ntohl: -- case LibFunc::ntohs: -+ case LibFunc_htonl: -+ case LibFunc_htons: -+ case LibFunc_ntohl: -+ case LibFunc_ntohs: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAccessMemory(F); - return Changed; -- case LibFunc::lstat: -+ case LibFunc_lstat: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::lchown: -+ case LibFunc_lchown: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::qsort: -+ case LibFunc_qsort: - // May throw; places call through function pointer. - Changed |= setDoesNotCapture(F, 4); - return Changed; -- case LibFunc::dunder_strdup: -- case LibFunc::dunder_strndup: -+ case LibFunc_dunder_strdup: -+ case LibFunc_dunder_strndup: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::dunder_strtok_r: -+ case LibFunc_dunder_strtok_r: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::under_IO_getc: -+ case LibFunc_under_IO_getc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::under_IO_putc: -+ case LibFunc_under_IO_putc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::dunder_isoc99_scanf: -+ case LibFunc_dunder_isoc99_scanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::stat64: -- case LibFunc::lstat64: -- case LibFunc::statvfs64: -+ case LibFunc_stat64: -+ case LibFunc_lstat64: -+ case LibFunc_statvfs64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::dunder_isoc99_sscanf: -+ case LibFunc_dunder_isoc99_sscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::fopen64: -+ case LibFunc_fopen64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - Changed |= setDoesNotCapture(F, 1); -@@ -647,26 +647,26 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { - Changed |= setOnlyReadsMemory(F, 1); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; -- case LibFunc::fseeko64: -- case LibFunc::ftello64: -+ case LibFunc_fseeko64: -+ case LibFunc_ftello64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; -- case LibFunc::tmpfile64: -+ case LibFunc_tmpfile64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAlias(F, 0); - return Changed; -- case LibFunc::fstat64: -- case LibFunc::fstatvfs64: -+ case LibFunc_fstat64: -+ case LibFunc_fstatvfs64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::open64: -+ case LibFunc_open64: - // May throw; "open" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; -- case LibFunc::gettimeofday: -+ case LibFunc_gettimeofday: - // Currently some platforms have the restrict keyword on the arguments to - // gettimeofday. To be conservative, do not add noalias to gettimeofday's - // arguments. -@@ -674,29 +674,29 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - return Changed; -- case LibFunc::Znwj: // new(unsigned int) -- case LibFunc::Znwm: // new(unsigned long) -- case LibFunc::Znaj: // new[](unsigned int) -- case LibFunc::Znam: // new[](unsigned long) -- case LibFunc::msvc_new_int: // new(unsigned int) -- case LibFunc::msvc_new_longlong: // new(unsigned long long) -- case LibFunc::msvc_new_array_int: // new[](unsigned int) -- case LibFunc::msvc_new_array_longlong: // new[](unsigned long long) -+ case LibFunc_Znwj: // new(unsigned int) -+ case LibFunc_Znwm: // new(unsigned long) -+ case LibFunc_Znaj: // new[](unsigned int) -+ case LibFunc_Znam: // new[](unsigned long) -+ case LibFunc_msvc_new_int: // new(unsigned int) -+ case LibFunc_msvc_new_longlong: // new(unsigned long long) -+ case LibFunc_msvc_new_array_int: // new[](unsigned int) -+ case LibFunc_msvc_new_array_longlong: // new[](unsigned long long) - // Operator new always returns a nonnull noalias pointer - Changed |= setNonNull(F, AttributeSet::ReturnIndex); - Changed |= setDoesNotAlias(F, AttributeSet::ReturnIndex); - return Changed; - //TODO: add LibFunc entries for: -- //case LibFunc::memset_pattern4: -- //case LibFunc::memset_pattern8: -- case LibFunc::memset_pattern16: -+ //case LibFunc_memset_pattern4: -+ //case LibFunc_memset_pattern8: -+ case LibFunc_memset_pattern16: - Changed |= setOnlyAccessesArgMemory(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; - // int __nvvm_reflect(const char *) -- case LibFunc::nvvm_reflect: -+ case LibFunc_nvvm_reflect: - Changed |= setDoesNotAccessMemory(F); - Changed |= setDoesNotThrow(F); - return Changed; -@@ -717,7 +717,7 @@ Value *llvm::castToCStr(Value *V, IRBuilder<> &B) { - - Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::strlen)) -+ if (!TLI->has(LibFunc_strlen)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -734,7 +734,7 @@ Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL, - - Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::strchr)) -+ if (!TLI->has(LibFunc_strchr)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -752,7 +752,7 @@ Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B, - - Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::strncmp)) -+ if (!TLI->has(LibFunc_strncmp)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -772,7 +772,7 @@ Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - - Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, - const TargetLibraryInfo *TLI, StringRef Name) { -- if (!TLI->has(LibFunc::strcpy)) -+ if (!TLI->has(LibFunc_strcpy)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -788,7 +788,7 @@ Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, - - Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, - const TargetLibraryInfo *TLI, StringRef Name) { -- if (!TLI->has(LibFunc::strncpy)) -+ if (!TLI->has(LibFunc_strncpy)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -806,7 +806,7 @@ Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, - Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, - IRBuilder<> &B, const DataLayout &DL, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::memcpy_chk)) -+ if (!TLI->has(LibFunc_memcpy_chk)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -828,7 +828,7 @@ Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, - - Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::memchr)) -+ if (!TLI->has(LibFunc_memchr)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -847,7 +847,7 @@ Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, - - Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::memcmp)) -+ if (!TLI->has(LibFunc_memcmp)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -914,7 +914,7 @@ Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name, - - Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::putchar)) -+ if (!TLI->has(LibFunc_putchar)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -934,7 +934,7 @@ Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B, - - Value *llvm::emitPutS(Value *Str, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::puts)) -+ if (!TLI->has(LibFunc_puts)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -949,7 +949,7 @@ Value *llvm::emitPutS(Value *Str, IRBuilder<> &B, - - Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::fputc)) -+ if (!TLI->has(LibFunc_fputc)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -@@ -968,11 +968,11 @@ Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B, - - Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::fputs)) -+ if (!TLI->has(LibFunc_fputs)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); -- StringRef FPutsName = TLI->getName(LibFunc::fputs); -+ StringRef FPutsName = TLI->getName(LibFunc_fputs); - Constant *F = M->getOrInsertFunction( - FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType(), nullptr); - if (File->getType()->isPointerTy()) -@@ -986,12 +986,12 @@ Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B, - - Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { -- if (!TLI->has(LibFunc::fwrite)) -+ if (!TLI->has(LibFunc_fwrite)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - LLVMContext &Context = B.GetInsertBlock()->getContext(); -- StringRef FWriteName = TLI->getName(LibFunc::fwrite); -+ StringRef FWriteName = TLI->getName(LibFunc_fwrite); - Constant *F = M->getOrInsertFunction( - FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(), - DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType(), -diff --git a/lib/Transforms/Utils/LibCallsShrinkWrap.cpp b/lib/Transforms/Utils/LibCallsShrinkWrap.cpp -index d97cd7582ea..fe93d6927c6 100644 ---- a/lib/Transforms/Utils/LibCallsShrinkWrap.cpp -+++ b/lib/Transforms/Utils/LibCallsShrinkWrap.cpp -@@ -100,12 +100,12 @@ private: - bool perform(CallInst *CI); - void checkCandidate(CallInst &CI); - void shrinkWrapCI(CallInst *CI, Value *Cond); -- bool performCallDomainErrorOnly(CallInst *CI, const LibFunc::Func &Func); -- bool performCallErrors(CallInst *CI, const LibFunc::Func &Func); -- bool performCallRangeErrorOnly(CallInst *CI, const LibFunc::Func &Func); -- Value *generateOneRangeCond(CallInst *CI, const LibFunc::Func &Func); -- Value *generateTwoRangeCond(CallInst *CI, const LibFunc::Func &Func); -- Value *generateCondForPow(CallInst *CI, const LibFunc::Func &Func); -+ bool performCallDomainErrorOnly(CallInst *CI, const LibFunc &Func); -+ bool performCallErrors(CallInst *CI, const LibFunc &Func); -+ bool performCallRangeErrorOnly(CallInst *CI, const LibFunc &Func); -+ Value *generateOneRangeCond(CallInst *CI, const LibFunc &Func); -+ Value *generateTwoRangeCond(CallInst *CI, const LibFunc &Func); -+ Value *generateCondForPow(CallInst *CI, const LibFunc &Func); - - // Create an OR of two conditions. - Value *createOrCond(CallInst *CI, CmpInst::Predicate Cmp, float Val, -@@ -141,44 +141,44 @@ private: - - // Perform the transformation to calls with errno set by domain error. - bool LibCallsShrinkWrap::performCallDomainErrorOnly(CallInst *CI, -- const LibFunc::Func &Func) { -+ const LibFunc &Func) { - Value *Cond = nullptr; - - switch (Func) { -- case LibFunc::acos: // DomainError: (x < -1 || x > 1) -- case LibFunc::acosf: // Same as acos -- case LibFunc::acosl: // Same as acos -- case LibFunc::asin: // DomainError: (x < -1 || x > 1) -- case LibFunc::asinf: // Same as asin -- case LibFunc::asinl: // Same as asin -+ case LibFunc_acos: // DomainError: (x < -1 || x > 1) -+ case LibFunc_acosf: // Same as acos -+ case LibFunc_acosl: // Same as acos -+ case LibFunc_asin: // DomainError: (x < -1 || x > 1) -+ case LibFunc_asinf: // Same as asin -+ case LibFunc_asinl: // Same as asin - { - ++NumWrappedTwoCond; - Cond = createOrCond(CI, CmpInst::FCMP_OLT, -1.0f, CmpInst::FCMP_OGT, 1.0f); - break; - } -- case LibFunc::cos: // DomainError: (x == +inf || x == -inf) -- case LibFunc::cosf: // Same as cos -- case LibFunc::cosl: // Same as cos -- case LibFunc::sin: // DomainError: (x == +inf || x == -inf) -- case LibFunc::sinf: // Same as sin -- case LibFunc::sinl: // Same as sin -+ case LibFunc_cos: // DomainError: (x == +inf || x == -inf) -+ case LibFunc_cosf: // Same as cos -+ case LibFunc_cosl: // Same as cos -+ case LibFunc_sin: // DomainError: (x == +inf || x == -inf) -+ case LibFunc_sinf: // Same as sin -+ case LibFunc_sinl: // Same as sin - { - ++NumWrappedTwoCond; - Cond = createOrCond(CI, CmpInst::FCMP_OEQ, INFINITY, CmpInst::FCMP_OEQ, - -INFINITY); - break; - } -- case LibFunc::acosh: // DomainError: (x < 1) -- case LibFunc::acoshf: // Same as acosh -- case LibFunc::acoshl: // Same as acosh -+ case LibFunc_acosh: // DomainError: (x < 1) -+ case LibFunc_acoshf: // Same as acosh -+ case LibFunc_acoshl: // Same as acosh - { - ++NumWrappedOneCond; - Cond = createCond(CI, CmpInst::FCMP_OLT, 1.0f); - break; - } -- case LibFunc::sqrt: // DomainError: (x < 0) -- case LibFunc::sqrtf: // Same as sqrt -- case LibFunc::sqrtl: // Same as sqrt -+ case LibFunc_sqrt: // DomainError: (x < 0) -+ case LibFunc_sqrtf: // Same as sqrt -+ case LibFunc_sqrtl: // Same as sqrt - { - ++NumWrappedOneCond; - Cond = createCond(CI, CmpInst::FCMP_OLT, 0.0f); -@@ -193,31 +193,31 @@ bool LibCallsShrinkWrap::performCallDomainErrorOnly(CallInst *CI, - - // Perform the transformation to calls with errno set by range error. - bool LibCallsShrinkWrap::performCallRangeErrorOnly(CallInst *CI, -- const LibFunc::Func &Func) { -+ const LibFunc &Func) { - Value *Cond = nullptr; - - switch (Func) { -- case LibFunc::cosh: -- case LibFunc::coshf: -- case LibFunc::coshl: -- case LibFunc::exp: -- case LibFunc::expf: -- case LibFunc::expl: -- case LibFunc::exp10: -- case LibFunc::exp10f: -- case LibFunc::exp10l: -- case LibFunc::exp2: -- case LibFunc::exp2f: -- case LibFunc::exp2l: -- case LibFunc::sinh: -- case LibFunc::sinhf: -- case LibFunc::sinhl: { -+ case LibFunc_cosh: -+ case LibFunc_coshf: -+ case LibFunc_coshl: -+ case LibFunc_exp: -+ case LibFunc_expf: -+ case LibFunc_expl: -+ case LibFunc_exp10: -+ case LibFunc_exp10f: -+ case LibFunc_exp10l: -+ case LibFunc_exp2: -+ case LibFunc_exp2f: -+ case LibFunc_exp2l: -+ case LibFunc_sinh: -+ case LibFunc_sinhf: -+ case LibFunc_sinhl: { - Cond = generateTwoRangeCond(CI, Func); - break; - } -- case LibFunc::expm1: // RangeError: (709, inf) -- case LibFunc::expm1f: // RangeError: (88, inf) -- case LibFunc::expm1l: // RangeError: (11356, inf) -+ case LibFunc_expm1: // RangeError: (709, inf) -+ case LibFunc_expm1f: // RangeError: (88, inf) -+ case LibFunc_expm1l: // RangeError: (11356, inf) - { - Cond = generateOneRangeCond(CI, Func); - break; -@@ -231,15 +231,15 @@ bool LibCallsShrinkWrap::performCallRangeErrorOnly(CallInst *CI, - - // Perform the transformation to calls with errno set by combination of errors. - bool LibCallsShrinkWrap::performCallErrors(CallInst *CI, -- const LibFunc::Func &Func) { -+ const LibFunc &Func) { - Value *Cond = nullptr; - - switch (Func) { -- case LibFunc::atanh: // DomainError: (x < -1 || x > 1) -+ case LibFunc_atanh: // DomainError: (x < -1 || x > 1) - // PoleError: (x == -1 || x == 1) - // Overall Cond: (x <= -1 || x >= 1) -- case LibFunc::atanhf: // Same as atanh -- case LibFunc::atanhl: // Same as atanh -+ case LibFunc_atanhf: // Same as atanh -+ case LibFunc_atanhl: // Same as atanh - { - if (!LibCallsShrinkWrapDoDomainError || !LibCallsShrinkWrapDoPoleError) - return false; -@@ -247,20 +247,20 @@ bool LibCallsShrinkWrap::performCallErrors(CallInst *CI, - Cond = createOrCond(CI, CmpInst::FCMP_OLE, -1.0f, CmpInst::FCMP_OGE, 1.0f); - break; - } -- case LibFunc::log: // DomainError: (x < 0) -+ case LibFunc_log: // DomainError: (x < 0) - // PoleError: (x == 0) - // Overall Cond: (x <= 0) -- case LibFunc::logf: // Same as log -- case LibFunc::logl: // Same as log -- case LibFunc::log10: // Same as log -- case LibFunc::log10f: // Same as log -- case LibFunc::log10l: // Same as log -- case LibFunc::log2: // Same as log -- case LibFunc::log2f: // Same as log -- case LibFunc::log2l: // Same as log -- case LibFunc::logb: // Same as log -- case LibFunc::logbf: // Same as log -- case LibFunc::logbl: // Same as log -+ case LibFunc_logf: // Same as log -+ case LibFunc_logl: // Same as log -+ case LibFunc_log10: // Same as log -+ case LibFunc_log10f: // Same as log -+ case LibFunc_log10l: // Same as log -+ case LibFunc_log2: // Same as log -+ case LibFunc_log2f: // Same as log -+ case LibFunc_log2l: // Same as log -+ case LibFunc_logb: // Same as log -+ case LibFunc_logbf: // Same as log -+ case LibFunc_logbl: // Same as log - { - if (!LibCallsShrinkWrapDoDomainError || !LibCallsShrinkWrapDoPoleError) - return false; -@@ -268,11 +268,11 @@ bool LibCallsShrinkWrap::performCallErrors(CallInst *CI, - Cond = createCond(CI, CmpInst::FCMP_OLE, 0.0f); - break; - } -- case LibFunc::log1p: // DomainError: (x < -1) -+ case LibFunc_log1p: // DomainError: (x < -1) - // PoleError: (x == -1) - // Overall Cond: (x <= -1) -- case LibFunc::log1pf: // Same as log1p -- case LibFunc::log1pl: // Same as log1p -+ case LibFunc_log1pf: // Same as log1p -+ case LibFunc_log1pl: // Same as log1p - { - if (!LibCallsShrinkWrapDoDomainError || !LibCallsShrinkWrapDoPoleError) - return false; -@@ -280,11 +280,11 @@ bool LibCallsShrinkWrap::performCallErrors(CallInst *CI, - Cond = createCond(CI, CmpInst::FCMP_OLE, -1.0f); - break; - } -- case LibFunc::pow: // DomainError: x < 0 and y is noninteger -+ case LibFunc_pow: // DomainError: x < 0 and y is noninteger - // PoleError: x == 0 and y < 0 - // RangeError: overflow or underflow -- case LibFunc::powf: -- case LibFunc::powl: { -+ case LibFunc_powf: -+ case LibFunc_powl: { - if (!LibCallsShrinkWrapDoDomainError || !LibCallsShrinkWrapDoPoleError || - !LibCallsShrinkWrapDoRangeError) - return false; -@@ -313,7 +313,7 @@ void LibCallsShrinkWrap::checkCandidate(CallInst &CI) { - if (!CI.use_empty()) - return; - -- LibFunc::Func Func; -+ LibFunc Func; - Function *Callee = CI.getCalledFunction(); - if (!Callee) - return; -@@ -333,16 +333,16 @@ void LibCallsShrinkWrap::checkCandidate(CallInst &CI) { - - // Generate the upper bound condition for RangeError. - Value *LibCallsShrinkWrap::generateOneRangeCond(CallInst *CI, -- const LibFunc::Func &Func) { -+ const LibFunc &Func) { - float UpperBound; - switch (Func) { -- case LibFunc::expm1: // RangeError: (709, inf) -+ case LibFunc_expm1: // RangeError: (709, inf) - UpperBound = 709.0f; - break; -- case LibFunc::expm1f: // RangeError: (88, inf) -+ case LibFunc_expm1f: // RangeError: (88, inf) - UpperBound = 88.0f; - break; -- case LibFunc::expm1l: // RangeError: (11356, inf) -+ case LibFunc_expm1l: // RangeError: (11356, inf) - UpperBound = 11356.0f; - break; - default: -@@ -355,57 +355,57 @@ Value *LibCallsShrinkWrap::generateOneRangeCond(CallInst *CI, - - // Generate the lower and upper bound condition for RangeError. - Value *LibCallsShrinkWrap::generateTwoRangeCond(CallInst *CI, -- const LibFunc::Func &Func) { -+ const LibFunc &Func) { - float UpperBound, LowerBound; - switch (Func) { -- case LibFunc::cosh: // RangeError: (x < -710 || x > 710) -- case LibFunc::sinh: // Same as cosh -+ case LibFunc_cosh: // RangeError: (x < -710 || x > 710) -+ case LibFunc_sinh: // Same as cosh - LowerBound = -710.0f; - UpperBound = 710.0f; - break; -- case LibFunc::coshf: // RangeError: (x < -89 || x > 89) -- case LibFunc::sinhf: // Same as coshf -+ case LibFunc_coshf: // RangeError: (x < -89 || x > 89) -+ case LibFunc_sinhf: // Same as coshf - LowerBound = -89.0f; - UpperBound = 89.0f; - break; -- case LibFunc::coshl: // RangeError: (x < -11357 || x > 11357) -- case LibFunc::sinhl: // Same as coshl -+ case LibFunc_coshl: // RangeError: (x < -11357 || x > 11357) -+ case LibFunc_sinhl: // Same as coshl - LowerBound = -11357.0f; - UpperBound = 11357.0f; - break; -- case LibFunc::exp: // RangeError: (x < -745 || x > 709) -+ case LibFunc_exp: // RangeError: (x < -745 || x > 709) - LowerBound = -745.0f; - UpperBound = 709.0f; - break; -- case LibFunc::expf: // RangeError: (x < -103 || x > 88) -+ case LibFunc_expf: // RangeError: (x < -103 || x > 88) - LowerBound = -103.0f; - UpperBound = 88.0f; - break; -- case LibFunc::expl: // RangeError: (x < -11399 || x > 11356) -+ case LibFunc_expl: // RangeError: (x < -11399 || x > 11356) - LowerBound = -11399.0f; - UpperBound = 11356.0f; - break; -- case LibFunc::exp10: // RangeError: (x < -323 || x > 308) -+ case LibFunc_exp10: // RangeError: (x < -323 || x > 308) - LowerBound = -323.0f; - UpperBound = 308.0f; - break; -- case LibFunc::exp10f: // RangeError: (x < -45 || x > 38) -+ case LibFunc_exp10f: // RangeError: (x < -45 || x > 38) - LowerBound = -45.0f; - UpperBound = 38.0f; - break; -- case LibFunc::exp10l: // RangeError: (x < -4950 || x > 4932) -+ case LibFunc_exp10l: // RangeError: (x < -4950 || x > 4932) - LowerBound = -4950.0f; - UpperBound = 4932.0f; - break; -- case LibFunc::exp2: // RangeError: (x < -1074 || x > 1023) -+ case LibFunc_exp2: // RangeError: (x < -1074 || x > 1023) - LowerBound = -1074.0f; - UpperBound = 1023.0f; - break; -- case LibFunc::exp2f: // RangeError: (x < -149 || x > 127) -+ case LibFunc_exp2f: // RangeError: (x < -149 || x > 127) - LowerBound = -149.0f; - UpperBound = 127.0f; - break; -- case LibFunc::exp2l: // RangeError: (x < -16445 || x > 11383) -+ case LibFunc_exp2l: // RangeError: (x < -16445 || x > 11383) - LowerBound = -16445.0f; - UpperBound = 11383.0f; - break; -@@ -434,9 +434,9 @@ Value *LibCallsShrinkWrap::generateTwoRangeCond(CallInst *CI, - // (i.e. we might invoke the calls that will not set the errno.). - // - Value *LibCallsShrinkWrap::generateCondForPow(CallInst *CI, -- const LibFunc::Func &Func) { -- // FIXME: LibFunc::powf and powl TBD. -- if (Func != LibFunc::pow) { -+ const LibFunc &Func) { -+ // FIXME: LibFunc_powf and powl TBD. -+ if (Func != LibFunc_pow) { - DEBUG(dbgs() << "Not handled powf() and powl()\n"); - return nullptr; - } -@@ -516,7 +516,7 @@ void LibCallsShrinkWrap::shrinkWrapCI(CallInst *CI, Value *Cond) { - - // Perform the transformation to a single candidate. - bool LibCallsShrinkWrap::perform(CallInst *CI) { -- LibFunc::Func Func; -+ LibFunc Func; - Function *Callee = CI->getCalledFunction(); - assert(Callee && "perform() should apply to a non-empty callee"); - TLI.getLibFunc(*Callee, Func); -diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp -index 6e4174aa0cd..9e217fec20c 100644 ---- a/lib/Transforms/Utils/Local.cpp -+++ b/lib/Transforms/Utils/Local.cpp -@@ -2068,7 +2068,7 @@ bool llvm::recognizeBSwapOrBitReverseIdiom( - void llvm::maybeMarkSanitizerLibraryCallNoBuiltin( - CallInst *CI, const TargetLibraryInfo *TLI) { - Function *F = CI->getCalledFunction(); -- LibFunc::Func Func; -+ LibFunc Func; - if (F && !F->hasLocalLinkage() && F->hasName() && - TLI->getLibFunc(F->getName(), Func) && TLI->hasOptimizedCodeGen(Func) && - !F->doesNotAccessMemory()) -diff --git a/lib/Transforms/Utils/SimplifyLibCalls.cpp b/lib/Transforms/Utils/SimplifyLibCalls.cpp -index 8eaeb1073a7..81c8f61fd35 100644 ---- a/lib/Transforms/Utils/SimplifyLibCalls.cpp -+++ b/lib/Transforms/Utils/SimplifyLibCalls.cpp -@@ -51,9 +51,9 @@ static cl::opt - // Helper Functions - //===----------------------------------------------------------------------===// - --static bool ignoreCallingConv(LibFunc::Func Func) { -- return Func == LibFunc::abs || Func == LibFunc::labs || -- Func == LibFunc::llabs || Func == LibFunc::strlen; -+static bool ignoreCallingConv(LibFunc Func) { -+ return Func == LibFunc_abs || Func == LibFunc_labs || -+ Func == LibFunc_llabs || Func == LibFunc_strlen; - } - - static bool isCallingConvCCompatible(CallInst *CI) { -@@ -123,8 +123,8 @@ static bool callHasFloatingPointArgument(const CallInst *CI) { - /// \brief Check whether the overloaded unary floating point function - /// corresponding to \a Ty is available. - static bool hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty, -- LibFunc::Func DoubleFn, LibFunc::Func FloatFn, -- LibFunc::Func LongDoubleFn) { -+ LibFunc DoubleFn, LibFunc FloatFn, -+ LibFunc LongDoubleFn) { - switch (Ty->getTypeID()) { - case Type::FloatTyID: - return TLI->has(FloatFn); -@@ -811,7 +811,7 @@ Value *LibCallSimplifier::optimizeMemMove(CallInst *CI, IRBuilder<> &B) { - // functions be moved here? - static Value *emitCalloc(Value *Num, Value *Size, const AttributeSet &Attrs, - IRBuilder<> &B, const TargetLibraryInfo &TLI) { -- LibFunc::Func Func; -+ LibFunc Func; - if (!TLI.getLibFunc("calloc", Func) || !TLI.has(Func)) - return nullptr; - -@@ -846,9 +846,9 @@ static Value *foldMallocMemset(CallInst *Memset, IRBuilder<> &B, - - // Is the inner call really malloc()? - Function *InnerCallee = Malloc->getCalledFunction(); -- LibFunc::Func Func; -+ LibFunc Func; - if (!TLI.getLibFunc(*InnerCallee, Func) || !TLI.has(Func) || -- Func != LibFunc::malloc) -+ Func != LibFunc_malloc) - return nullptr; - - // The memset must cover the same number of bytes that are malloc'd. -@@ -1041,9 +1041,9 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { - if (ConstantFP *Op1C = dyn_cast(Op1)) { - // pow(10.0, x) -> exp10(x) - if (Op1C->isExactlyValue(10.0) && -- hasUnaryFloatFn(TLI, Op1->getType(), LibFunc::exp10, LibFunc::exp10f, -- LibFunc::exp10l)) -- return emitUnaryFloatFnCall(Op2, TLI->getName(LibFunc::exp10), B, -+ hasUnaryFloatFn(TLI, Op1->getType(), LibFunc_exp10, LibFunc_exp10f, -+ LibFunc_exp10l)) -+ return emitUnaryFloatFnCall(Op2, TLI->getName(LibFunc_exp10), B, - Callee->getAttributes()); - } - -@@ -1055,10 +1055,10 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { - // pow(exp(x), y) = pow(inf, 0.001) = inf, whereas exp(x*y) = exp(1). - auto *OpC = dyn_cast(Op1); - if (OpC && OpC->hasUnsafeAlgebra() && CI->hasUnsafeAlgebra()) { -- LibFunc::Func Func; -+ LibFunc Func; - Function *OpCCallee = OpC->getCalledFunction(); - if (OpCCallee && TLI->getLibFunc(OpCCallee->getName(), Func) && -- TLI->has(Func) && (Func == LibFunc::exp || Func == LibFunc::exp2)) { -+ TLI->has(Func) && (Func == LibFunc_exp || Func == LibFunc_exp2)) { - IRBuilder<>::FastMathFlagGuard Guard(B); - B.setFastMathFlags(CI->getFastMathFlags()); - Value *FMul = B.CreateFMul(OpC->getArgOperand(0), Op2, "mul"); -@@ -1075,8 +1075,8 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { - return ConstantFP::get(CI->getType(), 1.0); - - if (Op2C->isExactlyValue(-0.5) && -- hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf, -- LibFunc::sqrtl)) { -+ hasUnaryFloatFn(TLI, Op2->getType(), LibFunc_sqrt, LibFunc_sqrtf, -+ LibFunc_sqrtl)) { - // If -ffast-math: - // pow(x, -0.5) -> 1.0 / sqrt(x) - if (CI->hasUnsafeAlgebra()) { -@@ -1085,7 +1085,7 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { - - // Here we cannot lower to an intrinsic because C99 sqrt() and llvm.sqrt - // are not guaranteed to have the same semantics. -- Value *Sqrt = emitUnaryFloatFnCall(Op1, TLI->getName(LibFunc::sqrt), B, -+ Value *Sqrt = emitUnaryFloatFnCall(Op1, TLI->getName(LibFunc_sqrt), B, - Callee->getAttributes()); - - return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), Sqrt, "sqrtrecip"); -@@ -1093,10 +1093,10 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { - } - - if (Op2C->isExactlyValue(0.5) && -- hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf, -- LibFunc::sqrtl) && -- hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::fabs, LibFunc::fabsf, -- LibFunc::fabsl)) { -+ hasUnaryFloatFn(TLI, Op2->getType(), LibFunc_sqrt, LibFunc_sqrtf, -+ LibFunc_sqrtl) && -+ hasUnaryFloatFn(TLI, Op2->getType(), LibFunc_fabs, LibFunc_fabsf, -+ LibFunc_fabsl)) { - - // In -ffast-math, pow(x, 0.5) -> sqrt(x). - if (CI->hasUnsafeAlgebra()) { -@@ -1105,7 +1105,7 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { - - // Unlike other math intrinsics, sqrt has differerent semantics - // from the libc function. See LangRef for details. -- return emitUnaryFloatFnCall(Op1, TLI->getName(LibFunc::sqrt), B, -+ return emitUnaryFloatFnCall(Op1, TLI->getName(LibFunc_sqrt), B, - Callee->getAttributes()); - } - -@@ -1173,11 +1173,11 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilder<> &B) { - Value *Op = CI->getArgOperand(0); - // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32 - // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32 -- LibFunc::Func LdExp = LibFunc::ldexpl; -+ LibFunc LdExp = LibFunc_ldexpl; - if (Op->getType()->isFloatTy()) -- LdExp = LibFunc::ldexpf; -+ LdExp = LibFunc_ldexpf; - else if (Op->getType()->isDoubleTy()) -- LdExp = LibFunc::ldexp; -+ LdExp = LibFunc_ldexp; - - if (TLI->has(LdExp)) { - Value *LdExpArg = nullptr; -@@ -1280,17 +1280,17 @@ Value *LibCallSimplifier::optimizeLog(CallInst *CI, IRBuilder<> &B) { - FMF.setUnsafeAlgebra(); - B.setFastMathFlags(FMF); - -- LibFunc::Func Func; -+ LibFunc Func; - Function *F = OpC->getCalledFunction(); - if (F && ((TLI->getLibFunc(F->getName(), Func) && TLI->has(Func) && -- Func == LibFunc::pow) || F->getIntrinsicID() == Intrinsic::pow)) -+ Func == LibFunc_pow) || F->getIntrinsicID() == Intrinsic::pow)) - return B.CreateFMul(OpC->getArgOperand(1), - emitUnaryFloatFnCall(OpC->getOperand(0), Callee->getName(), B, - Callee->getAttributes()), "mul"); - - // log(exp2(y)) -> y*log(2) - if (F && Name == "log" && TLI->getLibFunc(F->getName(), Func) && -- TLI->has(Func) && Func == LibFunc::exp2) -+ TLI->has(Func) && Func == LibFunc_exp2) - return B.CreateFMul( - OpC->getArgOperand(0), - emitUnaryFloatFnCall(ConstantFP::get(CI->getType(), 2.0), -@@ -1302,8 +1302,8 @@ Value *LibCallSimplifier::optimizeLog(CallInst *CI, IRBuilder<> &B) { - Value *LibCallSimplifier::optimizeSqrt(CallInst *CI, IRBuilder<> &B) { - Function *Callee = CI->getCalledFunction(); - Value *Ret = nullptr; -- if (TLI->has(LibFunc::sqrtf) && (Callee->getName() == "sqrt" || -- Callee->getIntrinsicID() == Intrinsic::sqrt)) -+ if (TLI->has(LibFunc_sqrtf) && (Callee->getName() == "sqrt" || -+ Callee->getIntrinsicID() == Intrinsic::sqrt)) - Ret = optimizeUnaryDoubleFP(CI, B, true); - - if (!CI->hasUnsafeAlgebra()) -@@ -1385,12 +1385,12 @@ Value *LibCallSimplifier::optimizeTan(CallInst *CI, IRBuilder<> &B) { - // tan(atan(x)) -> x - // tanf(atanf(x)) -> x - // tanl(atanl(x)) -> x -- LibFunc::Func Func; -+ LibFunc Func; - Function *F = OpC->getCalledFunction(); - if (F && TLI->getLibFunc(F->getName(), Func) && TLI->has(Func) && -- ((Func == LibFunc::atan && Callee->getName() == "tan") || -- (Func == LibFunc::atanf && Callee->getName() == "tanf") || -- (Func == LibFunc::atanl && Callee->getName() == "tanl"))) -+ ((Func == LibFunc_atan && Callee->getName() == "tan") || -+ (Func == LibFunc_atanf && Callee->getName() == "tanf") || -+ (Func == LibFunc_atanl && Callee->getName() == "tanl"))) - Ret = OpC->getArgOperand(0); - return Ret; - } -@@ -1508,24 +1508,24 @@ void LibCallSimplifier::classifyArgUse( - return; - - Function *Callee = CI->getCalledFunction(); -- LibFunc::Func Func; -+ LibFunc Func; - if (!Callee || !TLI->getLibFunc(*Callee, Func) || !TLI->has(Func) || - !isTrigLibCall(CI)) - return; - - if (IsFloat) { -- if (Func == LibFunc::sinpif) -+ if (Func == LibFunc_sinpif) - SinCalls.push_back(CI); -- else if (Func == LibFunc::cospif) -+ else if (Func == LibFunc_cospif) - CosCalls.push_back(CI); -- else if (Func == LibFunc::sincospif_stret) -+ else if (Func == LibFunc_sincospif_stret) - SinCosCalls.push_back(CI); - } else { -- if (Func == LibFunc::sinpi) -+ if (Func == LibFunc_sinpi) - SinCalls.push_back(CI); -- else if (Func == LibFunc::cospi) -+ else if (Func == LibFunc_cospi) - CosCalls.push_back(CI); -- else if (Func == LibFunc::sincospi_stret) -+ else if (Func == LibFunc_sincospi_stret) - SinCosCalls.push_back(CI); - } - } -@@ -1699,7 +1699,7 @@ Value *LibCallSimplifier::optimizePrintF(CallInst *CI, IRBuilder<> &B) { - - // printf(format, ...) -> iprintf(format, ...) if no floating point - // arguments. -- if (TLI->has(LibFunc::iprintf) && !callHasFloatingPointArgument(CI)) { -+ if (TLI->has(LibFunc_iprintf) && !callHasFloatingPointArgument(CI)) { - Module *M = B.GetInsertBlock()->getParent()->getParent(); - Constant *IPrintFFn = - M->getOrInsertFunction("iprintf", FT, Callee->getAttributes()); -@@ -1780,7 +1780,7 @@ Value *LibCallSimplifier::optimizeSPrintF(CallInst *CI, IRBuilder<> &B) { - - // sprintf(str, format, ...) -> siprintf(str, format, ...) if no floating - // point arguments. -- if (TLI->has(LibFunc::siprintf) && !callHasFloatingPointArgument(CI)) { -+ if (TLI->has(LibFunc_siprintf) && !callHasFloatingPointArgument(CI)) { - Module *M = B.GetInsertBlock()->getParent()->getParent(); - Constant *SIPrintFFn = - M->getOrInsertFunction("siprintf", FT, Callee->getAttributes()); -@@ -1850,7 +1850,7 @@ Value *LibCallSimplifier::optimizeFPrintF(CallInst *CI, IRBuilder<> &B) { - - // fprintf(stream, format, ...) -> fiprintf(stream, format, ...) if no - // floating point arguments. -- if (TLI->has(LibFunc::fiprintf) && !callHasFloatingPointArgument(CI)) { -+ if (TLI->has(LibFunc_fiprintf) && !callHasFloatingPointArgument(CI)) { - Module *M = B.GetInsertBlock()->getParent()->getParent(); - Constant *FIPrintFFn = - M->getOrInsertFunction("fiprintf", FT, Callee->getAttributes()); -@@ -1929,7 +1929,7 @@ Value *LibCallSimplifier::optimizePuts(CallInst *CI, IRBuilder<> &B) { - } - - bool LibCallSimplifier::hasFloatVersion(StringRef FuncName) { -- LibFunc::Func Func; -+ LibFunc Func; - SmallString<20> FloatFuncName = FuncName; - FloatFuncName += 'f'; - if (TLI->getLibFunc(FloatFuncName, Func)) -@@ -1939,7 +1939,7 @@ bool LibCallSimplifier::hasFloatVersion(StringRef FuncName) { - - Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI, - IRBuilder<> &Builder) { -- LibFunc::Func Func; -+ LibFunc Func; - Function *Callee = CI->getCalledFunction(); - // Check for string/memory library functions. - if (TLI->getLibFunc(*Callee, Func) && TLI->has(Func)) { -@@ -1948,51 +1948,51 @@ Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI, - isCallingConvCCompatible(CI)) && - "Optimizing string/memory libcall would change the calling convention"); - switch (Func) { -- case LibFunc::strcat: -+ case LibFunc_strcat: - return optimizeStrCat(CI, Builder); -- case LibFunc::strncat: -+ case LibFunc_strncat: - return optimizeStrNCat(CI, Builder); -- case LibFunc::strchr: -+ case LibFunc_strchr: - return optimizeStrChr(CI, Builder); -- case LibFunc::strrchr: -+ case LibFunc_strrchr: - return optimizeStrRChr(CI, Builder); -- case LibFunc::strcmp: -+ case LibFunc_strcmp: - return optimizeStrCmp(CI, Builder); -- case LibFunc::strncmp: -+ case LibFunc_strncmp: - return optimizeStrNCmp(CI, Builder); -- case LibFunc::strcpy: -+ case LibFunc_strcpy: - return optimizeStrCpy(CI, Builder); -- case LibFunc::stpcpy: -+ case LibFunc_stpcpy: - return optimizeStpCpy(CI, Builder); -- case LibFunc::strncpy: -+ case LibFunc_strncpy: - return optimizeStrNCpy(CI, Builder); -- case LibFunc::strlen: -+ case LibFunc_strlen: - return optimizeStrLen(CI, Builder); -- case LibFunc::strpbrk: -+ case LibFunc_strpbrk: - return optimizeStrPBrk(CI, Builder); -- case LibFunc::strtol: -- case LibFunc::strtod: -- case LibFunc::strtof: -- case LibFunc::strtoul: -- case LibFunc::strtoll: -- case LibFunc::strtold: -- case LibFunc::strtoull: -+ case LibFunc_strtol: -+ case LibFunc_strtod: -+ case LibFunc_strtof: -+ case LibFunc_strtoul: -+ case LibFunc_strtoll: -+ case LibFunc_strtold: -+ case LibFunc_strtoull: - return optimizeStrTo(CI, Builder); -- case LibFunc::strspn: -+ case LibFunc_strspn: - return optimizeStrSpn(CI, Builder); -- case LibFunc::strcspn: -+ case LibFunc_strcspn: - return optimizeStrCSpn(CI, Builder); -- case LibFunc::strstr: -+ case LibFunc_strstr: - return optimizeStrStr(CI, Builder); -- case LibFunc::memchr: -+ case LibFunc_memchr: - return optimizeMemChr(CI, Builder); -- case LibFunc::memcmp: -+ case LibFunc_memcmp: - return optimizeMemCmp(CI, Builder); -- case LibFunc::memcpy: -+ case LibFunc_memcpy: - return optimizeMemCpy(CI, Builder); -- case LibFunc::memmove: -+ case LibFunc_memmove: - return optimizeMemMove(CI, Builder); -- case LibFunc::memset: -+ case LibFunc_memset: - return optimizeMemSet(CI, Builder); - default: - break; -@@ -2005,7 +2005,7 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { - if (CI->isNoBuiltin()) - return nullptr; - -- LibFunc::Func Func; -+ LibFunc Func; - Function *Callee = CI->getCalledFunction(); - StringRef FuncName = Callee->getName(); - -@@ -2067,114 +2067,114 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { - if (Value *V = optimizeStringMemoryLibCall(CI, Builder)) - return V; - switch (Func) { -- case LibFunc::cosf: -- case LibFunc::cos: -- case LibFunc::cosl: -+ case LibFunc_cosf: -+ case LibFunc_cos: -+ case LibFunc_cosl: - return optimizeCos(CI, Builder); -- case LibFunc::sinpif: -- case LibFunc::sinpi: -- case LibFunc::cospif: -- case LibFunc::cospi: -+ case LibFunc_sinpif: -+ case LibFunc_sinpi: -+ case LibFunc_cospif: -+ case LibFunc_cospi: - return optimizeSinCosPi(CI, Builder); -- case LibFunc::powf: -- case LibFunc::pow: -- case LibFunc::powl: -+ case LibFunc_powf: -+ case LibFunc_pow: -+ case LibFunc_powl: - return optimizePow(CI, Builder); -- case LibFunc::exp2l: -- case LibFunc::exp2: -- case LibFunc::exp2f: -+ case LibFunc_exp2l: -+ case LibFunc_exp2: -+ case LibFunc_exp2f: - return optimizeExp2(CI, Builder); -- case LibFunc::fabsf: -- case LibFunc::fabs: -- case LibFunc::fabsl: -+ case LibFunc_fabsf: -+ case LibFunc_fabs: -+ case LibFunc_fabsl: - return optimizeFabs(CI, Builder); -- case LibFunc::sqrtf: -- case LibFunc::sqrt: -- case LibFunc::sqrtl: -+ case LibFunc_sqrtf: -+ case LibFunc_sqrt: -+ case LibFunc_sqrtl: - return optimizeSqrt(CI, Builder); -- case LibFunc::ffs: -- case LibFunc::ffsl: -- case LibFunc::ffsll: -+ case LibFunc_ffs: -+ case LibFunc_ffsl: -+ case LibFunc_ffsll: - return optimizeFFS(CI, Builder); -- case LibFunc::fls: -- case LibFunc::flsl: -- case LibFunc::flsll: -+ case LibFunc_fls: -+ case LibFunc_flsl: -+ case LibFunc_flsll: - return optimizeFls(CI, Builder); -- case LibFunc::abs: -- case LibFunc::labs: -- case LibFunc::llabs: -+ case LibFunc_abs: -+ case LibFunc_labs: -+ case LibFunc_llabs: - return optimizeAbs(CI, Builder); -- case LibFunc::isdigit: -+ case LibFunc_isdigit: - return optimizeIsDigit(CI, Builder); -- case LibFunc::isascii: -+ case LibFunc_isascii: - return optimizeIsAscii(CI, Builder); -- case LibFunc::toascii: -+ case LibFunc_toascii: - return optimizeToAscii(CI, Builder); -- case LibFunc::printf: -+ case LibFunc_printf: - return optimizePrintF(CI, Builder); -- case LibFunc::sprintf: -+ case LibFunc_sprintf: - return optimizeSPrintF(CI, Builder); -- case LibFunc::fprintf: -+ case LibFunc_fprintf: - return optimizeFPrintF(CI, Builder); -- case LibFunc::fwrite: -+ case LibFunc_fwrite: - return optimizeFWrite(CI, Builder); -- case LibFunc::fputs: -+ case LibFunc_fputs: - return optimizeFPuts(CI, Builder); -- case LibFunc::log: -- case LibFunc::log10: -- case LibFunc::log1p: -- case LibFunc::log2: -- case LibFunc::logb: -+ case LibFunc_log: -+ case LibFunc_log10: -+ case LibFunc_log1p: -+ case LibFunc_log2: -+ case LibFunc_logb: - return optimizeLog(CI, Builder); -- case LibFunc::puts: -+ case LibFunc_puts: - return optimizePuts(CI, Builder); -- case LibFunc::tan: -- case LibFunc::tanf: -- case LibFunc::tanl: -+ case LibFunc_tan: -+ case LibFunc_tanf: -+ case LibFunc_tanl: - return optimizeTan(CI, Builder); -- case LibFunc::perror: -+ case LibFunc_perror: - return optimizeErrorReporting(CI, Builder); -- case LibFunc::vfprintf: -- case LibFunc::fiprintf: -+ case LibFunc_vfprintf: -+ case LibFunc_fiprintf: - return optimizeErrorReporting(CI, Builder, 0); -- case LibFunc::fputc: -+ case LibFunc_fputc: - return optimizeErrorReporting(CI, Builder, 1); -- case LibFunc::ceil: -- case LibFunc::floor: -- case LibFunc::rint: -- case LibFunc::round: -- case LibFunc::nearbyint: -- case LibFunc::trunc: -+ case LibFunc_ceil: -+ case LibFunc_floor: -+ case LibFunc_rint: -+ case LibFunc_round: -+ case LibFunc_nearbyint: -+ case LibFunc_trunc: - if (hasFloatVersion(FuncName)) - return optimizeUnaryDoubleFP(CI, Builder, false); - return nullptr; -- case LibFunc::acos: -- case LibFunc::acosh: -- case LibFunc::asin: -- case LibFunc::asinh: -- case LibFunc::atan: -- case LibFunc::atanh: -- case LibFunc::cbrt: -- case LibFunc::cosh: -- case LibFunc::exp: -- case LibFunc::exp10: -- case LibFunc::expm1: -- case LibFunc::sin: -- case LibFunc::sinh: -- case LibFunc::tanh: -+ case LibFunc_acos: -+ case LibFunc_acosh: -+ case LibFunc_asin: -+ case LibFunc_asinh: -+ case LibFunc_atan: -+ case LibFunc_atanh: -+ case LibFunc_cbrt: -+ case LibFunc_cosh: -+ case LibFunc_exp: -+ case LibFunc_exp10: -+ case LibFunc_expm1: -+ case LibFunc_sin: -+ case LibFunc_sinh: -+ case LibFunc_tanh: - if (UnsafeFPShrink && hasFloatVersion(FuncName)) - return optimizeUnaryDoubleFP(CI, Builder, true); - return nullptr; -- case LibFunc::copysign: -+ case LibFunc_copysign: - if (hasFloatVersion(FuncName)) - return optimizeBinaryDoubleFP(CI, Builder); - return nullptr; -- case LibFunc::fminf: -- case LibFunc::fmin: -- case LibFunc::fminl: -- case LibFunc::fmaxf: -- case LibFunc::fmax: -- case LibFunc::fmaxl: -+ case LibFunc_fminf: -+ case LibFunc_fmin: -+ case LibFunc_fminl: -+ case LibFunc_fmaxf: -+ case LibFunc_fmax: -+ case LibFunc_fmaxl: - return optimizeFMinFMax(CI, Builder); - default: - return nullptr; -@@ -2300,7 +2300,7 @@ Value *FortifiedLibCallSimplifier::optimizeMemSetChk(CallInst *CI, - - Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI, - IRBuilder<> &B, -- LibFunc::Func Func) { -+ LibFunc Func) { - Function *Callee = CI->getCalledFunction(); - StringRef Name = Callee->getName(); - const DataLayout &DL = CI->getModule()->getDataLayout(); -@@ -2308,7 +2308,7 @@ Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI, - *ObjSize = CI->getArgOperand(2); - - // __stpcpy_chk(x,x,...) -> x+strlen(x) -- if (Func == LibFunc::stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) { -+ if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) { - Value *StrLen = emitStrLen(Src, B, DL, TLI); - return StrLen ? B.CreateInBoundsGEP(B.getInt8Ty(), Dst, StrLen) : nullptr; - } -@@ -2334,14 +2334,14 @@ Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI, - Value *Ret = emitMemCpyChk(Dst, Src, LenV, ObjSize, B, DL, TLI); - // If the function was an __stpcpy_chk, and we were able to fold it into - // a __memcpy_chk, we still need to return the correct end pointer. -- if (Ret && Func == LibFunc::stpcpy_chk) -+ if (Ret && Func == LibFunc_stpcpy_chk) - return B.CreateGEP(B.getInt8Ty(), Dst, ConstantInt::get(SizeTTy, Len - 1)); - return Ret; - } - - Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(CallInst *CI, - IRBuilder<> &B, -- LibFunc::Func Func) { -+ LibFunc Func) { - Function *Callee = CI->getCalledFunction(); - StringRef Name = Callee->getName(); - if (isFortifiedCallFoldable(CI, 3, 2, false)) { -@@ -2366,7 +2366,7 @@ Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI) { - // - // PR23093. - -- LibFunc::Func Func; -+ LibFunc Func; - Function *Callee = CI->getCalledFunction(); - - SmallVector OpBundles; -@@ -2384,17 +2384,17 @@ Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI) { - return nullptr; - - switch (Func) { -- case LibFunc::memcpy_chk: -+ case LibFunc_memcpy_chk: - return optimizeMemCpyChk(CI, Builder); -- case LibFunc::memmove_chk: -+ case LibFunc_memmove_chk: - return optimizeMemMoveChk(CI, Builder); -- case LibFunc::memset_chk: -+ case LibFunc_memset_chk: - return optimizeMemSetChk(CI, Builder); -- case LibFunc::stpcpy_chk: -- case LibFunc::strcpy_chk: -+ case LibFunc_stpcpy_chk: -+ case LibFunc_strcpy_chk: - return optimizeStrpCpyChk(CI, Builder, Func); -- case LibFunc::stpncpy_chk: -- case LibFunc::strncpy_chk: -+ case LibFunc_stpncpy_chk: -+ case LibFunc_strncpy_chk: - return optimizeStrpNCpyChk(CI, Builder, Func); - default: - break; diff --git a/deps/patches/llvm-D28759-loopclearance.patch b/deps/patches/llvm-D28759-loopclearance.patch deleted file mode 100644 index 036ca4d83103c..0000000000000 --- a/deps/patches/llvm-D28759-loopclearance.patch +++ /dev/null @@ -1,480 +0,0 @@ -From e3621af0115a851d0ed02f0b436deec62ec3e99c Mon Sep 17 00:00:00 2001 -From: Keno Fischer -Date: Sun, 15 Jan 2017 23:59:07 -0500 -Subject: [PATCH] [ExecutionDepsFix] Improve clearance calculation for loops - -In revision rL278321, ExecutionDepsFix learned how to pick a better -register for undef register reads, e.g. for instructions such as -`vcvtsi2sdq`. While this revision improved performance on a good number -of our benchmarks, it unfortunately also caused significant regressions -(up to 3x) on others. This regression turned out to be caused by loops -such as: - -PH -> A -> B (xmm -> xmm) -> C -> D -> EXIT - ^ | - +----------------------------------+ - -In the previous version of the clearance calculation, we would visit -the blocks in order, remembering for each whether there were any -incoming backedges from blocks that we hadn't processed yet and if -so queuing up the block to be re-processed. However, for loop structures -such as the above, this is clearly insufficient, since the block B -does not have any unknown backedges, so we do not see the false -dependency from the previous interation's Def of xmm registers in B. - -To fix this, we need to consider all blocks that are part of the loop -and reprocess them one the correct clearance values are known. As -an optimization, we also want to avoid reprocessing any later blocks -that are not part of the loop. - -In summary, the iteration order is as follows: -Before: PH A B C D A' -Corrected (Naive): PH A B C D A' B' C' D' -Corrected (w/ optimization): PH A B C A' B' C' D - -To facilitate this optimization we introduce two new counters for each -basic block. The first counts how many of it's predecssors have -completed primary processing. The second counts how many of its -predecessors have completed all processing (we will call such a block -*done*. Now, the criteria to reprocess a block is as follows: - - All Predecessors have completed primary processing - - For x the number of predecessors that have completed primary - processing *at the time of primary processing of this block*, - the number of predecessors that are done has reached x. - -The intuition behind this criterion is as follows: -We need to perform primary processing on all predecessors in order to -find out any direct defs in those predecessors. When predecessors are -done, we also know that we have information about indirect defs (e.g. -in block B though that were inherited through B->C->A->B). However, -we can't wait for all predecessors to be done, since that would -cause cyclic dependencies. However, it is guaranteed that all those -predecessors that are prior to us in reverse postorder will be done -before us. Since we iterate of the basic blocks in reverse postorder, -the number x above, is precisely the count of the number of predecessors -prior to us in reverse postorder. ---- - lib/CodeGen/ExecutionDepsFix.cpp | 223 ++++++++++++++++++++++-------------- - test/CodeGen/X86/break-false-dep.ll | 57 +++++++++ - 2 files changed, 197 insertions(+), 83 deletions(-) - -diff --git a/lib/CodeGen/ExecutionDepsFix.cpp b/lib/CodeGen/ExecutionDepsFix.cpp -index e7c6b03..6ac1db4 100644 ---- a/lib/CodeGen/ExecutionDepsFix.cpp -+++ b/lib/CodeGen/ExecutionDepsFix.cpp -@@ -142,8 +142,26 @@ class ExeDepsFix : public MachineFunctionPass { - std::vector> AliasMap; - const unsigned NumRegs; - LiveReg *LiveRegs; -- typedef DenseMap LiveOutMap; -- LiveOutMap LiveOuts; -+ struct MBBInfo { -+ // Keeps clearance and domain information for all registers. Not that this -+ // is different from the usual definition notion of liveness. The CPU -+ // doesn't care whether or not we consider a register killed. -+ LiveReg *OutRegs; -+ -+ // Whether we have gotten to this block in primary processing yet. -+ bool PrimaryCompleted; -+ -+ // The number of predecessors for which primary processing has completed -+ unsigned IncomingProcessed; -+ -+ // The value of `IncomingProcessed` at the start of primary processing -+ unsigned PrimaryIncoming; -+ -+ // The number of predecessors for which all processing steps are done. -+ unsigned IncomingCompleted; -+ }; -+ typedef DenseMap MBBInfoMap; -+ MBBInfoMap MBBInfos; - - /// List of undefined register reads in this block in forward order. - std::vector > UndefReads; -@@ -154,11 +172,6 @@ class ExeDepsFix : public MachineFunctionPass { - /// Current instruction number. - /// The first instruction in each basic block is 0. - int CurInstr; -- -- /// True when the current block has a predecessor that hasn't been visited -- /// yet. -- bool SeenUnknownBackEdge; -- - public: - ExeDepsFix(const TargetRegisterClass *rc) - : MachineFunctionPass(ID), RC(rc), NumRegs(RC->getNumRegs()) {} -@@ -180,7 +193,6 @@ public: - private: - iterator_range::const_iterator> - regIndices(unsigned Reg) const; -- - // DomainValue allocation. - DomainValue *alloc(int domain = -1); - DomainValue *retain(DomainValue *DV) { -@@ -199,8 +211,11 @@ private: - - void enterBasicBlock(MachineBasicBlock*); - void leaveBasicBlock(MachineBasicBlock*); -- void visitInstr(MachineInstr*); -- void processDefs(MachineInstr*, bool Kill); -+ bool isBlockDone(MachineBasicBlock *); -+ void processBasicBlock(MachineBasicBlock *MBB, bool PrimaryPass, bool Done); -+ void updateSuccessors(MachineBasicBlock *MBB, bool Primary, bool Done); -+ bool visitInstr(MachineInstr *); -+ void processDefs(MachineInstr *, bool BlockDone, bool Kill); - void visitSoftInstr(MachineInstr*, unsigned mask); - void visitHardInstr(MachineInstr*, unsigned domain); - void pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, -@@ -360,9 +375,6 @@ bool ExeDepsFix::merge(DomainValue *A, DomainValue *B) { - - /// Set up LiveRegs by merging predecessor live-out values. - void ExeDepsFix::enterBasicBlock(MachineBasicBlock *MBB) { -- // Detect back-edges from predecessors we haven't processed yet. -- SeenUnknownBackEdge = false; -- - // Reset instruction counter in each basic block. - CurInstr = 0; - -@@ -397,18 +409,18 @@ void ExeDepsFix::enterBasicBlock(MachineBasicBlock *MBB) { - // Try to coalesce live-out registers from predecessors. - for (MachineBasicBlock::const_pred_iterator pi = MBB->pred_begin(), - pe = MBB->pred_end(); pi != pe; ++pi) { -- LiveOutMap::const_iterator fi = LiveOuts.find(*pi); -- if (fi == LiveOuts.end()) { -- SeenUnknownBackEdge = true; -+ auto fi = MBBInfos.find(*pi); -+ assert(fi != MBBInfos.end()); -+ LiveReg *Incoming = fi->second.OutRegs; -+ if (Incoming == nullptr) { - continue; - } -- assert(fi->second && "Can't have NULL entries"); - - for (unsigned rx = 0; rx != NumRegs; ++rx) { - // Use the most recent predecessor def for each register. -- LiveRegs[rx].Def = std::max(LiveRegs[rx].Def, fi->second[rx].Def); -+ LiveRegs[rx].Def = std::max(LiveRegs[rx].Def, Incoming[rx].Def); - -- DomainValue *pdv = resolve(fi->second[rx].Value); -+ DomainValue *pdv = resolve(Incoming[rx].Value); - if (!pdv) - continue; - if (!LiveRegs[rx].Value) { -@@ -432,35 +444,33 @@ void ExeDepsFix::enterBasicBlock(MachineBasicBlock *MBB) { - force(rx, pdv->getFirstDomain()); - } - } -- DEBUG(dbgs() << "BB#" << MBB->getNumber() -- << (SeenUnknownBackEdge ? ": incomplete\n" : ": all preds known\n")); -+ DEBUG( -+ dbgs() << "BB#" << MBB->getNumber() -+ << (!isBlockDone(MBB) ? ": incomplete\n" : ": all preds known\n")); - } - - void ExeDepsFix::leaveBasicBlock(MachineBasicBlock *MBB) { - assert(LiveRegs && "Must enter basic block first."); -+ LiveReg *OldOutRegs = MBBInfos[MBB].OutRegs; - // Save live registers at end of MBB - used by enterBasicBlock(). - // Also use LiveOuts as a visited set to detect back-edges. -- bool First = LiveOuts.insert(std::make_pair(MBB, LiveRegs)).second; -- -- if (First) { -- // LiveRegs was inserted in LiveOuts. Adjust all defs to be relative to -- // the end of this block instead of the beginning. -- for (unsigned i = 0, e = NumRegs; i != e; ++i) -- LiveRegs[i].Def -= CurInstr; -- } else { -- // Insertion failed, this must be the second pass. -+ MBBInfos[MBB].OutRegs = LiveRegs; -+ -+ // LiveRegs was inserted in LiveOuts. Adjust all defs to be relative to -+ // the end of this block instead of the beginning. -+ for (unsigned i = 0, e = NumRegs; i != e; ++i) -+ LiveRegs[i].Def -= CurInstr; -+ if (OldOutRegs) { -+ // This must be the second pass. - // Release all the DomainValues instead of keeping them. - for (unsigned i = 0, e = NumRegs; i != e; ++i) -- release(LiveRegs[i].Value); -- delete[] LiveRegs; -+ release(OldOutRegs[i].Value); -+ delete[] OldOutRegs; - } - LiveRegs = nullptr; - } - --void ExeDepsFix::visitInstr(MachineInstr *MI) { -- if (MI->isDebugValue()) -- return; -- -+bool ExeDepsFix::visitInstr(MachineInstr *MI) { - // Update instructions with explicit execution domains. - std::pair DomP = TII->getExecutionDomain(*MI); - if (DomP.first) { -@@ -470,9 +480,7 @@ void ExeDepsFix::visitInstr(MachineInstr *MI) { - visitHardInstr(MI, DomP.first); - } - -- // Process defs to track register ages, and kill values clobbered by generic -- // instructions. -- processDefs(MI, !DomP.first); -+ return !DomP.first; - } - - /// \brief Helps avoid false dependencies on undef registers by updating the -@@ -542,14 +550,7 @@ bool ExeDepsFix::shouldBreakDependence(MachineInstr *MI, unsigned OpIdx, - DEBUG(dbgs() << ": Break dependency.\n"); - continue; - } -- // The current clearance seems OK, but we may be ignoring a def from a -- // back-edge. -- if (!SeenUnknownBackEdge || Pref <= unsigned(CurInstr)) { -- DEBUG(dbgs() << ": OK .\n"); -- return false; -- } -- // A def from an unprocessed back-edge may make us break this dependency. -- DEBUG(dbgs() << ": Wait for back-edge to resolve.\n"); -+ DEBUG(dbgs() << ": OK .\n"); - return false; - } - return true; -@@ -559,16 +560,21 @@ bool ExeDepsFix::shouldBreakDependence(MachineInstr *MI, unsigned OpIdx, - // If Kill is set, also kill off DomainValues clobbered by the defs. - // - // Also break dependencies on partial defs and undef uses. --void ExeDepsFix::processDefs(MachineInstr *MI, bool Kill) { -+void ExeDepsFix::processDefs(MachineInstr *MI, bool BlockDone, bool Kill) { - assert(!MI->isDebugValue() && "Won't process debug values"); - - // Break dependence on undef uses. Do this before updating LiveRegs below. - unsigned OpNum; -- unsigned Pref = TII->getUndefRegClearance(*MI, OpNum, TRI); -- if (Pref) { -- pickBestRegisterForUndef(MI, OpNum, Pref); -- if (shouldBreakDependence(MI, OpNum, Pref)) -- UndefReads.push_back(std::make_pair(MI, OpNum)); -+ // If this block is not done, it makes little sense to make any decisions -+ // based on clearance information. We need to make a second pass anyway, -+ // and by then we'll have better information, so we can avoid this work now. -+ if (BlockDone) { -+ unsigned Pref = TII->getUndefRegClearance(*MI, OpNum, TRI); -+ if (Pref) { -+ pickBestRegisterForUndef(MI, OpNum, Pref); -+ if (shouldBreakDependence(MI, OpNum, Pref)) -+ UndefReads.push_back(std::make_pair(MI, OpNum)); -+ } - } - const MCInstrDesc &MCID = MI->getDesc(); - for (unsigned i = 0, -@@ -584,11 +590,13 @@ void ExeDepsFix::processDefs(MachineInstr *MI, bool Kill) { - DEBUG(dbgs() << TRI->getName(RC->getRegister(rx)) << ":\t" << CurInstr - << '\t' << *MI); - -- // Check clearance before partial register updates. -- // Call breakDependence before setting LiveRegs[rx].Def. -- unsigned Pref = TII->getPartialRegUpdateClearance(*MI, i, TRI); -- if (Pref && shouldBreakDependence(MI, i, Pref)) -- TII->breakPartialRegDependency(*MI, i, TRI); -+ if (BlockDone) { -+ // Check clearance before partial register updates. -+ // Call breakDependence before setting LiveRegs[rx].Def. -+ unsigned Pref = TII->getPartialRegUpdateClearance(*MI, i, TRI); -+ if (Pref && shouldBreakDependence(MI, i, Pref)) -+ TII->breakPartialRegDependency(*MI, i, TRI); -+ } - - // How many instructions since rx was last written? - LiveRegs[rx].Def = CurInstr; -@@ -780,6 +788,45 @@ void ExeDepsFix::visitSoftInstr(MachineInstr *mi, unsigned mask) { - } - } - -+void ExeDepsFix::processBasicBlock(MachineBasicBlock *MBB, bool PrimaryPass, -+ bool Done) { -+ enterBasicBlock(MBB); -+ for (MachineInstr &MI : *MBB) { -+ if (!MI.isDebugValue()) { -+ bool Kill = false; -+ if (PrimaryPass) -+ Kill = visitInstr(&MI); -+ processDefs(&MI, isBlockDone(MBB), Kill); -+ } -+ } -+ processUndefReads(MBB); -+ leaveBasicBlock(MBB); -+} -+ -+bool ExeDepsFix::isBlockDone(MachineBasicBlock *MBB) { -+ return MBBInfos[MBB].PrimaryCompleted && -+ MBBInfos[MBB].IncomingCompleted == MBBInfos[MBB].PrimaryIncoming && -+ MBBInfos[MBB].IncomingProcessed == MBB->pred_size(); -+} -+ -+void ExeDepsFix::updateSuccessors(MachineBasicBlock *MBB, bool Primary, -+ bool Done) { -+ for (auto *Succ : MBB->successors()) { -+ if (!isBlockDone(Succ)) { -+ if (Primary) { -+ MBBInfos[Succ].IncomingProcessed++; -+ } -+ if (Done) { -+ MBBInfos[Succ].IncomingCompleted++; -+ } -+ if (isBlockDone(Succ)) { -+ processBasicBlock(Succ, false, true); -+ updateSuccessors(Succ, false, true); -+ } -+ } -+ } -+} -+ - bool ExeDepsFix::runOnMachineFunction(MachineFunction &mf) { - if (skipFunction(*mf.getFunction())) - return false; -@@ -816,44 +863,54 @@ bool ExeDepsFix::runOnMachineFunction(MachineFunction &mf) { - AliasMap[*AI].push_back(i); - } - -+ // Initialize the MMBInfos -+ for (auto &MBB : mf) { -+ MBBInfo InitialInfo{nullptr, false, 0, 0, 0}; -+ MBBInfos.insert(std::make_pair(&MBB, InitialInfo)); -+ } -+ - MachineBasicBlock *Entry = &*MF->begin(); - ReversePostOrderTraversal RPOT(Entry); -- SmallVector Loops; - for (ReversePostOrderTraversal::rpo_iterator - MBBI = RPOT.begin(), MBBE = RPOT.end(); MBBI != MBBE; ++MBBI) { - MachineBasicBlock *MBB = *MBBI; -- enterBasicBlock(MBB); -- if (SeenUnknownBackEdge) -- Loops.push_back(MBB); -- for (MachineInstr &MI : *MBB) -- visitInstr(&MI); -- processUndefReads(MBB); -- leaveBasicBlock(MBB); -- } -- -- // Visit all the loop blocks again in order to merge DomainValues from -- // back-edges. -- for (MachineBasicBlock *MBB : Loops) { -- enterBasicBlock(MBB); -- for (MachineInstr &MI : *MBB) -- if (!MI.isDebugValue()) -- processDefs(&MI, false); -- processUndefReads(MBB); -- leaveBasicBlock(MBB); -+ MBBInfos[MBB].PrimaryCompleted = true; -+ MBBInfos[MBB].PrimaryIncoming = MBBInfos[MBB].IncomingProcessed; -+ bool PrimaryDone = isBlockDone(MBB); -+ processBasicBlock(MBB, true, PrimaryDone); -+ updateSuccessors(MBB, true, PrimaryDone); -+ } -+ -+ // We need to go through again and finalize any blocks that are not done yet. -+ // This is possible if blocks have dead predecessors, so we didn't visit them -+ // above. N.B.: The reason we update succesors immidately above, rather than -+ // doing everything in one go here, is to avoid having to do two passes on -+ // basic block between loops (with the scheme above, the whole loop will be -+ // completed before moving on to the blocks after it). -+ for (ReversePostOrderTraversal::rpo_iterator -+ MBBI = RPOT.begin(), -+ MBBE = RPOT.end(); -+ MBBI != MBBE; ++MBBI) { -+ MachineBasicBlock *MBB = *MBBI; -+ if (!isBlockDone(MBB)) { -+ processBasicBlock(MBB, false, true); -+ // Don't update successors here. We'll get to them anyway through this -+ // loop. -+ } - } - - // Clear the LiveOuts vectors and collapse any remaining DomainValues. - for (ReversePostOrderTraversal::rpo_iterator - MBBI = RPOT.begin(), MBBE = RPOT.end(); MBBI != MBBE; ++MBBI) { -- LiveOutMap::const_iterator FI = LiveOuts.find(*MBBI); -- if (FI == LiveOuts.end() || !FI->second) -+ auto FI = MBBInfos.find(*MBBI); -+ if (FI == MBBInfos.end() || !FI->second.OutRegs) - continue; - for (unsigned i = 0, e = NumRegs; i != e; ++i) -- if (FI->second[i].Value) -- release(FI->second[i].Value); -- delete[] FI->second; -+ if (FI->second.OutRegs[i].Value) -+ release(FI->second.OutRegs[i].Value); -+ delete[] FI->second.OutRegs; - } -- LiveOuts.clear(); -+ MBBInfos.clear(); - UndefReads.clear(); - Avail.clear(); - Allocator.DestroyAll(); -diff --git a/test/CodeGen/X86/break-false-dep.ll b/test/CodeGen/X86/break-false-dep.ll -index 4c5e747..0ba1825 100644 ---- a/test/CodeGen/X86/break-false-dep.ll -+++ b/test/CodeGen/X86/break-false-dep.ll -@@ -277,3 +277,60 @@ ret: - ;AVX: vcvtsi2sdq {{.*}}, [[XMM4_7:%xmm[4-7]]], {{%xmm[0-9]+}} - ;AVX-NOT: [[XMM4_7]] - } -+ -+; Make sure we are making a smart choice regarding undef registers even for more -+; complicated loop structures. This example is the inner loop from -+; julia> a = falses(10000); a[1:4:end] = true -+; julia> linspace(1.0,2.0,10000)[a] -+define void @loopclearance2(double* nocapture %y, i64* %x, double %c1, double %c2, double %c3, double %c4, i64 %size) { -+entry: -+ tail call void asm sideeffect "", "~{xmm7},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm12},~{xmm13},~{xmm14},~{xmm15},~{dirflag},~{fpsr},~{flags}"() -+ br label %loop -+ -+loop: -+ %phi_i = phi i64 [ 1, %entry ], [ %nexti, %loop_end ] -+ %phi_j = phi i64 [ 1, %entry ], [ %nextj, %loop_end ] -+ %phi_k = phi i64 [ 0, %entry ], [ %nextk, %loop_end ] -+ br label %inner_loop -+ -+inner_loop: -+ %phi = phi i64 [ %phi_k, %loop ], [ %nextk, %inner_loop ] -+ %idx = lshr i64 %phi, 6 -+ %inputptr = getelementptr i64, i64* %x, i64 %idx -+ %input = load i64, i64* %inputptr, align 8 -+ %masked = and i64 %phi, 63 -+ %shiftedmasked = shl i64 1, %masked -+ %maskedinput = and i64 %input, %shiftedmasked -+ %cmp = icmp eq i64 %maskedinput, 0 -+ %nextk = add i64 %phi, 1 -+ br i1 %cmp, label %inner_loop, label %loop_end -+ -+loop_end: -+ %nexti = add i64 %phi_i, 1 -+ %nextj = add i64 %phi_j, 1 -+ ; Register use, plus us clobbering 7-15 above, basically forces xmm7 here as -+ ; the only reasonable choice. The primary thing we care about is that it's -+ ; not one of the registers used in the loop (e.g. not the output reg here) -+;AVX-NOT: %xmm6 -+;AVX: vcvtsi2sdq {{.*}}, %xmm6, {{%xmm[0-9]+}} -+;AVX-NOT: %xmm6 -+ %nexti_f = sitofp i64 %nexti to double -+ %sub = fsub double %c1, %nexti_f -+ %mul = fmul double %sub, %c2 -+;AVX: vcvtsi2sdq {{.*}}, %xmm6, {{%xmm[0-9]+}} -+;AVX-NOT: %xmm6 -+ %phi_f = sitofp i64 %phi to double -+ %mul2 = fmul double %phi_f, %c3 -+ %add2 = fadd double %mul, %mul2 -+ %div = fdiv double %add2, %c4 -+ %prev_j = add i64 %phi_j, -1 -+ %outptr = getelementptr double, double* %y, i64 %prev_j -+ store double %div, double* %outptr, align 8 -+ %done = icmp slt i64 %size, %nexti -+ br i1 %done, label %loopdone, label %loop -+ -+loopdone: -+ ret void -+} --- -2.9.3 diff --git a/deps/patches/llvm-D28786-callclearance.patch b/deps/patches/llvm-D28786-callclearance.patch deleted file mode 100644 index fa7dfd3f22d38..0000000000000 --- a/deps/patches/llvm-D28786-callclearance.patch +++ /dev/null @@ -1,344 +0,0 @@ -diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h -index 83515bc..65b435a 100644 ---- a/include/llvm/Target/TargetInstrInfo.h -+++ b/include/llvm/Target/TargetInstrInfo.h -@@ -1440,6 +1440,17 @@ public: - virtual void breakPartialRegDependency(MachineInstr &MI, unsigned OpNum, - const TargetRegisterInfo *TRI) const {} - -+ /// May return true if the instruction in question is a dependency breaking -+ /// instruction. If so, the register number for which it is dependency -+ /// breaking should be returned in `OutReg`. It is prefereable to return -+ /// false if the result cannot be determined. This would at worst result -+ /// in the insertion of an unnecessary instruction, while the other -+ /// alternative could result in significant false-dependency penalties. -+ virtual bool isDependencyBreak(MachineInstr &MI, -+ unsigned *OutReg = nullptr) const { -+ return false; -+ } -+ - /// Create machine specific model for scheduling. - virtual DFAPacketizer * - CreateTargetScheduleState(const TargetSubtargetInfo &) const { -diff --git a/lib/CodeGen/ExecutionDepsFix.cpp b/lib/CodeGen/ExecutionDepsFix.cpp -index 6ac1db4..63065ea 100644 ---- a/lib/CodeGen/ExecutionDepsFix.cpp -+++ b/lib/CodeGen/ExecutionDepsFix.cpp -@@ -214,13 +214,18 @@ private: - bool isBlockDone(MachineBasicBlock *); - void processBasicBlock(MachineBasicBlock *MBB, bool PrimaryPass, bool Done); - void updateSuccessors(MachineBasicBlock *MBB, bool Primary, bool Done); -- bool visitInstr(MachineInstr *); -+ bool visitInstr(MachineInstr *, bool PrimaryPass); - void processDefs(MachineInstr *, bool BlockDone, bool Kill); - void visitSoftInstr(MachineInstr*, unsigned mask); - void visitHardInstr(MachineInstr*, unsigned domain); -- void pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, -- unsigned Pref); -+ void pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, unsigned Pref, -+ bool &TrueDependency); - bool shouldBreakDependence(MachineInstr*, unsigned OpIdx, unsigned Pref); -+ -+ // Undef Reads -+ void collapseUndefReads(unsigned from, unsigned to, unsigned Reg); -+ unsigned updateChooseableRegs(SparseSet &, -+ const TargetRegisterClass *, bool); - void processUndefReads(MachineBasicBlock*); - }; - } -@@ -394,11 +399,19 @@ void ExeDepsFix::enterBasicBlock(MachineBasicBlock *MBB) { - - // This is the entry block. - if (MBB->pred_empty()) { -+ // Treat all registers as being defined just before the first instruction. -+ // Howver, we want the logic later to prefer non live-ins over live-ins, -+ // so pretend the live-ins were defined slightly later. -+ // We used to only do this for live-ins, but that's a bit of a gamble. -+ // If our caller does arithmetic with these registers is is quite likely -+ // that it will have used registers beyond the ones that are live here. -+ // Given the immense penalty for getting this wrong, being conservative -+ // here seems worth it. -+ for (unsigned rx = 0; rx != NumRegs; ++rx) { -+ LiveRegs[rx].Def = -2; -+ } - for (const auto &LI : MBB->liveins()) { - for (int rx : regIndices(LI.PhysReg)) { -- // Treat function live-ins as if they were defined just before the first -- // instruction. Usually, function arguments are set up immediately -- // before the call. - LiveRegs[rx].Def = -1; - } - } -@@ -470,24 +483,36 @@ void ExeDepsFix::leaveBasicBlock(MachineBasicBlock *MBB) { - LiveRegs = nullptr; - } - --bool ExeDepsFix::visitInstr(MachineInstr *MI) { -- // Update instructions with explicit execution domains. -- std::pair DomP = TII->getExecutionDomain(*MI); -- if (DomP.first) { -- if (DomP.second) -- visitSoftInstr(MI, DomP.second); -- else -- visitHardInstr(MI, DomP.first); -+bool ExeDepsFix::visitInstr(MachineInstr *MI, bool PrimaryPass) { -+ bool Kill = false; -+ -+ if (PrimaryPass) { -+ // Update instructions with explicit execution domains. -+ std::pair DomP = TII->getExecutionDomain(*MI); -+ if (DomP.first) { -+ if (DomP.second) -+ visitSoftInstr(MI, DomP.second); -+ else -+ visitHardInstr(MI, DomP.first); -+ } -+ Kill = !DomP.first; - } - -- return !DomP.first; -+ // If this is a call, pretend all registers we are considering are def'd here. -+ // We have no idea which registers the callee may use. -+ if (MI->isCall()) { -+ for (unsigned i = 0, e = NumRegs; i != e; ++i) -+ LiveRegs[i].Def = CurInstr; -+ } -+ -+ return Kill; - } - - /// \brief Helps avoid false dependencies on undef registers by updating the - /// machine instructions' undef operand to use a register that the instruction - /// is truly dependent on, or use a register with clearance higher than Pref. - void ExeDepsFix::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, -- unsigned Pref) { -+ unsigned Pref, bool &TrueDependency) { - MachineOperand &MO = MI->getOperand(OpIdx); - assert(MO.isUndef() && "Expected undef machine operand"); - -@@ -510,6 +535,7 @@ void ExeDepsFix::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, - // We found a true dependency - replace the undef register with the true - // dependency. - MO.setReg(CurrMO.getReg()); -+ TrueDependency = true; - return; - } - -@@ -571,9 +597,14 @@ void ExeDepsFix::processDefs(MachineInstr *MI, bool BlockDone, bool Kill) { - if (BlockDone) { - unsigned Pref = TII->getUndefRegClearance(*MI, OpNum, TRI); - if (Pref) { -- pickBestRegisterForUndef(MI, OpNum, Pref); -- if (shouldBreakDependence(MI, OpNum, Pref)) -+ bool TrueDependency = false; -+ pickBestRegisterForUndef(MI, OpNum, Pref, TrueDependency); -+ // Don't bother adding true dependencies to UndefReads. All we'd find out -+ // is that the register is live (since this very instruction depends on -+ // it), so we can't do anything. -+ if (!TrueDependency && shouldBreakDependence(MI, OpNum, Pref)) { - UndefReads.push_back(std::make_pair(MI, OpNum)); -+ } - } - } - const MCInstrDesc &MCID = MI->getDesc(); -@@ -606,9 +637,52 @@ void ExeDepsFix::processDefs(MachineInstr *MI, bool BlockDone, bool Kill) { - kill(rx); - } - } -+ unsigned DepReg = 0; -+ if (TII->isDependencyBreak(*MI, &DepReg)) { -+ for (int rx : regIndices(DepReg)) { -+ // This instruction is a dependency break, so there are no clearance -+ // issues, reset the counter. -+ LiveRegs[rx].Def = -(1 << 20); -+ } -+ } - ++CurInstr; - } - -+// Set the undef read register to `Reg` for all UndefReads in the range -+// [from,to). -+void ExeDepsFix::collapseUndefReads(unsigned from, unsigned to, unsigned Reg) { -+ if (from >= to) -+ return; -+ for (unsigned i = from; i < to; ++i) { -+ MachineInstr *MI = std::get<0>(UndefReads[i]); -+ unsigned OpIdx = std::get<1>(UndefReads[i]); -+ MachineOperand &MO = MI->getOperand(OpIdx); -+ MO.setReg(Reg); -+ } -+ TII->breakPartialRegDependency(*std::get<0>(UndefReads[from]), -+ std::get<1>(UndefReads[from]), TRI); -+} -+ -+unsigned ExeDepsFix::updateChooseableRegs(SparseSet &ChoosableRegs, -+ const TargetRegisterClass *OpRC, -+ bool add) { -+ unsigned LowestValid = (unsigned)-1; -+ -+ for (auto Reg : OpRC->getRegisters()) { -+ if (LiveRegSet.contains(Reg)) -+ ChoosableRegs.erase(Reg); -+ else if (add) { -+ ChoosableRegs.insert(Reg); -+ if (LowestValid == (unsigned)-1) -+ LowestValid = Reg; -+ } else if (ChoosableRegs.count(Reg) == 1) { -+ if (LowestValid == (unsigned)-1) -+ LowestValid = Reg; -+ } -+ } -+ return LowestValid; -+} -+ - /// \break Break false dependencies on undefined register reads. - /// - /// Walk the block backward computing precise liveness. This is expensive, so we -@@ -619,31 +693,87 @@ void ExeDepsFix::processUndefReads(MachineBasicBlock *MBB) { - if (UndefReads.empty()) - return; - -+ // We want to be slightly clever here, to avoid the following common pattern: -+ // Suppose we have some instruction `vrandom %in, %out` and the following code -+ // vrandom %xmm0, %xmm0 -+ // vrandom %xmm1, %xmm1 -+ // vrandom %xmm2, %xmm2 -+ // vrandom %xmm3, %xmm3 -+ // The earlier logic likes to produce these, because it picks the first -+ // register -+ // to break ties in clearance. However, most register allocators pick the dest -+ // register the same way. Naively, we'd have to insert a dependency break, -+ // before every instruction above. However, what we really want is -+ // vxorps %xmm3, %xmm3, %xmm3 -+ // vrandom %xmm3, %xmm0 -+ // vrandom %xmm3, %xmm1 -+ // vrandom %xmm3, %xmm2 -+ // vrandom %xmm3, %xmm3 -+ // To do so, we walk backwards and cumulatively keep track of which registers -+ // we can use to break the dependency. Then, once the set has collapsed, we -+ // reset the undef read register for all following instructions. -+ - // Collect this block's live out register units. - LiveRegSet.init(TRI); - // We do not need to care about pristine registers as they are just preserved - // but not actually used in the function. - LiveRegSet.addLiveOutsNoPristines(*MBB); - -- MachineInstr *UndefMI = UndefReads.back().first; -- unsigned OpIdx = UndefReads.back().second; -+ SparseSet ChoosableRegs; -+ ChoosableRegs.setUniverse(TRI->getNumRegs()); -+ -+ unsigned LastValid = (unsigned)-1; -+ const TargetRegisterClass *LastOpRC = nullptr; -+ size_t i, LastInit; -+ i = LastInit = UndefReads.size() - 1; -+ MachineInstr *UndefMI = std::get<0>(UndefReads[i]); - - for (MachineInstr &I : make_range(MBB->rbegin(), MBB->rend())) { - // Update liveness, including the current instruction's defs. - LiveRegSet.stepBackward(I); - -+ // This ensures that we don't accidentally pick a register whose live region -+ // lies entirely between two undef reads (since that would defeat the -+ // purpose of breaking the dependency). -+ for (auto LiveReg : LiveRegSet) -+ ChoosableRegs.erase(LiveReg); -+ - if (UndefMI == &I) { -- if (!LiveRegSet.contains(UndefMI->getOperand(OpIdx).getReg())) -- TII->breakPartialRegDependency(*UndefMI, OpIdx, TRI); -+ unsigned OpIdx = std::get<1>(UndefReads[i]); -+ // Get the undef operand's register class -+ const TargetRegisterClass *OpRC = -+ TII->getRegClass(UndefMI->getDesc(), OpIdx, TRI, *MF); -+ if (OpRC != LastOpRC || ChoosableRegs.size() == 0) { -+ if (LastInit != i) { -+ if (LastValid != (unsigned)-1) -+ collapseUndefReads(i + 1, LastInit + 1, LastValid); -+ ChoosableRegs.clear(); -+ LastInit = i; -+ } -+ } -+ -+ unsigned LowestValid = -+ updateChooseableRegs(ChoosableRegs, OpRC, LastInit == i); -+ -+ if (ChoosableRegs.size() == 0) { -+ if (LastInit != i) { -+ if (LastValid != (unsigned)-1) -+ collapseUndefReads(i + 1, LastInit + 1, LastValid); -+ LowestValid = updateChooseableRegs(ChoosableRegs, OpRC, true); -+ LastInit = i; -+ } -+ } -+ LastValid = LowestValid; -+ LastOpRC = OpRC; - -- UndefReads.pop_back(); -- if (UndefReads.empty()) -- return; -+ if (i == 0) -+ break; - -- UndefMI = UndefReads.back().first; -- OpIdx = UndefReads.back().second; -+ UndefMI = std::get<0>(UndefReads[--i]); - } - } -+ if (LastValid != (unsigned)-1) -+ collapseUndefReads(0, LastInit + 1, LastValid); - } - - // A hard instruction only works in one domain. All input registers will be -@@ -793,9 +923,7 @@ void ExeDepsFix::processBasicBlock(MachineBasicBlock *MBB, bool PrimaryPass, - enterBasicBlock(MBB); - for (MachineInstr &MI : *MBB) { - if (!MI.isDebugValue()) { -- bool Kill = false; -- if (PrimaryPass) -- Kill = visitInstr(&MI); -+ bool Kill = visitInstr(&MI, PrimaryPass); - processDefs(&MI, isBlockDone(MBB), Kill); - } - } -diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp -index 5793597..f31c97e 100644 ---- a/lib/Target/X86/X86InstrInfo.cpp -+++ b/lib/Target/X86/X86InstrInfo.cpp -@@ -7496,6 +7496,23 @@ void X86InstrInfo::breakPartialRegDependency( - } - } - -+bool X86InstrInfo::isDependencyBreak(MachineInstr &MI, unsigned *OutReg) const { -+ unsigned Opc = MI.getOpcode(); -+ if (!(Opc == X86::VXORPSrr || Opc == X86::VXORPDrr || Opc == X86::XORPSrr || -+ Opc == X86::XORPDrr)) -+ return false; -+ unsigned Reg = 0; -+ for (unsigned i = 0; i < MI.getNumOperands(); ++i) { -+ const MachineOperand &MO = MI.getOperand(i); -+ if (!MO.isReg() || (Reg != 0 && MO.getReg() != Reg)) -+ return false; -+ Reg = MO.getReg(); -+ } -+ if (OutReg) -+ *OutReg = Reg; -+ return true; -+} -+ - MachineInstr * - X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, - ArrayRef Ops, -diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h -index 8d74617..fa86882 100644 ---- a/lib/Target/X86/X86InstrInfo.h -+++ b/lib/Target/X86/X86InstrInfo.h -@@ -484,6 +484,7 @@ public: - const TargetRegisterInfo *TRI) const override; - void breakPartialRegDependency(MachineInstr &MI, unsigned OpNum, - const TargetRegisterInfo *TRI) const override; -+ bool isDependencyBreak(MachineInstr &MI, unsigned *OutReg) const override; - - MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, - unsigned OpNum, diff --git a/deps/patches/llvm-D28786-callclearance_4.0.patch b/deps/patches/llvm-D28786-callclearance_4.0.patch deleted file mode 100644 index 2735c7f5b3e94..0000000000000 --- a/deps/patches/llvm-D28786-callclearance_4.0.patch +++ /dev/null @@ -1,344 +0,0 @@ -diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h -index 247d694f2e4..e455549cdc6 100644 ---- a/include/llvm/Target/TargetInstrInfo.h -+++ b/include/llvm/Target/TargetInstrInfo.h -@@ -1421,6 +1421,17 @@ public: - virtual void breakPartialRegDependency(MachineInstr &MI, unsigned OpNum, - const TargetRegisterInfo *TRI) const {} - -+ /// May return true if the instruction in question is a dependency breaking -+ /// instruction. If so, the register number for which it is dependency -+ /// breaking should be returned in `OutReg`. It is prefereable to return -+ /// false if the result cannot be determined. This would at worst result -+ /// in the insertion of an unnecessary instruction, while the other -+ /// alternative could result in significant false-dependency penalties. -+ virtual bool isDependencyBreak(MachineInstr &MI, -+ unsigned *OutReg = nullptr) const { -+ return false; -+ } -+ - /// Create machine specific model for scheduling. - virtual DFAPacketizer * - CreateTargetScheduleState(const TargetSubtargetInfo &) const { -diff --git a/lib/CodeGen/ExecutionDepsFix.cpp b/lib/CodeGen/ExecutionDepsFix.cpp -index 64aed533a9d..9f3bd634622 100644 ---- a/lib/CodeGen/ExecutionDepsFix.cpp -+++ b/lib/CodeGen/ExecutionDepsFix.cpp -@@ -214,13 +214,18 @@ private: - bool isBlockDone(MachineBasicBlock *); - void processBasicBlock(MachineBasicBlock *MBB, bool PrimaryPass, bool Done); - void updateSuccessors(MachineBasicBlock *MBB, bool Primary, bool Done); -- bool visitInstr(MachineInstr *); -+ bool visitInstr(MachineInstr *, bool PrimaryPass); - void processDefs(MachineInstr *, bool BlockDone, bool Kill); - void visitSoftInstr(MachineInstr*, unsigned mask); - void visitHardInstr(MachineInstr*, unsigned domain); -- void pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, -- unsigned Pref); -+ void pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, unsigned Pref, -+ bool &TrueDependency); - bool shouldBreakDependence(MachineInstr*, unsigned OpIdx, unsigned Pref); -+ -+ // Undef Reads -+ void collapseUndefReads(unsigned from, unsigned to, unsigned Reg); -+ unsigned updateChooseableRegs(SparseSet &, -+ const TargetRegisterClass *, bool); - void processUndefReads(MachineBasicBlock*); - }; - } -@@ -394,11 +399,19 @@ void ExeDepsFix::enterBasicBlock(MachineBasicBlock *MBB) { - - // This is the entry block. - if (MBB->pred_empty()) { -+ // Treat all registers as being defined just before the first instruction. -+ // Howver, we want the logic later to prefer non live-ins over live-ins, -+ // so pretend the live-ins were defined slightly later. -+ // We used to only do this for live-ins, but that's a bit of a gamble. -+ // If our caller does arithmetic with these registers is is quite likely -+ // that it will have used registers beyond the ones that are live here. -+ // Given the immense penalty for getting this wrong, being conservative -+ // here seems worth it. -+ for (unsigned rx = 0; rx != NumRegs; ++rx) { -+ LiveRegs[rx].Def = -2; -+ } - for (const auto &LI : MBB->liveins()) { - for (int rx : regIndices(LI.PhysReg)) { -- // Treat function live-ins as if they were defined just before the first -- // instruction. Usually, function arguments are set up immediately -- // before the call. - LiveRegs[rx].Def = -1; - } - } -@@ -470,24 +483,36 @@ void ExeDepsFix::leaveBasicBlock(MachineBasicBlock *MBB) { - LiveRegs = nullptr; - } - --bool ExeDepsFix::visitInstr(MachineInstr *MI) { -- // Update instructions with explicit execution domains. -- std::pair DomP = TII->getExecutionDomain(*MI); -- if (DomP.first) { -- if (DomP.second) -- visitSoftInstr(MI, DomP.second); -- else -- visitHardInstr(MI, DomP.first); -+bool ExeDepsFix::visitInstr(MachineInstr *MI, bool PrimaryPass) { -+ bool Kill = false; -+ -+ if (PrimaryPass) { -+ // Update instructions with explicit execution domains. -+ std::pair DomP = TII->getExecutionDomain(*MI); -+ if (DomP.first) { -+ if (DomP.second) -+ visitSoftInstr(MI, DomP.second); -+ else -+ visitHardInstr(MI, DomP.first); -+ } -+ Kill = !DomP.first; -+ } -+ -+ // If this is a call, pretend all registers we are considering are def'd here. -+ // We have no idea which registers the callee may use. -+ if (MI->isCall()) { -+ for (unsigned i = 0, e = NumRegs; i != e; ++i) -+ LiveRegs[i].Def = CurInstr; - } - -- return !DomP.first; -+ return Kill; - } - - /// \brief Helps avoid false dependencies on undef registers by updating the - /// machine instructions' undef operand to use a register that the instruction - /// is truly dependent on, or use a register with clearance higher than Pref. - void ExeDepsFix::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, -- unsigned Pref) { -+ unsigned Pref, bool &TrueDependency) { - MachineOperand &MO = MI->getOperand(OpIdx); - assert(MO.isUndef() && "Expected undef machine operand"); - -@@ -510,6 +535,7 @@ void ExeDepsFix::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, - // We found a true dependency - replace the undef register with the true - // dependency. - MO.setReg(CurrMO.getReg()); -+ TrueDependency = true; - return; - } - -@@ -571,9 +597,14 @@ void ExeDepsFix::processDefs(MachineInstr *MI, bool BlockDone, bool Kill) { - if (BlockDone) { - unsigned Pref = TII->getUndefRegClearance(*MI, OpNum, TRI); - if (Pref) { -- pickBestRegisterForUndef(MI, OpNum, Pref); -- if (shouldBreakDependence(MI, OpNum, Pref)) -+ bool TrueDependency = false; -+ pickBestRegisterForUndef(MI, OpNum, Pref, TrueDependency); -+ // Don't bother adding true dependencies to UndefReads. All we'd find out -+ // is that the register is live (since this very instruction depends on -+ // it), so we can't do anything. -+ if (!TrueDependency && shouldBreakDependence(MI, OpNum, Pref)) { - UndefReads.push_back(std::make_pair(MI, OpNum)); -+ } - } - } - const MCInstrDesc &MCID = MI->getDesc(); -@@ -606,9 +637,52 @@ void ExeDepsFix::processDefs(MachineInstr *MI, bool BlockDone, bool Kill) { - kill(rx); - } - } -+ unsigned DepReg = 0; -+ if (TII->isDependencyBreak(*MI, &DepReg)) { -+ for (int rx : regIndices(DepReg)) { -+ // This instruction is a dependency break, so there are no clearance -+ // issues, reset the counter. -+ LiveRegs[rx].Def = -(1 << 20); -+ } -+ } - ++CurInstr; - } - -+// Set the undef read register to `Reg` for all UndefReads in the range -+// [from,to). -+void ExeDepsFix::collapseUndefReads(unsigned from, unsigned to, unsigned Reg) { -+ if (from >= to) -+ return; -+ for (unsigned i = from; i < to; ++i) { -+ MachineInstr *MI = std::get<0>(UndefReads[i]); -+ unsigned OpIdx = std::get<1>(UndefReads[i]); -+ MachineOperand &MO = MI->getOperand(OpIdx); -+ MO.setReg(Reg); -+ } -+ TII->breakPartialRegDependency(*std::get<0>(UndefReads[from]), -+ std::get<1>(UndefReads[from]), TRI); -+} -+ -+unsigned ExeDepsFix::updateChooseableRegs(SparseSet &ChoosableRegs, -+ const TargetRegisterClass *OpRC, -+ bool add) { -+ unsigned LowestValid = (unsigned)-1; -+ -+ for (auto Reg : OpRC->getRegisters()) { -+ if (LiveRegSet.contains(Reg)) -+ ChoosableRegs.erase(Reg); -+ else if (add) { -+ ChoosableRegs.insert(Reg); -+ if (LowestValid == (unsigned)-1) -+ LowestValid = Reg; -+ } else if (ChoosableRegs.count(Reg) == 1) { -+ if (LowestValid == (unsigned)-1) -+ LowestValid = Reg; -+ } -+ } -+ return LowestValid; -+} -+ - /// \break Break false dependencies on undefined register reads. - /// - /// Walk the block backward computing precise liveness. This is expensive, so we -@@ -619,31 +693,87 @@ void ExeDepsFix::processUndefReads(MachineBasicBlock *MBB) { - if (UndefReads.empty()) - return; - -+ // We want to be slightly clever here, to avoid the following common pattern: -+ // Suppose we have some instruction `vrandom %in, %out` and the following code -+ // vrandom %xmm0, %xmm0 -+ // vrandom %xmm1, %xmm1 -+ // vrandom %xmm2, %xmm2 -+ // vrandom %xmm3, %xmm3 -+ // The earlier logic likes to produce these, because it picks the first -+ // register -+ // to break ties in clearance. However, most register allocators pick the dest -+ // register the same way. Naively, we'd have to insert a dependency break, -+ // before every instruction above. However, what we really want is -+ // vxorps %xmm3, %xmm3, %xmm3 -+ // vrandom %xmm3, %xmm0 -+ // vrandom %xmm3, %xmm1 -+ // vrandom %xmm3, %xmm2 -+ // vrandom %xmm3, %xmm3 -+ // To do so, we walk backwards and cumulatively keep track of which registers -+ // we can use to break the dependency. Then, once the set has collapsed, we -+ // reset the undef read register for all following instructions. -+ - // Collect this block's live out register units. - LiveRegSet.init(*TRI); - // We do not need to care about pristine registers as they are just preserved - // but not actually used in the function. - LiveRegSet.addLiveOutsNoPristines(*MBB); - -- MachineInstr *UndefMI = UndefReads.back().first; -- unsigned OpIdx = UndefReads.back().second; -+ SparseSet ChoosableRegs; -+ ChoosableRegs.setUniverse(TRI->getNumRegs()); -+ -+ unsigned LastValid = (unsigned)-1; -+ const TargetRegisterClass *LastOpRC = nullptr; -+ size_t i, LastInit; -+ i = LastInit = UndefReads.size() - 1; -+ MachineInstr *UndefMI = std::get<0>(UndefReads[i]); - - for (MachineInstr &I : make_range(MBB->rbegin(), MBB->rend())) { - // Update liveness, including the current instruction's defs. - LiveRegSet.stepBackward(I); - -+ // This ensures that we don't accidentally pick a register whose live region -+ // lies entirely between two undef reads (since that would defeat the -+ // purpose of breaking the dependency). -+ for (auto LiveReg : LiveRegSet) -+ ChoosableRegs.erase(LiveReg); -+ - if (UndefMI == &I) { -- if (!LiveRegSet.contains(UndefMI->getOperand(OpIdx).getReg())) -- TII->breakPartialRegDependency(*UndefMI, OpIdx, TRI); -+ unsigned OpIdx = std::get<1>(UndefReads[i]); -+ // Get the undef operand's register class -+ const TargetRegisterClass *OpRC = -+ TII->getRegClass(UndefMI->getDesc(), OpIdx, TRI, *MF); -+ if (OpRC != LastOpRC || ChoosableRegs.size() == 0) { -+ if (LastInit != i) { -+ if (LastValid != (unsigned)-1) -+ collapseUndefReads(i + 1, LastInit + 1, LastValid); -+ ChoosableRegs.clear(); -+ LastInit = i; -+ } -+ } -+ -+ unsigned LowestValid = -+ updateChooseableRegs(ChoosableRegs, OpRC, LastInit == i); -+ -+ if (ChoosableRegs.size() == 0) { -+ if (LastInit != i) { -+ if (LastValid != (unsigned)-1) -+ collapseUndefReads(i + 1, LastInit + 1, LastValid); -+ LowestValid = updateChooseableRegs(ChoosableRegs, OpRC, true); -+ LastInit = i; -+ } -+ } -+ LastValid = LowestValid; -+ LastOpRC = OpRC; - -- UndefReads.pop_back(); -- if (UndefReads.empty()) -- return; -+ if (i == 0) -+ break; - -- UndefMI = UndefReads.back().first; -- OpIdx = UndefReads.back().second; -+ UndefMI = std::get<0>(UndefReads[--i]); - } - } -+ if (LastValid != (unsigned)-1) -+ collapseUndefReads(0, LastInit + 1, LastValid); - } - - // A hard instruction only works in one domain. All input registers will be -@@ -787,9 +917,7 @@ void ExeDepsFix::processBasicBlock(MachineBasicBlock *MBB, bool PrimaryPass, - enterBasicBlock(MBB); - for (MachineInstr &MI : *MBB) { - if (!MI.isDebugValue()) { -- bool Kill = false; -- if (PrimaryPass) -- Kill = visitInstr(&MI); -+ bool Kill = visitInstr(&MI, PrimaryPass); - processDefs(&MI, isBlockDone(MBB), Kill); - } - } -diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp -index 627b6120b04..26665b2a15d 100644 ---- a/lib/Target/X86/X86InstrInfo.cpp -+++ b/lib/Target/X86/X86InstrInfo.cpp -@@ -7432,6 +7432,23 @@ void X86InstrInfo::breakPartialRegDependency( - } - } - -+bool X86InstrInfo::isDependencyBreak(MachineInstr &MI, unsigned *OutReg) const { -+ unsigned Opc = MI.getOpcode(); -+ if (!(Opc == X86::VXORPSrr || Opc == X86::VXORPDrr || Opc == X86::XORPSrr || -+ Opc == X86::XORPDrr)) -+ return false; -+ unsigned Reg = 0; -+ for (unsigned i = 0; i < MI.getNumOperands(); ++i) { -+ const MachineOperand &MO = MI.getOperand(i); -+ if (!MO.isReg() || (Reg != 0 && MO.getReg() != Reg)) -+ return false; -+ Reg = MO.getReg(); -+ } -+ if (OutReg) -+ *OutReg = Reg; -+ return true; -+} -+ - MachineInstr * - X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, - ArrayRef Ops, -diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h -index acfdef4da7a..4ea9ddfc863 100644 ---- a/lib/Target/X86/X86InstrInfo.h -+++ b/lib/Target/X86/X86InstrInfo.h -@@ -477,6 +477,7 @@ public: - const TargetRegisterInfo *TRI) const override; - void breakPartialRegDependency(MachineInstr &MI, unsigned OpNum, - const TargetRegisterInfo *TRI) const override; -+ bool isDependencyBreak(MachineInstr &MI, unsigned *OutReg) const override; - - MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, - unsigned OpNum, diff --git a/deps/patches/llvm-D30114.patch b/deps/patches/llvm-D30114.patch deleted file mode 100644 index 6d2cde9370d32..0000000000000 --- a/deps/patches/llvm-D30114.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0ee8e563c9b4c77183c4a3b5fbbbb0ed71d3d5bb Mon Sep 17 00:00:00 2001 -From: Eli Friedman -Date: Fri, 24 Feb 2017 20:51:36 +0000 -Subject: [PATCH] [CodeGenPrepare] Make -addr-sink-using-gep work with address - spaces. - -When we construct addressing modes, we use isNoopAddrSpaceCast to ignore -addrspacecast instructions. Make sure we insert the correct addrspacecast -when we reconstruct the addressing mode. - -Differential Revision: https://reviews.llvm.org/D30114 - - - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296167 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/CodeGen/CodeGenPrepare.cpp | 8 ++++---- - test/Transforms/CodeGenPrepare/X86/sink-addrspacecast.ll | 11 ++++++++--- - 2 files changed, 12 insertions(+), 7 deletions(-) - -diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp -index 09d8b0274e5..2c9395ca4b2 100644 ---- a/lib/CodeGen/CodeGenPrepare.cpp -+++ b/lib/CodeGen/CodeGenPrepare.cpp -@@ -4167,7 +4167,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, - DEBUG(dbgs() << "CGP: Reusing nonlocal addrmode: " << AddrMode << " for " - << *MemoryInst << "\n"); - if (SunkAddr->getType() != Addr->getType()) -- SunkAddr = Builder.CreateBitCast(SunkAddr, Addr->getType()); -+ SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType()); - } else if (AddrSinkUsingGEPs || - (!AddrSinkUsingGEPs.getNumOccurrences() && TM && - SubtargetInfo->useAA())) { -@@ -4273,7 +4273,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, - // We need to add this separately from the scale above to help with - // SDAG consecutive load/store merging. - if (ResultPtr->getType() != I8PtrTy) -- ResultPtr = Builder.CreateBitCast(ResultPtr, I8PtrTy); -+ ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy); - ResultPtr = Builder.CreateGEP(I8Ty, ResultPtr, ResultIndex, "sunkaddr"); - } - -@@ -4284,12 +4284,12 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, - SunkAddr = ResultPtr; - } else { - if (ResultPtr->getType() != I8PtrTy) -- ResultPtr = Builder.CreateBitCast(ResultPtr, I8PtrTy); -+ ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy); - SunkAddr = Builder.CreateGEP(I8Ty, ResultPtr, ResultIndex, "sunkaddr"); - } - - if (SunkAddr->getType() != Addr->getType()) -- SunkAddr = Builder.CreateBitCast(SunkAddr, Addr->getType()); -+ SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType()); - } - } else { - DEBUG(dbgs() << "CGP: SINKING nonlocal addrmode: " << AddrMode << " for " -diff --git a/test/Transforms/CodeGenPrepare/X86/sink-addrspacecast.ll b/test/Transforms/CodeGenPrepare/X86/sink-addrspacecast.ll -index c9f49b5d4f8..eb2c985c70e 100644 ---- a/test/Transforms/CodeGenPrepare/X86/sink-addrspacecast.ll -+++ b/test/Transforms/CodeGenPrepare/X86/sink-addrspacecast.ll -@@ -1,11 +1,14 @@ --; RUN: opt -S -codegenprepare < %s | FileCheck %s -+; RUN: opt -S -codegenprepare < %s | FileCheck %s -check-prefix=CHECK -check-prefix=INT -+; RUN: opt -S -codegenprepare -addr-sink-using-gep=true < %s | FileCheck %s -check-prefix=CHECK -check-prefix=GEP - - target datalayout = - "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" - target triple = "x86_64-unknown-linux-gnu" - - ; CHECK-LABEL: @load_cast_gep --; CHECK: add i64 %sunkaddr, 40 -+; INT: add i64 %sunkaddr, 40 -+; GEP: [[CAST:%[0-9]+]] = addrspacecast i64* %base to i8 addrspace(1)* -+; GEP: getelementptr i8, i8 addrspace(1)* [[CAST]], i64 40 - define void @load_cast_gep(i1 %cond, i64* %base) { - entry: - %addr = getelementptr inbounds i64, i64* %base, i64 5 -@@ -21,7 +24,9 @@ fallthrough: - } - - ; CHECK-LABEL: @store_gep_cast --; CHECK: add i64 %sunkaddr, 20 -+; INT: add i64 %sunkaddr, 20 -+; GEP: [[CAST:%[0-9]+]] = addrspacecast i64* %base to i8 addrspace(1)* -+; GEP: getelementptr i8, i8 addrspace(1)* [[CAST]], i64 20 - define void @store_gep_cast(i1 %cond, i64* %base) { - entry: - %casted = addrspacecast i64* %base to i32 addrspace(1)* --- -2.16.2 - diff --git a/deps/patches/llvm-D30478-VNCoercion.patch b/deps/patches/llvm-D30478-VNCoercion.patch deleted file mode 100644 index 99ba3d9739bf4..0000000000000 --- a/deps/patches/llvm-D30478-VNCoercion.patch +++ /dev/null @@ -1,1139 +0,0 @@ -From 6a7ec8843d08cb2cb8d4f55353c67d879ceacb92 Mon Sep 17 00:00:00 2001 -From: Daniel Berlin -Date: Fri, 10 Mar 2017 04:54:10 +0000 -Subject: [PATCH 1/5] Move memory coercion functions from GVN.cpp to - VNCoercion.cpp so they can be shared between GVN and NewGVN. - -Summary: -These are the functions used to determine when values of loads can be -extracted from stores, etc, and to perform the necessary insertions to -do this. There are no changes to the functions themselves except -reformatting, and one case where memdep was informed of a removed load -(which was pushed into the caller). - -Reviewers: davide - -Subscribers: mgorny, llvm-commits, Prazek - -Differential Revision: https://reviews.llvm.org/D30478 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297438 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - include/llvm/Transforms/Utils/VNCoercion.h | 96 ++++++ - lib/Transforms/Scalar/GVN.cpp | 466 ++--------------------------- - lib/Transforms/Utils/CMakeLists.txt | 1 + - lib/Transforms/Utils/VNCoercion.cpp | 440 +++++++++++++++++++++++++++ - 4 files changed, 556 insertions(+), 447 deletions(-) - create mode 100644 include/llvm/Transforms/Utils/VNCoercion.h - create mode 100644 lib/Transforms/Utils/VNCoercion.cpp - -diff --git a/include/llvm/Transforms/Utils/VNCoercion.h b/include/llvm/Transforms/Utils/VNCoercion.h -new file mode 100644 -index 00000000000..d3c998fa8a8 ---- /dev/null -+++ b/include/llvm/Transforms/Utils/VNCoercion.h -@@ -0,0 +1,96 @@ -+//===- VNCoercion.h - Value Numbering Coercion Utilities --------*- C++ -*-===// -+// -+// The LLVM Compiler Infrastructure -+// -+// This file is distributed under the University of Illinois Open Source -+// License. See LICENSE.TXT for details. -+// -+//===----------------------------------------------------------------------===// -+/// \file / This file provides routines used by LLVM's value numbering passes to -+/// perform various forms of value extraction from memory when the types are not -+/// identical. For example, given -+/// -+/// store i32 8, i32 *%foo -+/// %a = bitcast i32 *%foo to i16 -+/// %val = load i16, i16 *%a -+/// -+/// It possible to extract the value of the load of %a from the store to %foo. -+/// These routines know how to tell whether they can do that (the analyze* -+/// routines), and can also insert the necessary IR to do it (the get* -+/// routines). -+ -+#ifndef LLVM_TRANSFORMS_UTILS_VNCOERCION_H -+#define LLVM_TRANSFORMS_UTILS_VNCOERCION_H -+#include "llvm/IR/IRBuilder.h" -+ -+namespace llvm { -+class Function; -+class StoreInst; -+class LoadInst; -+class MemIntrinsic; -+class Instruction; -+class Value; -+class Type; -+class DataLayout; -+namespace VNCoercion { -+/// Return true if CoerceAvailableValueToLoadType would succeed if it was -+/// called. -+bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, -+ const DataLayout &DL); -+ -+/// If we saw a store of a value to memory, and then a load from a must-aliased -+/// pointer of a different type, try to coerce the stored value to the loaded -+/// type. LoadedTy is the type of the load we want to replace. IRB is -+/// IRBuilder used to insert new instructions. -+/// -+/// If we can't do it, return null. -+Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, -+ IRBuilder<> &IRB, const DataLayout &DL); -+ -+/// This function determines whether a value for the pointer LoadPtr can be -+/// extracted from the store at DepSI. -+/// -+/// On success, it returns the offset into DepSI that extraction would start. -+/// On failure, it returns -1. -+int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, -+ StoreInst *DepSI); -+ -+/// This function determines whether a value for the pointer LoadPtr can be -+/// extracted from the load at DepLI. -+/// -+/// On success, it returns the offset into DepLI that extraction would start. -+/// On failure, it returns -1. -+int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI, -+ const DataLayout &DL); -+ -+/// This function determines whether a value for the pointer LoadPtr can be -+/// extracted from the memory intrinsic at DepMI. -+/// -+/// On success, it returns the offset into DepMI that extraction would start. -+/// On failure, it returns -1. -+int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, -+ MemIntrinsic *DepMI, const DataLayout &DL); -+ -+/// If analyzeLoadFromClobberingStore returned an offset, this function can be -+/// used to actually perform the extraction of the bits from the store. It -+/// inserts instructions to do so at InsertPt, and returns the extracted value. -+Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, -+ Instruction *InsertPt, const DataLayout &DL); -+ -+/// If analyzeLoadFromClobberingLoad returned an offset, this function can be -+/// used to actually perform the extraction of the bits from the load, including -+/// any necessary load widening. It inserts instructions to do so at InsertPt, -+/// and returns the extracted value. -+Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy, -+ Instruction *InsertPt); -+ -+/// If analyzeLoadFromClobberingMemInst returned an offset, this function can be -+/// used to actually perform the extraction of the bits from the memory -+/// intrinsic. It inserts instructions to do so at InsertPt, and returns the -+/// extracted value. -+Value *getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, -+ Type *LoadTy, Instruction *InsertPt, -+ const DataLayout &DL); -+} -+} -+#endif -diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp -index 0137378b828..132c7297d77 100644 ---- a/lib/Transforms/Scalar/GVN.cpp -+++ b/lib/Transforms/Scalar/GVN.cpp -@@ -36,7 +36,6 @@ - #include "llvm/Analysis/OptimizationDiagnosticInfo.h" - #include "llvm/Analysis/PHITransAddr.h" - #include "llvm/Analysis/TargetLibraryInfo.h" --#include "llvm/Analysis/ValueTracking.h" - #include "llvm/IR/DataLayout.h" - #include "llvm/IR/Dominators.h" - #include "llvm/IR/GlobalVariable.h" -@@ -51,9 +50,12 @@ - #include "llvm/Transforms/Utils/BasicBlockUtils.h" - #include "llvm/Transforms/Utils/Local.h" - #include "llvm/Transforms/Utils/SSAUpdater.h" -+#include "llvm/Transforms/Utils/VNCoercion.h" -+ - #include - using namespace llvm; - using namespace llvm::gvn; -+using namespace llvm::VNCoercion; - using namespace PatternMatch; - - #define DEBUG_TYPE "gvn" -@@ -690,442 +692,6 @@ SpeculationFailure: - } - - --/// Return true if CoerceAvailableValueToLoadType will succeed. --static bool CanCoerceMustAliasedValueToLoad(Value *StoredVal, -- Type *LoadTy, -- const DataLayout &DL) { -- // If the loaded or stored value is an first class array or struct, don't try -- // to transform them. We need to be able to bitcast to integer. -- if (LoadTy->isStructTy() || LoadTy->isArrayTy() || -- StoredVal->getType()->isStructTy() || -- StoredVal->getType()->isArrayTy()) -- return false; -- -- // The store has to be at least as big as the load. -- if (DL.getTypeSizeInBits(StoredVal->getType()) < -- DL.getTypeSizeInBits(LoadTy)) -- return false; -- -- return true; --} -- --/// If we saw a store of a value to memory, and --/// then a load from a must-aliased pointer of a different type, try to coerce --/// the stored value. LoadedTy is the type of the load we want to replace. --/// IRB is IRBuilder used to insert new instructions. --/// --/// If we can't do it, return null. --static Value *CoerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, -- IRBuilder<> &IRB, -- const DataLayout &DL) { -- assert(CanCoerceMustAliasedValueToLoad(StoredVal, LoadedTy, DL) && -- "precondition violation - materialization can't fail"); -- -- if (auto *C = dyn_cast(StoredVal)) -- if (auto *FoldedStoredVal = ConstantFoldConstant(C, DL)) -- StoredVal = FoldedStoredVal; -- -- // If this is already the right type, just return it. -- Type *StoredValTy = StoredVal->getType(); -- -- uint64_t StoredValSize = DL.getTypeSizeInBits(StoredValTy); -- uint64_t LoadedValSize = DL.getTypeSizeInBits(LoadedTy); -- -- // If the store and reload are the same size, we can always reuse it. -- if (StoredValSize == LoadedValSize) { -- // Pointer to Pointer -> use bitcast. -- if (StoredValTy->getScalarType()->isPointerTy() && -- LoadedTy->getScalarType()->isPointerTy()) { -- StoredVal = IRB.CreateBitCast(StoredVal, LoadedTy); -- } else { -- // Convert source pointers to integers, which can be bitcast. -- if (StoredValTy->getScalarType()->isPointerTy()) { -- StoredValTy = DL.getIntPtrType(StoredValTy); -- StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy); -- } -- -- Type *TypeToCastTo = LoadedTy; -- if (TypeToCastTo->getScalarType()->isPointerTy()) -- TypeToCastTo = DL.getIntPtrType(TypeToCastTo); -- -- if (StoredValTy != TypeToCastTo) -- StoredVal = IRB.CreateBitCast(StoredVal, TypeToCastTo); -- -- // Cast to pointer if the load needs a pointer type. -- if (LoadedTy->getScalarType()->isPointerTy()) -- StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy); -- } -- -- if (auto *C = dyn_cast(StoredVal)) -- if (auto *FoldedStoredVal = ConstantFoldConstant(C, DL)) -- StoredVal = FoldedStoredVal; -- -- return StoredVal; -- } -- -- // If the loaded value is smaller than the available value, then we can -- // extract out a piece from it. If the available value is too small, then we -- // can't do anything. -- assert(StoredValSize >= LoadedValSize && -- "CanCoerceMustAliasedValueToLoad fail"); -- -- // Convert source pointers to integers, which can be manipulated. -- if (StoredValTy->getScalarType()->isPointerTy()) { -- StoredValTy = DL.getIntPtrType(StoredValTy); -- StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy); -- } -- -- // Convert vectors and fp to integer, which can be manipulated. -- if (!StoredValTy->isIntegerTy()) { -- StoredValTy = IntegerType::get(StoredValTy->getContext(), StoredValSize); -- StoredVal = IRB.CreateBitCast(StoredVal, StoredValTy); -- } -- -- // If this is a big-endian system, we need to shift the value down to the low -- // bits so that a truncate will work. -- if (DL.isBigEndian()) { -- uint64_t ShiftAmt = DL.getTypeStoreSizeInBits(StoredValTy) - -- DL.getTypeStoreSizeInBits(LoadedTy); -- StoredVal = IRB.CreateLShr(StoredVal, ShiftAmt, "tmp"); -- } -- -- // Truncate the integer to the right size now. -- Type *NewIntTy = IntegerType::get(StoredValTy->getContext(), LoadedValSize); -- StoredVal = IRB.CreateTrunc(StoredVal, NewIntTy, "trunc"); -- -- if (LoadedTy != NewIntTy) { -- // If the result is a pointer, inttoptr. -- if (LoadedTy->getScalarType()->isPointerTy()) -- StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy, "inttoptr"); -- else -- // Otherwise, bitcast. -- StoredVal = IRB.CreateBitCast(StoredVal, LoadedTy, "bitcast"); -- } -- -- if (auto *C = dyn_cast(StoredVal)) -- if (auto *FoldedStoredVal = ConstantFoldConstant(C, DL)) -- StoredVal = FoldedStoredVal; -- -- return StoredVal; --} -- --/// This function is called when we have a --/// memdep query of a load that ends up being a clobbering memory write (store, --/// memset, memcpy, memmove). This means that the write *may* provide bits used --/// by the load but we can't be sure because the pointers don't mustalias. --/// --/// Check this case to see if there is anything more we can do before we give --/// up. This returns -1 if we have to give up, or a byte number in the stored --/// value of the piece that feeds the load. --static int AnalyzeLoadFromClobberingWrite(Type *LoadTy, Value *LoadPtr, -- Value *WritePtr, -- uint64_t WriteSizeInBits, -- const DataLayout &DL) { -- // If the loaded or stored value is a first class array or struct, don't try -- // to transform them. We need to be able to bitcast to integer. -- if (LoadTy->isStructTy() || LoadTy->isArrayTy()) -- return -1; -- -- int64_t StoreOffset = 0, LoadOffset = 0; -- Value *StoreBase = -- GetPointerBaseWithConstantOffset(WritePtr, StoreOffset, DL); -- Value *LoadBase = GetPointerBaseWithConstantOffset(LoadPtr, LoadOffset, DL); -- if (StoreBase != LoadBase) -- return -1; -- -- // If the load and store are to the exact same address, they should have been -- // a must alias. AA must have gotten confused. -- // FIXME: Study to see if/when this happens. One case is forwarding a memset -- // to a load from the base of the memset. -- -- // If the load and store don't overlap at all, the store doesn't provide -- // anything to the load. In this case, they really don't alias at all, AA -- // must have gotten confused. -- uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy); -- -- if ((WriteSizeInBits & 7) | (LoadSize & 7)) -- return -1; -- uint64_t StoreSize = WriteSizeInBits / 8; // Convert to bytes. -- LoadSize /= 8; -- -- -- bool isAAFailure = false; -- if (StoreOffset < LoadOffset) -- isAAFailure = StoreOffset+int64_t(StoreSize) <= LoadOffset; -- else -- isAAFailure = LoadOffset+int64_t(LoadSize) <= StoreOffset; -- -- if (isAAFailure) -- return -1; -- -- // If the Load isn't completely contained within the stored bits, we don't -- // have all the bits to feed it. We could do something crazy in the future -- // (issue a smaller load then merge the bits in) but this seems unlikely to be -- // valuable. -- if (StoreOffset > LoadOffset || -- StoreOffset+StoreSize < LoadOffset+LoadSize) -- return -1; -- -- // Okay, we can do this transformation. Return the number of bytes into the -- // store that the load is. -- return LoadOffset-StoreOffset; --} -- --/// This function is called when we have a --/// memdep query of a load that ends up being a clobbering store. --static int AnalyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, -- StoreInst *DepSI) { -- // Cannot handle reading from store of first-class aggregate yet. -- if (DepSI->getValueOperand()->getType()->isStructTy() || -- DepSI->getValueOperand()->getType()->isArrayTy()) -- return -1; -- -- const DataLayout &DL = DepSI->getModule()->getDataLayout(); -- Value *StorePtr = DepSI->getPointerOperand(); -- uint64_t StoreSize =DL.getTypeSizeInBits(DepSI->getValueOperand()->getType()); -- return AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr, -- StorePtr, StoreSize, DL); --} -- --/// This function is called when we have a --/// memdep query of a load that ends up being clobbered by another load. See if --/// the other load can feed into the second load. --static int AnalyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, -- LoadInst *DepLI, const DataLayout &DL){ -- // Cannot handle reading from store of first-class aggregate yet. -- if (DepLI->getType()->isStructTy() || DepLI->getType()->isArrayTy()) -- return -1; -- -- Value *DepPtr = DepLI->getPointerOperand(); -- uint64_t DepSize = DL.getTypeSizeInBits(DepLI->getType()); -- int R = AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr, DepPtr, DepSize, DL); -- if (R != -1) return R; -- -- // If we have a load/load clobber an DepLI can be widened to cover this load, -- // then we should widen it! -- int64_t LoadOffs = 0; -- const Value *LoadBase = -- GetPointerBaseWithConstantOffset(LoadPtr, LoadOffs, DL); -- unsigned LoadSize = DL.getTypeStoreSize(LoadTy); -- -- unsigned Size = MemoryDependenceResults::getLoadLoadClobberFullWidthSize( -- LoadBase, LoadOffs, LoadSize, DepLI); -- if (Size == 0) return -1; -- -- // Check non-obvious conditions enforced by MDA which we rely on for being -- // able to materialize this potentially available value -- assert(DepLI->isSimple() && "Cannot widen volatile/atomic load!"); -- assert(DepLI->getType()->isIntegerTy() && "Can't widen non-integer load"); -- -- return AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr, DepPtr, Size*8, DL); --} -- -- -- --static int AnalyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, -- MemIntrinsic *MI, -- const DataLayout &DL) { -- // If the mem operation is a non-constant size, we can't handle it. -- ConstantInt *SizeCst = dyn_cast(MI->getLength()); -- if (!SizeCst) return -1; -- uint64_t MemSizeInBits = SizeCst->getZExtValue()*8; -- -- // If this is memset, we just need to see if the offset is valid in the size -- // of the memset.. -- if (MI->getIntrinsicID() == Intrinsic::memset) -- return AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr, MI->getDest(), -- MemSizeInBits, DL); -- -- // If we have a memcpy/memmove, the only case we can handle is if this is a -- // copy from constant memory. In that case, we can read directly from the -- // constant memory. -- MemTransferInst *MTI = cast(MI); -- -- Constant *Src = dyn_cast(MTI->getSource()); -- if (!Src) return -1; -- -- GlobalVariable *GV = dyn_cast(GetUnderlyingObject(Src, DL)); -- if (!GV || !GV->isConstant()) return -1; -- -- // See if the access is within the bounds of the transfer. -- int Offset = AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr, -- MI->getDest(), MemSizeInBits, DL); -- if (Offset == -1) -- return Offset; -- -- unsigned AS = Src->getType()->getPointerAddressSpace(); -- // Otherwise, see if we can constant fold a load from the constant with the -- // offset applied as appropriate. -- Src = ConstantExpr::getBitCast(Src, -- Type::getInt8PtrTy(Src->getContext(), AS)); -- Constant *OffsetCst = -- ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); -- Src = ConstantExpr::getGetElementPtr(Type::getInt8Ty(Src->getContext()), Src, -- OffsetCst); -- Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS)); -- if (ConstantFoldLoadFromConstPtr(Src, LoadTy, DL)) -- return Offset; -- return -1; --} -- -- --/// This function is called when we have a --/// memdep query of a load that ends up being a clobbering store. This means --/// that the store provides bits used by the load but we the pointers don't --/// mustalias. Check this case to see if there is anything more we can do --/// before we give up. --static Value *GetStoreValueForLoad(Value *SrcVal, unsigned Offset, -- Type *LoadTy, -- Instruction *InsertPt, const DataLayout &DL){ -- LLVMContext &Ctx = SrcVal->getType()->getContext(); -- -- uint64_t StoreSize = (DL.getTypeSizeInBits(SrcVal->getType()) + 7) / 8; -- uint64_t LoadSize = (DL.getTypeSizeInBits(LoadTy) + 7) / 8; -- -- IRBuilder<> Builder(InsertPt); -- -- // Compute which bits of the stored value are being used by the load. Convert -- // to an integer type to start with. -- if (SrcVal->getType()->getScalarType()->isPointerTy()) -- SrcVal = Builder.CreatePtrToInt(SrcVal, -- DL.getIntPtrType(SrcVal->getType())); -- if (!SrcVal->getType()->isIntegerTy()) -- SrcVal = Builder.CreateBitCast(SrcVal, IntegerType::get(Ctx, StoreSize*8)); -- -- // Shift the bits to the least significant depending on endianness. -- unsigned ShiftAmt; -- if (DL.isLittleEndian()) -- ShiftAmt = Offset*8; -- else -- ShiftAmt = (StoreSize-LoadSize-Offset)*8; -- -- if (ShiftAmt) -- SrcVal = Builder.CreateLShr(SrcVal, ShiftAmt); -- -- if (LoadSize != StoreSize) -- SrcVal = Builder.CreateTrunc(SrcVal, IntegerType::get(Ctx, LoadSize*8)); -- -- return CoerceAvailableValueToLoadType(SrcVal, LoadTy, Builder, DL); --} -- --/// This function is called when we have a --/// memdep query of a load that ends up being a clobbering load. This means --/// that the load *may* provide bits used by the load but we can't be sure --/// because the pointers don't mustalias. Check this case to see if there is --/// anything more we can do before we give up. --static Value *GetLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, -- Type *LoadTy, Instruction *InsertPt, -- GVN &gvn) { -- const DataLayout &DL = SrcVal->getModule()->getDataLayout(); -- // If Offset+LoadTy exceeds the size of SrcVal, then we must be wanting to -- // widen SrcVal out to a larger load. -- unsigned SrcValStoreSize = DL.getTypeStoreSize(SrcVal->getType()); -- unsigned LoadSize = DL.getTypeStoreSize(LoadTy); -- if (Offset+LoadSize > SrcValStoreSize) { -- assert(SrcVal->isSimple() && "Cannot widen volatile/atomic load!"); -- assert(SrcVal->getType()->isIntegerTy() && "Can't widen non-integer load"); -- // If we have a load/load clobber an DepLI can be widened to cover this -- // load, then we should widen it to the next power of 2 size big enough! -- unsigned NewLoadSize = Offset+LoadSize; -- if (!isPowerOf2_32(NewLoadSize)) -- NewLoadSize = NextPowerOf2(NewLoadSize); -- -- Value *PtrVal = SrcVal->getPointerOperand(); -- -- // Insert the new load after the old load. This ensures that subsequent -- // memdep queries will find the new load. We can't easily remove the old -- // load completely because it is already in the value numbering table. -- IRBuilder<> Builder(SrcVal->getParent(), ++BasicBlock::iterator(SrcVal)); -- Type *DestPTy = -- IntegerType::get(LoadTy->getContext(), NewLoadSize*8); -- DestPTy = PointerType::get(DestPTy, -- PtrVal->getType()->getPointerAddressSpace()); -- Builder.SetCurrentDebugLocation(SrcVal->getDebugLoc()); -- PtrVal = Builder.CreateBitCast(PtrVal, DestPTy); -- LoadInst *NewLoad = Builder.CreateLoad(PtrVal); -- NewLoad->takeName(SrcVal); -- NewLoad->setAlignment(SrcVal->getAlignment()); -- -- DEBUG(dbgs() << "GVN WIDENED LOAD: " << *SrcVal << "\n"); -- DEBUG(dbgs() << "TO: " << *NewLoad << "\n"); -- -- // Replace uses of the original load with the wider load. On a big endian -- // system, we need to shift down to get the relevant bits. -- Value *RV = NewLoad; -- if (DL.isBigEndian()) -- RV = Builder.CreateLShr(RV, (NewLoadSize - SrcValStoreSize) * 8); -- RV = Builder.CreateTrunc(RV, SrcVal->getType()); -- SrcVal->replaceAllUsesWith(RV); -- -- // We would like to use gvn.markInstructionForDeletion here, but we can't -- // because the load is already memoized into the leader map table that GVN -- // tracks. It is potentially possible to remove the load from the table, -- // but then there all of the operations based on it would need to be -- // rehashed. Just leave the dead load around. -- gvn.getMemDep().removeInstruction(SrcVal); -- SrcVal = NewLoad; -- } -- -- return GetStoreValueForLoad(SrcVal, Offset, LoadTy, InsertPt, DL); --} -- -- --/// This function is called when we have a --/// memdep query of a load that ends up being a clobbering mem intrinsic. --static Value *GetMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, -- Type *LoadTy, Instruction *InsertPt, -- const DataLayout &DL){ -- LLVMContext &Ctx = LoadTy->getContext(); -- uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy)/8; -- -- IRBuilder<> Builder(InsertPt); -- -- // We know that this method is only called when the mem transfer fully -- // provides the bits for the load. -- if (MemSetInst *MSI = dyn_cast(SrcInst)) { -- // memset(P, 'x', 1234) -> splat('x'), even if x is a variable, and -- // independently of what the offset is. -- Value *Val = MSI->getValue(); -- if (LoadSize != 1) -- Val = Builder.CreateZExt(Val, IntegerType::get(Ctx, LoadSize*8)); -- -- Value *OneElt = Val; -- -- // Splat the value out to the right number of bits. -- for (unsigned NumBytesSet = 1; NumBytesSet != LoadSize; ) { -- // If we can double the number of bytes set, do it. -- if (NumBytesSet*2 <= LoadSize) { -- Value *ShVal = Builder.CreateShl(Val, NumBytesSet*8); -- Val = Builder.CreateOr(Val, ShVal); -- NumBytesSet <<= 1; -- continue; -- } -- -- // Otherwise insert one byte at a time. -- Value *ShVal = Builder.CreateShl(Val, 1*8); -- Val = Builder.CreateOr(OneElt, ShVal); -- ++NumBytesSet; -- } -- -- return CoerceAvailableValueToLoadType(Val, LoadTy, Builder, DL); -- } -- -- // Otherwise, this is a memcpy/memmove from a constant global. -- MemTransferInst *MTI = cast(SrcInst); -- Constant *Src = cast(MTI->getSource()); -- unsigned AS = Src->getType()->getPointerAddressSpace(); -- -- // Otherwise, see if we can constant fold a load from the constant with the -- // offset applied as appropriate. -- Src = ConstantExpr::getBitCast(Src, -- Type::getInt8PtrTy(Src->getContext(), AS)); -- Constant *OffsetCst = -- ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); -- Src = ConstantExpr::getGetElementPtr(Type::getInt8Ty(Src->getContext()), Src, -- OffsetCst); -- Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS)); -- return ConstantFoldLoadFromConstPtr(Src, LoadTy, DL); --} - - - /// Given a set of loads specified by ValuesPerBlock, -@@ -1171,7 +737,7 @@ Value *AvailableValue::MaterializeAdjustedValue(LoadInst *LI, - if (isSimpleValue()) { - Res = getSimpleValue(); - if (Res->getType() != LoadTy) { -- Res = GetStoreValueForLoad(Res, Offset, LoadTy, InsertPt, DL); -+ Res = getStoreValueForLoad(Res, Offset, LoadTy, InsertPt, DL); - - DEBUG(dbgs() << "GVN COERCED NONLOCAL VAL:\nOffset: " << Offset << " " - << *getSimpleValue() << '\n' -@@ -1182,14 +748,20 @@ Value *AvailableValue::MaterializeAdjustedValue(LoadInst *LI, - if (Load->getType() == LoadTy && Offset == 0) { - Res = Load; - } else { -- Res = GetLoadValueForLoad(Load, Offset, LoadTy, InsertPt, gvn); -- -+ Res = getLoadValueForLoad(Load, Offset, LoadTy, InsertPt); -+ // We would like to use gvn.markInstructionForDeletion here, but we can't -+ // because the load is already memoized into the leader map table that GVN -+ // tracks. It is potentially possible to remove the load from the table, -+ // but then there all of the operations based on it would need to be -+ // rehashed. Just leave the dead load around. -+ gvn.getMemDep().removeInstruction(Load); - DEBUG(dbgs() << "GVN COERCED NONLOCAL LOAD:\nOffset: " << Offset << " " - << *getCoercedLoadValue() << '\n' -- << *Res << '\n' << "\n\n\n"); -+ << *Res << '\n' -+ << "\n\n\n"); - } - } else if (isMemIntrinValue()) { -- Res = GetMemInstValueForLoad(getMemIntrinValue(), Offset, LoadTy, -+ Res = getMemInstValueForLoad(getMemIntrinValue(), Offset, LoadTy, - InsertPt, DL); - DEBUG(dbgs() << "GVN COERCED NONLOCAL MEM INTRIN:\nOffset: " << Offset - << " " << *getMemIntrinValue() << '\n' -@@ -1258,7 +830,7 @@ bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo, - // Can't forward from non-atomic to atomic without violating memory model. - if (Address && LI->isAtomic() <= DepSI->isAtomic()) { - int Offset = -- AnalyzeLoadFromClobberingStore(LI->getType(), Address, DepSI); -+ analyzeLoadFromClobberingStore(LI->getType(), Address, DepSI); - if (Offset != -1) { - Res = AvailableValue::get(DepSI->getValueOperand(), Offset); - return true; -@@ -1276,7 +848,7 @@ bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo, - // Can't forward from non-atomic to atomic without violating memory model. - if (DepLI != LI && Address && LI->isAtomic() <= DepLI->isAtomic()) { - int Offset = -- AnalyzeLoadFromClobberingLoad(LI->getType(), Address, DepLI, DL); -+ analyzeLoadFromClobberingLoad(LI->getType(), Address, DepLI, DL); - - if (Offset != -1) { - Res = AvailableValue::getLoad(DepLI, Offset); -@@ -1289,7 +861,7 @@ bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo, - // forward a value on from it. - if (MemIntrinsic *DepMI = dyn_cast(DepInfo.getInst())) { - if (Address && !LI->isAtomic()) { -- int Offset = AnalyzeLoadFromClobberingMemInst(LI->getType(), Address, -+ int Offset = analyzeLoadFromClobberingMemInst(LI->getType(), Address, - DepMI, DL); - if (Offset != -1) { - Res = AvailableValue::getMI(DepMI, Offset); -@@ -1334,7 +906,7 @@ bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo, - // different types if we have to. If the stored value is larger or equal to - // the loaded value, we can reuse it. - if (S->getValueOperand()->getType() != LI->getType() && -- !CanCoerceMustAliasedValueToLoad(S->getValueOperand(), -+ !canCoerceMustAliasedValueToLoad(S->getValueOperand(), - LI->getType(), DL)) - return false; - -@@ -1351,7 +923,7 @@ bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo, - // If the stored value is larger or equal to the loaded value, we can reuse - // it. - if (LD->getType() != LI->getType() && -- !CanCoerceMustAliasedValueToLoad(LD, LI->getType(), DL)) -+ !canCoerceMustAliasedValueToLoad(LD, LI->getType(), DL)) - return false; - - // Can't forward from non-atomic to atomic without violating memory model. -diff --git a/lib/Transforms/Utils/CMakeLists.txt b/lib/Transforms/Utils/CMakeLists.txt -index 69889ec72f9..838761fd71d 100644 ---- a/lib/Transforms/Utils/CMakeLists.txt -+++ b/lib/Transforms/Utils/CMakeLists.txt -@@ -51,6 +51,7 @@ add_llvm_library(LLVMTransformUtils - UnifyFunctionExitNodes.cpp - Utils.cpp - ValueMapper.cpp -+ VNCoercion.cpp - - ADDITIONAL_HEADER_DIRS - ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms -diff --git a/lib/Transforms/Utils/VNCoercion.cpp b/lib/Transforms/Utils/VNCoercion.cpp -new file mode 100644 -index 00000000000..38d26e922c3 ---- /dev/null -+++ b/lib/Transforms/Utils/VNCoercion.cpp -@@ -0,0 +1,440 @@ -+#include "llvm/Transforms/Utils/VNCoercion.h" -+#include "llvm/Analysis/AliasAnalysis.h" -+#include "llvm/Analysis/ConstantFolding.h" -+#include "llvm/Analysis/MemoryDependenceAnalysis.h" -+#include "llvm/Analysis/ValueTracking.h" -+#include "llvm/IR/IRBuilder.h" -+#include "llvm/IR/IntrinsicInst.h" -+#include "llvm/Support/Debug.h" -+ -+#define DEBUG_TYPE "vncoerce" -+namespace llvm { -+namespace VNCoercion { -+ -+/// Return true if coerceAvailableValueToLoadType will succeed. -+bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, -+ const DataLayout &DL) { -+ // If the loaded or stored value is an first class array or struct, don't try -+ // to transform them. We need to be able to bitcast to integer. -+ if (LoadTy->isStructTy() || LoadTy->isArrayTy() || -+ StoredVal->getType()->isStructTy() || StoredVal->getType()->isArrayTy()) -+ return false; -+ -+ // The store has to be at least as big as the load. -+ if (DL.getTypeSizeInBits(StoredVal->getType()) < DL.getTypeSizeInBits(LoadTy)) -+ return false; -+ -+ return true; -+} -+ -+/// If we saw a store of a value to memory, and -+/// then a load from a must-aliased pointer of a different type, try to coerce -+/// the stored value. LoadedTy is the type of the load we want to replace. -+/// IRB is IRBuilder used to insert new instructions. -+/// -+/// If we can't do it, return null. -+Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, -+ IRBuilder<> &IRB, const DataLayout &DL) { -+ assert(canCoerceMustAliasedValueToLoad(StoredVal, LoadedTy, DL) && -+ "precondition violation - materialization can't fail"); -+ -+ if (auto *C = dyn_cast(StoredVal)) -+ if (auto *FoldedStoredVal = ConstantFoldConstant(C, DL)) -+ StoredVal = FoldedStoredVal; -+ -+ // If this is already the right type, just return it. -+ Type *StoredValTy = StoredVal->getType(); -+ -+ uint64_t StoredValSize = DL.getTypeSizeInBits(StoredValTy); -+ uint64_t LoadedValSize = DL.getTypeSizeInBits(LoadedTy); -+ -+ // If the store and reload are the same size, we can always reuse it. -+ if (StoredValSize == LoadedValSize) { -+ // Pointer to Pointer -> use bitcast. -+ if (StoredValTy->getScalarType()->isPointerTy() && -+ LoadedTy->getScalarType()->isPointerTy()) { -+ StoredVal = IRB.CreateBitCast(StoredVal, LoadedTy); -+ } else { -+ // Convert source pointers to integers, which can be bitcast. -+ if (StoredValTy->getScalarType()->isPointerTy()) { -+ StoredValTy = DL.getIntPtrType(StoredValTy); -+ StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy); -+ } -+ -+ Type *TypeToCastTo = LoadedTy; -+ if (TypeToCastTo->getScalarType()->isPointerTy()) -+ TypeToCastTo = DL.getIntPtrType(TypeToCastTo); -+ -+ if (StoredValTy != TypeToCastTo) -+ StoredVal = IRB.CreateBitCast(StoredVal, TypeToCastTo); -+ -+ // Cast to pointer if the load needs a pointer type. -+ if (LoadedTy->getScalarType()->isPointerTy()) -+ StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy); -+ } -+ -+ if (auto *C = dyn_cast(StoredVal)) -+ if (auto *FoldedStoredVal = ConstantFoldConstant(C, DL)) -+ StoredVal = FoldedStoredVal; -+ -+ return StoredVal; -+ } -+ -+ // If the loaded value is smaller than the available value, then we can -+ // extract out a piece from it. If the available value is too small, then we -+ // can't do anything. -+ assert(StoredValSize >= LoadedValSize && -+ "canCoerceMustAliasedValueToLoad fail"); -+ -+ // Convert source pointers to integers, which can be manipulated. -+ if (StoredValTy->getScalarType()->isPointerTy()) { -+ StoredValTy = DL.getIntPtrType(StoredValTy); -+ StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy); -+ } -+ -+ // Convert vectors and fp to integer, which can be manipulated. -+ if (!StoredValTy->isIntegerTy()) { -+ StoredValTy = IntegerType::get(StoredValTy->getContext(), StoredValSize); -+ StoredVal = IRB.CreateBitCast(StoredVal, StoredValTy); -+ } -+ -+ // If this is a big-endian system, we need to shift the value down to the low -+ // bits so that a truncate will work. -+ if (DL.isBigEndian()) { -+ uint64_t ShiftAmt = DL.getTypeStoreSizeInBits(StoredValTy) - -+ DL.getTypeStoreSizeInBits(LoadedTy); -+ StoredVal = IRB.CreateLShr(StoredVal, ShiftAmt, "tmp"); -+ } -+ -+ // Truncate the integer to the right size now. -+ Type *NewIntTy = IntegerType::get(StoredValTy->getContext(), LoadedValSize); -+ StoredVal = IRB.CreateTrunc(StoredVal, NewIntTy, "trunc"); -+ -+ if (LoadedTy != NewIntTy) { -+ // If the result is a pointer, inttoptr. -+ if (LoadedTy->getScalarType()->isPointerTy()) -+ StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy, "inttoptr"); -+ else -+ // Otherwise, bitcast. -+ StoredVal = IRB.CreateBitCast(StoredVal, LoadedTy, "bitcast"); -+ } -+ -+ if (auto *C = dyn_cast(StoredVal)) -+ if (auto *FoldedStoredVal = ConstantFoldConstant(C, DL)) -+ StoredVal = FoldedStoredVal; -+ -+ return StoredVal; -+} -+ -+/// This function is called when we have a -+/// memdep query of a load that ends up being a clobbering memory write (store, -+/// memset, memcpy, memmove). This means that the write *may* provide bits used -+/// by the load but we can't be sure because the pointers don't mustalias. -+/// -+/// Check this case to see if there is anything more we can do before we give -+/// up. This returns -1 if we have to give up, or a byte number in the stored -+/// value of the piece that feeds the load. -+static int analyzeLoadFromClobberingWrite(Type *LoadTy, Value *LoadPtr, -+ Value *WritePtr, -+ uint64_t WriteSizeInBits, -+ const DataLayout &DL) { -+ // If the loaded or stored value is a first class array or struct, don't try -+ // to transform them. We need to be able to bitcast to integer. -+ if (LoadTy->isStructTy() || LoadTy->isArrayTy()) -+ return -1; -+ -+ int64_t StoreOffset = 0, LoadOffset = 0; -+ Value *StoreBase = -+ GetPointerBaseWithConstantOffset(WritePtr, StoreOffset, DL); -+ Value *LoadBase = GetPointerBaseWithConstantOffset(LoadPtr, LoadOffset, DL); -+ if (StoreBase != LoadBase) -+ return -1; -+ -+ // If the load and store are to the exact same address, they should have been -+ // a must alias. AA must have gotten confused. -+ // FIXME: Study to see if/when this happens. One case is forwarding a memset -+ // to a load from the base of the memset. -+ -+ // If the load and store don't overlap at all, the store doesn't provide -+ // anything to the load. In this case, they really don't alias at all, AA -+ // must have gotten confused. -+ uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy); -+ -+ if ((WriteSizeInBits & 7) | (LoadSize & 7)) -+ return -1; -+ uint64_t StoreSize = WriteSizeInBits / 8; // Convert to bytes. -+ LoadSize /= 8; -+ -+ bool isAAFailure = false; -+ if (StoreOffset < LoadOffset) -+ isAAFailure = StoreOffset + int64_t(StoreSize) <= LoadOffset; -+ else -+ isAAFailure = LoadOffset + int64_t(LoadSize) <= StoreOffset; -+ -+ if (isAAFailure) -+ return -1; -+ -+ // If the Load isn't completely contained within the stored bits, we don't -+ // have all the bits to feed it. We could do something crazy in the future -+ // (issue a smaller load then merge the bits in) but this seems unlikely to be -+ // valuable. -+ if (StoreOffset > LoadOffset || -+ StoreOffset + StoreSize < LoadOffset + LoadSize) -+ return -1; -+ -+ // Okay, we can do this transformation. Return the number of bytes into the -+ // store that the load is. -+ return LoadOffset - StoreOffset; -+} -+ -+/// This function is called when we have a -+/// memdep query of a load that ends up being a clobbering store. -+int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, -+ StoreInst *DepSI) { -+ // Cannot handle reading from store of first-class aggregate yet. -+ if (DepSI->getValueOperand()->getType()->isStructTy() || -+ DepSI->getValueOperand()->getType()->isArrayTy()) -+ return -1; -+ -+ const DataLayout &DL = DepSI->getModule()->getDataLayout(); -+ Value *StorePtr = DepSI->getPointerOperand(); -+ uint64_t StoreSize = -+ DL.getTypeSizeInBits(DepSI->getValueOperand()->getType()); -+ return analyzeLoadFromClobberingWrite(LoadTy, LoadPtr, StorePtr, StoreSize, -+ DL); -+} -+ -+/// This function is called when we have a -+/// memdep query of a load that ends up being clobbered by another load. See if -+/// the other load can feed into the second load. -+int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI, -+ const DataLayout &DL) { -+ // Cannot handle reading from store of first-class aggregate yet. -+ if (DepLI->getType()->isStructTy() || DepLI->getType()->isArrayTy()) -+ return -1; -+ -+ Value *DepPtr = DepLI->getPointerOperand(); -+ uint64_t DepSize = DL.getTypeSizeInBits(DepLI->getType()); -+ int R = analyzeLoadFromClobberingWrite(LoadTy, LoadPtr, DepPtr, DepSize, DL); -+ if (R != -1) -+ return R; -+ -+ // If we have a load/load clobber an DepLI can be widened to cover this load, -+ // then we should widen it! -+ int64_t LoadOffs = 0; -+ const Value *LoadBase = -+ GetPointerBaseWithConstantOffset(LoadPtr, LoadOffs, DL); -+ unsigned LoadSize = DL.getTypeStoreSize(LoadTy); -+ -+ unsigned Size = MemoryDependenceResults::getLoadLoadClobberFullWidthSize( -+ LoadBase, LoadOffs, LoadSize, DepLI); -+ if (Size == 0) -+ return -1; -+ -+ // Check non-obvious conditions enforced by MDA which we rely on for being -+ // able to materialize this potentially available value -+ assert(DepLI->isSimple() && "Cannot widen volatile/atomic load!"); -+ assert(DepLI->getType()->isIntegerTy() && "Can't widen non-integer load"); -+ -+ return analyzeLoadFromClobberingWrite(LoadTy, LoadPtr, DepPtr, Size * 8, DL); -+} -+ -+int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, -+ MemIntrinsic *MI, const DataLayout &DL) { -+ // If the mem operation is a non-constant size, we can't handle it. -+ ConstantInt *SizeCst = dyn_cast(MI->getLength()); -+ if (!SizeCst) -+ return -1; -+ uint64_t MemSizeInBits = SizeCst->getZExtValue() * 8; -+ -+ // If this is memset, we just need to see if the offset is valid in the size -+ // of the memset.. -+ if (MI->getIntrinsicID() == Intrinsic::memset) -+ return analyzeLoadFromClobberingWrite(LoadTy, LoadPtr, MI->getDest(), -+ MemSizeInBits, DL); -+ -+ // If we have a memcpy/memmove, the only case we can handle is if this is a -+ // copy from constant memory. In that case, we can read directly from the -+ // constant memory. -+ MemTransferInst *MTI = cast(MI); -+ -+ Constant *Src = dyn_cast(MTI->getSource()); -+ if (!Src) -+ return -1; -+ -+ GlobalVariable *GV = dyn_cast(GetUnderlyingObject(Src, DL)); -+ if (!GV || !GV->isConstant()) -+ return -1; -+ -+ // See if the access is within the bounds of the transfer. -+ int Offset = analyzeLoadFromClobberingWrite(LoadTy, LoadPtr, MI->getDest(), -+ MemSizeInBits, DL); -+ if (Offset == -1) -+ return Offset; -+ -+ unsigned AS = Src->getType()->getPointerAddressSpace(); -+ // Otherwise, see if we can constant fold a load from the constant with the -+ // offset applied as appropriate. -+ Src = -+ ConstantExpr::getBitCast(Src, Type::getInt8PtrTy(Src->getContext(), AS)); -+ Constant *OffsetCst = -+ ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); -+ Src = ConstantExpr::getGetElementPtr(Type::getInt8Ty(Src->getContext()), Src, -+ OffsetCst); -+ Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS)); -+ if (ConstantFoldLoadFromConstPtr(Src, LoadTy, DL)) -+ return Offset; -+ return -1; -+} -+ -+/// This function is called when we have a -+/// memdep query of a load that ends up being a clobbering store. This means -+/// that the store provides bits used by the load but we the pointers don't -+/// mustalias. Check this case to see if there is anything more we can do -+/// before we give up. -+Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, -+ Instruction *InsertPt, const DataLayout &DL) { -+ LLVMContext &Ctx = SrcVal->getType()->getContext(); -+ -+ uint64_t StoreSize = (DL.getTypeSizeInBits(SrcVal->getType()) + 7) / 8; -+ uint64_t LoadSize = (DL.getTypeSizeInBits(LoadTy) + 7) / 8; -+ -+ IRBuilder<> Builder(InsertPt); -+ -+ // Compute which bits of the stored value are being used by the load. Convert -+ // to an integer type to start with. -+ if (SrcVal->getType()->getScalarType()->isPointerTy()) -+ SrcVal = -+ Builder.CreatePtrToInt(SrcVal, DL.getIntPtrType(SrcVal->getType())); -+ if (!SrcVal->getType()->isIntegerTy()) -+ SrcVal = -+ Builder.CreateBitCast(SrcVal, IntegerType::get(Ctx, StoreSize * 8)); -+ -+ // Shift the bits to the least significant depending on endianness. -+ unsigned ShiftAmt; -+ if (DL.isLittleEndian()) -+ ShiftAmt = Offset * 8; -+ else -+ ShiftAmt = (StoreSize - LoadSize - Offset) * 8; -+ -+ if (ShiftAmt) -+ SrcVal = Builder.CreateLShr(SrcVal, ShiftAmt); -+ -+ if (LoadSize != StoreSize) -+ SrcVal = Builder.CreateTrunc(SrcVal, IntegerType::get(Ctx, LoadSize * 8)); -+ -+ return coerceAvailableValueToLoadType(SrcVal, LoadTy, Builder, DL); -+} -+ -+/// This function is called when we have a -+/// memdep query of a load that ends up being a clobbering load. This means -+/// that the load *may* provide bits used by the load but we can't be sure -+/// because the pointers don't mustalias. Check this case to see if there is -+/// anything more we can do before we give up. -+Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy, -+ Instruction *InsertPt) { -+ -+ const DataLayout &DL = SrcVal->getModule()->getDataLayout(); -+ // If Offset+LoadTy exceeds the size of SrcVal, then we must be wanting to -+ // widen SrcVal out to a larger load. -+ unsigned SrcValStoreSize = DL.getTypeStoreSize(SrcVal->getType()); -+ unsigned LoadSize = DL.getTypeStoreSize(LoadTy); -+ if (Offset + LoadSize > SrcValStoreSize) { -+ assert(SrcVal->isSimple() && "Cannot widen volatile/atomic load!"); -+ assert(SrcVal->getType()->isIntegerTy() && "Can't widen non-integer load"); -+ // If we have a load/load clobber an DepLI can be widened to cover this -+ // load, then we should widen it to the next power of 2 size big enough! -+ unsigned NewLoadSize = Offset + LoadSize; -+ if (!isPowerOf2_32(NewLoadSize)) -+ NewLoadSize = NextPowerOf2(NewLoadSize); -+ -+ Value *PtrVal = SrcVal->getPointerOperand(); -+ -+ // Insert the new load after the old load. This ensures that subsequent -+ // memdep queries will find the new load. We can't easily remove the old -+ // load completely because it is already in the value numbering table. -+ IRBuilder<> Builder(SrcVal->getParent(), ++BasicBlock::iterator(SrcVal)); -+ Type *DestPTy = IntegerType::get(LoadTy->getContext(), NewLoadSize * 8); -+ DestPTy = -+ PointerType::get(DestPTy, PtrVal->getType()->getPointerAddressSpace()); -+ Builder.SetCurrentDebugLocation(SrcVal->getDebugLoc()); -+ PtrVal = Builder.CreateBitCast(PtrVal, DestPTy); -+ LoadInst *NewLoad = Builder.CreateLoad(PtrVal); -+ NewLoad->takeName(SrcVal); -+ NewLoad->setAlignment(SrcVal->getAlignment()); -+ -+ DEBUG(dbgs() << "GVN WIDENED LOAD: " << *SrcVal << "\n"); -+ DEBUG(dbgs() << "TO: " << *NewLoad << "\n"); -+ -+ // Replace uses of the original load with the wider load. On a big endian -+ // system, we need to shift down to get the relevant bits. -+ Value *RV = NewLoad; -+ if (DL.isBigEndian()) -+ RV = Builder.CreateLShr(RV, (NewLoadSize - SrcValStoreSize) * 8); -+ RV = Builder.CreateTrunc(RV, SrcVal->getType()); -+ SrcVal->replaceAllUsesWith(RV); -+ -+ SrcVal = NewLoad; -+ } -+ -+ return getStoreValueForLoad(SrcVal, Offset, LoadTy, InsertPt, DL); -+} -+ -+/// This function is called when we have a -+/// memdep query of a load that ends up being a clobbering mem intrinsic. -+Value *getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, -+ Type *LoadTy, Instruction *InsertPt, -+ const DataLayout &DL) { -+ LLVMContext &Ctx = LoadTy->getContext(); -+ uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy) / 8; -+ -+ IRBuilder<> Builder(InsertPt); -+ -+ // We know that this method is only called when the mem transfer fully -+ // provides the bits for the load. -+ if (MemSetInst *MSI = dyn_cast(SrcInst)) { -+ // memset(P, 'x', 1234) -> splat('x'), even if x is a variable, and -+ // independently of what the offset is. -+ Value *Val = MSI->getValue(); -+ if (LoadSize != 1) -+ Val = Builder.CreateZExt(Val, IntegerType::get(Ctx, LoadSize * 8)); -+ -+ Value *OneElt = Val; -+ -+ // Splat the value out to the right number of bits. -+ for (unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) { -+ // If we can double the number of bytes set, do it. -+ if (NumBytesSet * 2 <= LoadSize) { -+ Value *ShVal = Builder.CreateShl(Val, NumBytesSet * 8); -+ Val = Builder.CreateOr(Val, ShVal); -+ NumBytesSet <<= 1; -+ continue; -+ } -+ -+ // Otherwise insert one byte at a time. -+ Value *ShVal = Builder.CreateShl(Val, 1 * 8); -+ Val = Builder.CreateOr(OneElt, ShVal); -+ ++NumBytesSet; -+ } -+ -+ return coerceAvailableValueToLoadType(Val, LoadTy, Builder, DL); -+ } -+ -+ // Otherwise, this is a memcpy/memmove from a constant global. -+ MemTransferInst *MTI = cast(SrcInst); -+ Constant *Src = cast(MTI->getSource()); -+ unsigned AS = Src->getType()->getPointerAddressSpace(); -+ -+ // Otherwise, see if we can constant fold a load from the constant with the -+ // offset applied as appropriate. -+ Src = -+ ConstantExpr::getBitCast(Src, Type::getInt8PtrTy(Src->getContext(), AS)); -+ Constant *OffsetCst = -+ ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); -+ Src = ConstantExpr::getGetElementPtr(Type::getInt8Ty(Src->getContext()), Src, -+ OffsetCst); -+ Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS)); -+ return ConstantFoldLoadFromConstPtr(Src, LoadTy, DL); -+} -+} // namespace VNCoercion -+} // namespace llvm --- -2.13.1 - diff --git a/deps/patches/llvm-D31524-sovers_4.0.patch b/deps/patches/llvm-D31524-sovers_4.0.patch deleted file mode 100644 index 0e8947afc4e62..0000000000000 --- a/deps/patches/llvm-D31524-sovers_4.0.patch +++ /dev/null @@ -1,82 +0,0 @@ -From cd789d8cfe12aa374e66eafc748f4fc06e149ca7 Mon Sep 17 00:00:00 2001 -From: Sylvestre Ledru -Date: Mon, 17 Apr 2017 20:51:50 +0000 -Subject: [PATCH] Add a linker script to version LLVM symbols -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Summary: -This patch adds a very simple linker script to version the lib's symbols -and thus trying to avoid crashes if an application loads two different -LLVM versions (as long as they do not share data between them). - -Note that we deliberately *don't* make LLVM_5.0 depend on LLVM_4.0: -they're incompatible and the whole point of this patch is -to tell the linker that. - - -Avoid unexpected crashes when two LLVM versions are used in the same process. - -Author: Rebecca N. Palmer -Author: Lisandro Damían Nicanor Pérez Meyer -Author: Sylvestre Ledru -Bug-Debian: https://bugs.debian.org/848368 - - -Reviewers: beanz, rnk - -Reviewed By: rnk - -Subscribers: mgorny, llvm-commits - -Differential Revision: https://reviews.llvm.org/D31524 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300496 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - cmake/modules/AddLLVM.cmake | 3 ++- - tools/llvm-shlib/CMakeLists.txt | 6 +++++- - tools/llvm-shlib/simple_version_script.map.in | 1 + - 3 files changed, 8 insertions(+), 2 deletions(-) - create mode 100644 tools/llvm-shlib/simple_version_script.map.in - -diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake -index 7f7608cff33..e011bb40275 100644 ---- a/cmake/modules/AddLLVM.cmake -+++ b/cmake/modules/AddLLVM.cmake -@@ -81,8 +81,9 @@ function(add_llvm_symbol_exports target_name export_file) - # Gold and BFD ld require a version script rather than a plain list. - set(native_export_file "${target_name}.exports") - # FIXME: Don't write the "local:" line on OpenBSD. -+ # in the export file, also add a linker script to version LLVM symbols (form: LLVM_N.M) - add_custom_command(OUTPUT ${native_export_file} -- COMMAND echo "{" > ${native_export_file} -+ COMMAND echo "LLVM_${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR} {" > ${native_export_file} - COMMAND grep -q "[[:alnum:]]" ${export_file} && echo " global:" >> ${native_export_file} || : - COMMAND sed -e "s/$/;/" -e "s/^/ /" < ${export_file} >> ${native_export_file} - COMMAND echo " local: *;" >> ${native_export_file} -diff --git a/tools/llvm-shlib/CMakeLists.txt b/tools/llvm-shlib/CMakeLists.txt -index c68a2b0e60e..27815868629 100644 ---- a/tools/llvm-shlib/CMakeLists.txt -+++ b/tools/llvm-shlib/CMakeLists.txt -@@ -38,8 +38,12 @@ add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB SONAME ${SOURCES}) - - list(REMOVE_DUPLICATES LIB_NAMES) - if(("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") OR (MINGW) OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD") OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly")) # FIXME: It should be "GNU ld for elf" -+ configure_file( -+ ${CMAKE_CURRENT_SOURCE_DIR}/simple_version_script.map.in -+ ${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map) -+ - # GNU ld doesn't resolve symbols in the version script. -- set(LIB_NAMES -Wl,--whole-archive ${LIB_NAMES} -Wl,--no-whole-archive) -+ set(LIB_NAMES -Wl,--version-script,${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map -Wl,--whole-archive ${LIB_NAMES} -Wl,--no-whole-archive) - elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") - set(LIB_NAMES -Wl,-all_load ${LIB_NAMES}) - endif() -diff --git a/tools/llvm-shlib/simple_version_script.map.in b/tools/llvm-shlib/simple_version_script.map.in -new file mode 100644 -index 00000000000..e9515fe7862 ---- /dev/null -+++ b/tools/llvm-shlib/simple_version_script.map.in -@@ -0,0 +1 @@ -+LLVM_@LLVM_VERSION_MAJOR@.@LLVM_VERSION_MINOR@ { global: *; }; diff --git a/deps/patches/llvm-D32196-LIR-non-integral.patch b/deps/patches/llvm-D32196-LIR-non-integral.patch deleted file mode 100644 index 28b4abdafa225..0000000000000 --- a/deps/patches/llvm-D32196-LIR-non-integral.patch +++ /dev/null @@ -1,95 +0,0 @@ -From aebd138996c29589d44d6eccea659757c6184b44 Mon Sep 17 00:00:00 2001 -From: Sanjoy Das -Date: Mon, 24 Apr 2017 20:12:10 +0000 -Subject: [PATCH 3/5] [LIR] Obey non-integral pointer semantics - -Summary: See http://llvm.org/docs/LangRef.html#non-integral-pointer-type - -Reviewers: haicheng - -Reviewed By: haicheng - -Subscribers: mcrosier, mzolotukhin, llvm-commits - -Differential Revision: https://reviews.llvm.org/D32196 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301238 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 5 +++ - test/Transforms/LoopIdiom/non-integral-pointers.ll | 48 ++++++++++++++++++++++ - 2 files changed, 53 insertions(+) - create mode 100644 test/Transforms/LoopIdiom/non-integral-pointers.ll - -diff --git a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp -index 5fec51c095d..570c55a3e76 100644 ---- a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp -+++ b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp -@@ -345,6 +345,11 @@ bool LoopIdiomRecognize::isLegalStore(StoreInst *SI, bool &ForMemset, - if (!SI->isSimple()) - return false; - -+ // Don't convert stores of non-integral pointer types to memsets (which stores -+ // integers). -+ if (DL->isNonIntegralPointerType(SI->getValueOperand()->getType())) -+ return false; -+ - // Avoid merging nontemporal stores. - if (SI->getMetadata(LLVMContext::MD_nontemporal)) - return false; -diff --git a/test/Transforms/LoopIdiom/non-integral-pointers.ll b/test/Transforms/LoopIdiom/non-integral-pointers.ll -new file mode 100644 -index 00000000000..7646d5ac72d ---- /dev/null -+++ b/test/Transforms/LoopIdiom/non-integral-pointers.ll -@@ -0,0 +1,48 @@ -+; RUN: opt -S -basicaa -loop-idiom < %s | FileCheck %s -+ -+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4" -+target triple = "x86_64-unknown-linux-gnu" -+ -+define void @f_0(i8 addrspace(3)** %ptr) { -+; CHECK-LABEL: @f_0( -+; CHECK: call{{.*}}memset -+ -+; LIR'ing stores of pointers with address space 3 is fine, since -+; they're integral pointers. -+ -+entry: -+ br label %for.body -+ -+for.body: -+ %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ] -+ %arrayidx = getelementptr i8 addrspace(3)*, i8 addrspace(3)** %ptr, i64 %indvar -+ store i8 addrspace(3)* null, i8 addrspace(3)** %arrayidx, align 4 -+ %indvar.next = add i64 %indvar, 1 -+ %exitcond = icmp eq i64 %indvar.next, 10000 -+ br i1 %exitcond, label %for.end, label %for.body -+ -+for.end: -+ ret void -+} -+ -+define void @f_1(i8 addrspace(4)** %ptr) { -+; CHECK-LABEL: @f_1( -+; CHECK-NOT: call{{.*}}memset -+ -+; LIR'ing stores of pointers with address space 4 is not ok, since -+; they're non-integral pointers. -+ -+entry: -+ br label %for.body -+ -+for.body: -+ %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ] -+ %arrayidx = getelementptr i8 addrspace(4)*, i8 addrspace(4)** %ptr, i64 %indvar -+ store i8 addrspace(4)* null, i8 addrspace(4)** %arrayidx, align 4 -+ %indvar.next = add i64 %indvar, 1 -+ %exitcond = icmp eq i64 %indvar.next, 10000 -+ br i1 %exitcond, label %for.end, label %for.body -+ -+for.end: -+ ret void -+} --- -2.13.1 - diff --git a/deps/patches/llvm-D32203-SORA-non-integral.patch b/deps/patches/llvm-D32203-SORA-non-integral.patch deleted file mode 100644 index 6c9b75b1ca0da..0000000000000 --- a/deps/patches/llvm-D32203-SORA-non-integral.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 2fe2c1173e286203309e5bb9b034fd55dc9fc8fc Mon Sep 17 00:00:00 2001 -From: Sanjoy Das -Date: Sat, 17 Jun 2017 11:06:25 -0400 -Subject: [PATCH 1/2] [SROA] Add support for non-integral pointers - -Summary: C.f. http://llvm.org/docs/LangRef.html#non-integral-pointer-type - -Reviewers: chandlerc, loladiro - -Reviewed By: loladiro - -Subscribers: reames, loladiro, mcrosier, llvm-commits - -Differential Revision: https://reviews.llvm.org/D32203 ---- - lib/Transforms/Scalar/SROA.cpp | 13 ++++++-- - test/Transforms/SROA/non-integral-pointers.ll | 46 +++++++++++++++++++++++++++ - 2 files changed, 57 insertions(+), 2 deletions(-) - create mode 100644 test/Transforms/SROA/non-integral-pointers.ll - -diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp -index d28490f3a50..ec8636fe25a 100644 ---- a/lib/Transforms/Scalar/SROA.cpp -+++ b/lib/Transforms/Scalar/SROA.cpp -@@ -1636,8 +1636,17 @@ static bool canConvertValue(const DataLayout &DL, Type *OldTy, Type *NewTy) { - return cast(NewTy)->getPointerAddressSpace() == - cast(OldTy)->getPointerAddressSpace(); - } -- if (NewTy->isIntegerTy() || OldTy->isIntegerTy()) -- return true; -+ -+ // We can convert integers to integral pointers, but not to non-integral -+ // pointers. -+ if (OldTy->isIntegerTy()) -+ return !DL.isNonIntegralPointerType(NewTy); -+ -+ // We can convert integral pointers to integers, but non-integral pointers -+ // need to remain pointers. -+ if (!DL.isNonIntegralPointerType(OldTy)) -+ return NewTy->isIntegerTy(); -+ - return false; - } - -diff --git a/test/Transforms/SROA/non-integral-pointers.ll b/test/Transforms/SROA/non-integral-pointers.ll -new file mode 100644 -index 00000000000..63286309f6f ---- /dev/null -+++ b/test/Transforms/SROA/non-integral-pointers.ll -@@ -0,0 +1,46 @@ -+; RUN: opt -sroa -S < %s | FileCheck %s -+ -+; This test checks that SROA does not introduce ptrtoint and inttoptr -+; casts from and to non-integral pointers. The "ni:4" bit in the -+; datalayout states that pointers of address space 4 are to be -+; considered "non-integral". -+ -+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4" -+target triple = "x86_64-unknown-linux-gnu" -+ -+define void @f0(i1 %alwaysFalse, i64 %val) { -+; CHECK-LABEL: @f0( -+; CHECK-NOT: inttoptr -+; CHECK-NOT: ptrtoint -+entry: -+ %loc = alloca i64 -+ store i64 %val, i64* %loc -+ br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken -+ -+neverTaken: -+ %loc.bc = bitcast i64* %loc to i8 addrspace(4)** -+ %ptr = load i8 addrspace(4)*, i8 addrspace(4)** %loc.bc -+ store i8 5, i8 addrspace(4)* %ptr -+ ret void -+ -+alwaysTaken: -+ ret void -+} -+ -+define i64 @f1(i1 %alwaysFalse, i8 addrspace(4)* %val) { -+; CHECK-LABEL: @f1( -+; CHECK-NOT: inttoptr -+; CHECK-NOT: ptrtoint -+entry: -+ %loc = alloca i8 addrspace(4)* -+ store i8 addrspace(4)* %val, i8 addrspace(4)** %loc -+ br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken -+ -+neverTaken: -+ %loc.bc = bitcast i8 addrspace(4)** %loc to i64* -+ %int = load i64, i64* %loc.bc -+ ret i64 %int -+ -+alwaysTaken: -+ ret i64 42 -+} --- -2.13.1 - diff --git a/deps/patches/llvm-D32208-coerce-non-integral.patch b/deps/patches/llvm-D32208-coerce-non-integral.patch deleted file mode 100644 index bc0ec8a594e72..0000000000000 --- a/deps/patches/llvm-D32208-coerce-non-integral.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 2a7ef55ed78bb5f147900af862fed32103257839 Mon Sep 17 00:00:00 2001 -From: Sanjoy Das -Date: Wed, 19 Apr 2017 18:21:09 +0000 -Subject: [PATCH 2/5] [GVN] Don't coerce non-integral pointers to integers or - vice versa - -Summary: -See http://llvm.org/docs/LangRef.html#non-integral-pointer-type - -The NewGVN test does not fail without these changes (perhaps it does -try to coerce pointers <-> integers to begin with?), but I added the -test case anyway. - -Reviewers: dberlin - -Subscribers: mcrosier, llvm-commits, Prazek - -Differential Revision: https://reviews.llvm.org/D32208 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300730 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Transforms/Utils/VNCoercion.cpp | 5 ++++ - test/Transforms/GVN/non-integral-pointers.ll | 39 +++++++++++++++++++++++++ - test/Transforms/NewGVN/non-integral-pointers.ll | 39 +++++++++++++++++++++++++ - 3 files changed, 83 insertions(+) - create mode 100644 test/Transforms/GVN/non-integral-pointers.ll - create mode 100644 test/Transforms/NewGVN/non-integral-pointers.ll - -diff --git a/lib/Transforms/Utils/VNCoercion.cpp b/lib/Transforms/Utils/VNCoercion.cpp -index 38d26e922c3..80762ccc0d4 100644 ---- a/lib/Transforms/Utils/VNCoercion.cpp -+++ b/lib/Transforms/Utils/VNCoercion.cpp -@@ -24,6 +24,11 @@ bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, - if (DL.getTypeSizeInBits(StoredVal->getType()) < DL.getTypeSizeInBits(LoadTy)) - return false; - -+ // Don't coerce non-integral pointers to integers or vice versa. -+ if (DL.isNonIntegralPointerType(StoredVal->getType()) != -+ DL.isNonIntegralPointerType(LoadTy)) -+ return false; -+ - return true; - } - -diff --git a/test/Transforms/GVN/non-integral-pointers.ll b/test/Transforms/GVN/non-integral-pointers.ll -new file mode 100644 -index 00000000000..9ae4132231d ---- /dev/null -+++ b/test/Transforms/GVN/non-integral-pointers.ll -@@ -0,0 +1,39 @@ -+; RUN: opt -gvn -S < %s | FileCheck %s -+ -+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4" -+target triple = "x86_64-unknown-linux-gnu" -+ -+define void @f0(i1 %alwaysFalse, i64 %val, i64* %loc) { -+; CHECK-LABEL: @f0( -+; CHECK-NOT: inttoptr -+; CHECK-NOT: ptrtoint -+ entry: -+ store i64 %val, i64* %loc -+ br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken -+ -+ neverTaken: -+ %loc.bc = bitcast i64* %loc to i8 addrspace(4)** -+ %ptr = load i8 addrspace(4)*, i8 addrspace(4)** %loc.bc -+ store i8 5, i8 addrspace(4)* %ptr -+ ret void -+ -+ alwaysTaken: -+ ret void -+} -+ -+define i64 @f1(i1 %alwaysFalse, i8 addrspace(4)* %val, i8 addrspace(4)** %loc) { -+; CHECK-LABEL: @f1( -+; CHECK-NOT: inttoptr -+; CHECK-NOT: ptrtoint -+ entry: -+ store i8 addrspace(4)* %val, i8 addrspace(4)** %loc -+ br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken -+ -+ neverTaken: -+ %loc.bc = bitcast i8 addrspace(4)** %loc to i64* -+ %int = load i64, i64* %loc.bc -+ ret i64 %int -+ -+ alwaysTaken: -+ ret i64 42 -+} -diff --git a/test/Transforms/NewGVN/non-integral-pointers.ll b/test/Transforms/NewGVN/non-integral-pointers.ll -new file mode 100644 -index 00000000000..75b8285d51f ---- /dev/null -+++ b/test/Transforms/NewGVN/non-integral-pointers.ll -@@ -0,0 +1,39 @@ -+; RUN: opt -newgvn -S < %s | FileCheck %s -+ -+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4" -+target triple = "x86_64-unknown-linux-gnu" -+ -+define void @f0(i1 %alwaysFalse, i64 %val, i64* %loc) { -+; CHECK-LABEL: @f0( -+; CHECK-NOT: inttoptr -+; CHECK-NOT: ptrtoint -+ entry: -+ store i64 %val, i64* %loc -+ br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken -+ -+ neverTaken: -+ %loc.bc = bitcast i64* %loc to i8 addrspace(4)** -+ %ptr = load i8 addrspace(4)*, i8 addrspace(4)** %loc.bc -+ store i8 5, i8 addrspace(4)* %ptr -+ ret void -+ -+ alwaysTaken: -+ ret void -+} -+ -+define i64 @f1(i1 %alwaysFalse, i8 addrspace(4)* %val, i8 addrspace(4)** %loc) { -+; CHECK-LABEL: @f1( -+; CHECK-NOT: inttoptr -+; CHECK-NOT: ptrtoint -+ entry: -+ store i8 addrspace(4)* %val, i8 addrspace(4)** %loc -+ br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken -+ -+ neverTaken: -+ %loc.bc = bitcast i8 addrspace(4)** %loc to i64* -+ %int = load i64, i64* %loc.bc -+ ret i64 %int -+ -+ alwaysTaken: -+ ret i64 42 -+} --- -2.13.1 - diff --git a/deps/patches/llvm-D32593.patch b/deps/patches/llvm-D32593.patch deleted file mode 100644 index 19c4acb960f97..0000000000000 --- a/deps/patches/llvm-D32593.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 5eeab81d22e07b6e12821067fced590f534c251a Mon Sep 17 00:00:00 2001 -From: Keno Fischer -Date: Thu, 27 Apr 2017 14:33:33 -0400 -Subject: [PATCH] [SROA] Fix crash due to bad bitcast - -Summary: -As shown in the test case, SROA was crashing when trying to split -stores (to the alloca) of loads (from anywhere), because it assumed -the pointer operand to the loads and stores had to have the same -address space. This isn't the case. Make sure to use the correct -pointer type for both the load and the store. - -Reviewers: chandlerc, majnemer, sanjoy - -Subscribers: arsenm, llvm-commits - -Differential Revision: https://reviews.llvm.org/D32593 ---- - lib/Transforms/Scalar/SROA.cpp | 7 ++++--- - test/Transforms/SROA/address-spaces.ll | 18 ++++++++++++++++++ - 2 files changed, 22 insertions(+), 3 deletions(-) - -diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp -index d01e91a..610d5a8 100644 ---- a/lib/Transforms/Scalar/SROA.cpp -+++ b/lib/Transforms/Scalar/SROA.cpp -@@ -3697,7 +3697,8 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) { - int Idx = 0, Size = Offsets.Splits.size(); - for (;;) { - auto *PartTy = Type::getIntNTy(Ty->getContext(), PartSize * 8); -- auto *PartPtrTy = PartTy->getPointerTo(SI->getPointerAddressSpace()); -+ auto *LoadPartPtrTy = PartTy->getPointerTo(LI->getPointerAddressSpace()); -+ auto *StorePartPtrTy = PartTy->getPointerTo(SI->getPointerAddressSpace()); - - // Either lookup a split load or create one. - LoadInst *PLoad; -@@ -3708,7 +3709,7 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) { - PLoad = IRB.CreateAlignedLoad( - getAdjustedPtr(IRB, DL, LoadBasePtr, - APInt(DL.getPointerSizeInBits(), PartOffset), -- PartPtrTy, LoadBasePtr->getName() + "."), -+ LoadPartPtrTy, LoadBasePtr->getName() + "."), - getAdjustedAlignment(LI, PartOffset, DL), /*IsVolatile*/ false, - LI->getName()); - } -@@ -3718,7 +3719,7 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) { - StoreInst *PStore = IRB.CreateAlignedStore( - PLoad, getAdjustedPtr(IRB, DL, StoreBasePtr, - APInt(DL.getPointerSizeInBits(), PartOffset), -- PartPtrTy, StoreBasePtr->getName() + "."), -+ StorePartPtrTy, StoreBasePtr->getName() + "."), - getAdjustedAlignment(SI, PartOffset, DL), /*IsVolatile*/ false); - - // Now build a new slice for the alloca. -diff --git a/test/Transforms/SROA/address-spaces.ll b/test/Transforms/SROA/address-spaces.ll -index 119f225..8fba30c 100644 ---- a/test/Transforms/SROA/address-spaces.ll -+++ b/test/Transforms/SROA/address-spaces.ll -@@ -83,3 +83,21 @@ define void @pr27557() { - store i32 addrspace(3)* @l, i32 addrspace(3)** %3, align 8 - ret void - } -+ -+; Make sure pre-splitting doesn't try to introduce an illegal bitcast -+define float @presplit(i64 addrspace(1)* %p) { -+entry: -+; CHECK-LABEL: @presplit( -+; CHECK: %[[CAST:.*]] = bitcast i64 addrspace(1)* {{.*}} to i32 addrspace(1)* -+; CHECK: load i32, i32 addrspace(1)* %[[CAST]] -+ %b = alloca i64 -+ %b.cast = bitcast i64* %b to [2 x float]* -+ %b.gep1 = getelementptr [2 x float], [2 x float]* %b.cast, i32 0, i32 0 -+ %b.gep2 = getelementptr [2 x float], [2 x float]* %b.cast, i32 0, i32 1 -+ %l = load i64, i64 addrspace(1)* %p -+ store i64 %l, i64* %b -+ %f1 = load float, float* %b.gep1 -+ %f2 = load float, float* %b.gep2 -+ %ret = fadd float %f1, %f2 -+ ret float %ret -+} --- -2.9.3 - diff --git a/deps/patches/llvm-D32623-GVN-non-integral.patch b/deps/patches/llvm-D32623-GVN-non-integral.patch deleted file mode 100644 index 5ddc76bc046d5..0000000000000 --- a/deps/patches/llvm-D32623-GVN-non-integral.patch +++ /dev/null @@ -1,94 +0,0 @@ -From ad3b6cad4fcd66aab2ef2e93566d5868505c03bb Mon Sep 17 00:00:00 2001 -From: Keno Fischer -Date: Tue, 9 May 2017 21:07:20 +0000 -Subject: [PATCH 4/5] [GVN] Fix a crash on encountering non-integral pointers - -Summary: -This fixes the immediate crash caused by introducing an incorrect inttoptr -before attempting the conversion. There may still be a legality -check missing somewhere earlier for non-integral pointers, but this change -seems necessary in any case. - -Reviewers: sanjoy, dberlin - -Reviewed By: dberlin - -Subscribers: llvm-commits - -Differential Revision: https://reviews.llvm.org/D32623 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302587 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Transforms/Utils/VNCoercion.cpp | 9 ++++++++ - test/Transforms/GVN/PRE/nonintegral.ll | 39 ++++++++++++++++++++++++++++++++++ - 2 files changed, 48 insertions(+) - create mode 100644 test/Transforms/GVN/PRE/nonintegral.ll - -diff --git a/lib/Transforms/Utils/VNCoercion.cpp b/lib/Transforms/Utils/VNCoercion.cpp -index 80762ccc0d4..9d2eab19ded 100644 ---- a/lib/Transforms/Utils/VNCoercion.cpp -+++ b/lib/Transforms/Utils/VNCoercion.cpp -@@ -301,6 +301,15 @@ Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, - Instruction *InsertPt, const DataLayout &DL) { - LLVMContext &Ctx = SrcVal->getType()->getContext(); - -+ // If two pointers are in the same address space, they have the same size, -+ // so we don't need to do any truncation, etc. This avoids introducing -+ // ptrtoint instructions for pointers that may be non-integral. -+ if (SrcVal->getType()->isPointerTy() && LoadTy->isPointerTy() && -+ cast(SrcVal->getType())->getAddressSpace() == -+ cast(LoadTy)->getAddressSpace()) { -+ return SrcVal; -+ } -+ - uint64_t StoreSize = (DL.getTypeSizeInBits(SrcVal->getType()) + 7) / 8; - uint64_t LoadSize = (DL.getTypeSizeInBits(LoadTy) + 7) / 8; - -diff --git a/test/Transforms/GVN/PRE/nonintegral.ll b/test/Transforms/GVN/PRE/nonintegral.ll -new file mode 100644 -index 00000000000..75a756e8af8 ---- /dev/null -+++ b/test/Transforms/GVN/PRE/nonintegral.ll -@@ -0,0 +1,39 @@ -+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -+; RUN: opt -gvn -S < %s | FileCheck %s -+ -+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4" -+target triple = "x86_64-unknown-linux-gnu" -+ -+define void @nipre(double addrspace(4)** noalias %p, i64 addrspace(4)** noalias %p2, i8 %jmp) { -+ -+; CHECK-LABEL: @nipre( -+; CHECK: [[PCAST:%.*]] = bitcast double addrspace(4)** [[P:%.*]] to i64 addrspace(4)** -+; CHECK: a: -+; CHECK: [[L1:%.*]] = load i64 addrspace(4)*, i64 addrspace(4)** [[PCAST]] -+; CHECK: [[TMP0:%.*]] = bitcast i64 addrspace(4)* [[L1]] to double addrspace(4)* -+; CHECK: b: -+; CHECK: [[L2:%.*]] = load i64 addrspace(4)*, i64 addrspace(4)** [[PCAST]] -+; CHECK: [[TMP1:%.*]] = bitcast i64 addrspace(4)* [[L2]] to double addrspace(4)* -+; CHECK: c: -+; CHECK-NEXT: [[L3_PRE:%.*]] = load double addrspace(4)*, double addrspace(4)** %p -+ -+entry: -+ %pcast = bitcast double addrspace(4)** %p to i64 addrspace(4)** -+ switch i8 %jmp, label %c [ i8 0, label %a -+ i8 1, label %b] -+a: -+ %l1 = load i64 addrspace(4)*, i64 addrspace(4)** %pcast -+ store i64 addrspace(4)* %l1, i64 addrspace(4)** %p2 -+ br label %tail -+b: -+ %l2 = load i64 addrspace(4)*, i64 addrspace(4)** %pcast -+ store i64 addrspace(4)* %l2, i64 addrspace(4)** %p2 -+ br label %tail -+c: -+ br label %tail -+tail: -+ %l3 = load double addrspace(4)*, double addrspace(4)** %p -+ %l3cast = bitcast double addrspace(4)* %l3 to i64 addrspace(4)* -+ store i64 addrspace(4)* %l3cast, i64 addrspace(4)** %p2 -+ ret void -+} --- -2.13.1 - diff --git a/deps/patches/llvm-D33110-codegen-prepare-inttoptr.patch b/deps/patches/llvm-D33110-codegen-prepare-inttoptr.patch deleted file mode 100644 index 5f1f874c3db83..0000000000000 --- a/deps/patches/llvm-D33110-codegen-prepare-inttoptr.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 8a2f775df3c8548bedd8437c0b96b54e9e71549d Mon Sep 17 00:00:00 2001 -From: Keno Fischer -Date: Sat, 17 Jun 2017 11:07:26 -0400 -Subject: [PATCH 2/2] [CodeGenPrepare] Don't create inttoptr for ni ptrs - -Summary: -Arguably non-integral pointers probably shouldn't show up here at all, -but since the backend doesn't complain and this takes valid (according -to the Verifier) IR and makes it invalid, make sure not to introduce -any inttoptr instructions if we're dealing with non-integral pointers. - -Reviewers: sanjoy - -Subscribers: llvm-commits - -Differential Revision: https://reviews.llvm.org/D33110 ---- - lib/CodeGen/CodeGenPrepare.cpp | 23 ++++++++----- - test/Transforms/CodeGenPrepare/nonintegral.ll | 47 +++++++++++++++++++++++++++ - 2 files changed, 62 insertions(+), 8 deletions(-) - create mode 100644 test/Transforms/CodeGenPrepare/nonintegral.ll - -diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp -index 934b470f13b..44d6b3e264c 100644 ---- a/lib/CodeGen/CodeGenPrepare.cpp -+++ b/lib/CodeGen/CodeGenPrepare.cpp -@@ -3973,14 +3973,16 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, - // If the real base value actually came from an inttoptr, then the matcher - // will look through it and provide only the integer value. In that case, - // use it here. -- if (!ResultPtr && AddrMode.BaseReg) { -- ResultPtr = -- Builder.CreateIntToPtr(AddrMode.BaseReg, Addr->getType(), "sunkaddr"); -- AddrMode.BaseReg = nullptr; -- } else if (!ResultPtr && AddrMode.Scale == 1) { -- ResultPtr = -- Builder.CreateIntToPtr(AddrMode.ScaledReg, Addr->getType(), "sunkaddr"); -- AddrMode.Scale = 0; -+ if (!DL->isNonIntegralPointerType(Addr->getType())) { -+ if (!ResultPtr && AddrMode.BaseReg) { -+ ResultPtr = Builder.CreateIntToPtr(AddrMode.BaseReg, Addr->getType(), -+ "sunkaddr"); -+ AddrMode.BaseReg = nullptr; -+ } else if (!ResultPtr && AddrMode.Scale == 1) { -+ ResultPtr = Builder.CreateIntToPtr(AddrMode.ScaledReg, Addr->getType(), -+ "sunkaddr"); -+ AddrMode.Scale = 0; -+ } - } - - if (!ResultPtr && -@@ -4061,6 +4063,11 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, - SunkAddr = Builder.CreateBitCast(SunkAddr, Addr->getType()); - } - } else { -+ // We'd require an inttoptr down the line, which we can't do for -+ // non-integral pointers, so in that case bail out now. -+ if (DL->isNonIntegralPointerType(Addr->getType())) -+ return false; -+ - DEBUG(dbgs() << "CGP: SINKING nonlocal addrmode: " << AddrMode << " for " - << *MemoryInst << "\n"); - Type *IntPtrTy = DL->getIntPtrType(Addr->getType()); -diff --git a/test/Transforms/CodeGenPrepare/nonintegral.ll b/test/Transforms/CodeGenPrepare/nonintegral.ll -new file mode 100644 -index 00000000000..e49977bc940 ---- /dev/null -+++ b/test/Transforms/CodeGenPrepare/nonintegral.ll -@@ -0,0 +1,47 @@ -+; RUN: opt -S -codegenprepare < %s | FileCheck %s -+; RUN: opt -S -codegenprepare -addr-sink-using-gep=false < %s | FileCheck %s -+ -+; This target data layout is modified to have a non-integral addrspace(1), -+; in order to verify that codegenprepare does not try to introduce illegal -+; inttoptrs. -+target datalayout = -+"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-ni:1" -+target triple = "x86_64-unknown-linux-gnu" -+ -+define void @test_simple(i1 %cond, i64 addrspace(1)* %base) { -+; CHECK-LABEL: @test_simple -+; CHECK-NOT: inttoptr {{.*}} to i64 addrspace(1)* -+entry: -+ %addr = getelementptr inbounds i64, i64 addrspace(1)* %base, i64 5 -+ %casted = bitcast i64 addrspace(1)* %addr to i32 addrspace(1)* -+ br i1 %cond, label %if.then, label %fallthrough -+ -+if.then: -+ %v = load i32, i32 addrspace(1)* %casted, align 4 -+ br label %fallthrough -+ -+fallthrough: -+ ret void -+} -+ -+ -+define void @test_inttoptr_base(i1 %cond, i64 %base) { -+; CHECK-LABEL: @test_inttoptr_base -+; CHECK-NOT: inttoptr {{.*}} to i64 addrspace(1)* -+entry: -+; Doing the inttoptr in the integral addrspace(0) followed by an explicit -+; (frontend-introduced) addrspacecast is fine. We cannot however introduce -+; a direct inttoptr to addrspace(1) -+ %baseptr = inttoptr i64 %base to i64* -+ %baseptrni = addrspacecast i64 *%baseptr to i64 addrspace(1)* -+ %addr = getelementptr inbounds i64, i64 addrspace(1)* %baseptrni, i64 5 -+ %casted = bitcast i64 addrspace(1)* %addr to i32 addrspace(1)* -+ br i1 %cond, label %if.then, label %fallthrough -+ -+if.then: -+ %v = load i32, i32 addrspace(1)* %casted, align 4 -+ br label %fallthrough -+ -+fallthrough: -+ ret void -+} --- -2.13.1 - diff --git a/deps/patches/llvm-D33129-scevexpander-non-integral.patch b/deps/patches/llvm-D33129-scevexpander-non-integral.patch deleted file mode 100644 index 1dab29f94c041..0000000000000 --- a/deps/patches/llvm-D33129-scevexpander-non-integral.patch +++ /dev/null @@ -1,153 +0,0 @@ -From d551af32da5fd6654e7804848a7a409e9444aeea Mon Sep 17 00:00:00 2001 -From: Keno Fischer -Date: Sat, 27 May 2017 03:22:55 +0000 -Subject: [PATCH 5/5] [SCEVExpander] Try harder to avoid introducing inttoptr - -Summary: -This fixes introduction of an incorrect inttoptr/ptrtoint pair in -the included test case which makes use of non-integral pointers. I -suspect there are more cases like this left, but this takes care of -the one I was seeing at the moment. - -Reviewers: sanjoy - -Subscribers: mzolotukhin, llvm-commits - -Differential Revision: https://reviews.llvm.org/D33129 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304058 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Analysis/ScalarEvolutionExpander.cpp | 20 ++++++++-- - test/Transforms/LoopStrengthReduce/nonintegral.ll | 45 +++++++++++++++++++++++ - unittests/Analysis/ScalarEvolutionTest.cpp | 11 +++--- - 3 files changed, 67 insertions(+), 9 deletions(-) - create mode 100644 test/Transforms/LoopStrengthReduce/nonintegral.ll - -diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp -index d15a7dbd20e..e7d9e9a633e 100644 ---- a/lib/Analysis/ScalarEvolutionExpander.cpp -+++ b/lib/Analysis/ScalarEvolutionExpander.cpp -@@ -1306,12 +1306,17 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) { - // Expand the core addrec. If we need post-loop scaling, force it to - // expand to an integer type to avoid the need for additional casting. - Type *ExpandTy = PostLoopScale ? IntTy : STy; -+ // We can't use a pointer type for the addrec if the pointer type is -+ // non-integral. -+ Type *AddRecPHIExpandTy = -+ DL.isNonIntegralPointerType(STy) ? Normalized->getType() : ExpandTy; -+ - // In some cases, we decide to reuse an existing phi node but need to truncate - // it and/or invert the step. - Type *TruncTy = nullptr; - bool InvertStep = false; -- PHINode *PN = getAddRecExprPHILiterally(Normalized, L, ExpandTy, IntTy, -- TruncTy, InvertStep); -+ PHINode *PN = getAddRecExprPHILiterally(Normalized, L, AddRecPHIExpandTy, -+ IntTy, TruncTy, InvertStep); - - // Accommodate post-inc mode, if necessary. - Value *Result; -@@ -1384,8 +1389,15 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) { - // Re-apply any non-loop-dominating offset. - if (PostLoopOffset) { - if (PointerType *PTy = dyn_cast(ExpandTy)) { -- const SCEV *const OffsetArray[1] = { PostLoopOffset }; -- Result = expandAddToGEP(OffsetArray, OffsetArray+1, PTy, IntTy, Result); -+ if (Result->getType()->isIntegerTy()) { -+ Value *Base = expandCodeFor(PostLoopOffset, ExpandTy); -+ const SCEV *const OffsetArray[1] = {SE.getUnknown(Result)}; -+ Result = expandAddToGEP(OffsetArray, OffsetArray + 1, PTy, IntTy, Base); -+ } else { -+ const SCEV *const OffsetArray[1] = {PostLoopOffset}; -+ Result = -+ expandAddToGEP(OffsetArray, OffsetArray + 1, PTy, IntTy, Result); -+ } - } else { - Result = InsertNoopCastOfTo(Result, IntTy); - Result = Builder.CreateAdd(Result, -diff --git a/test/Transforms/LoopStrengthReduce/nonintegral.ll b/test/Transforms/LoopStrengthReduce/nonintegral.ll -new file mode 100644 -index 00000000000..5648e3aa74a ---- /dev/null -+++ b/test/Transforms/LoopStrengthReduce/nonintegral.ll -@@ -0,0 +1,45 @@ -+; RUN: opt -S -loop-reduce < %s | FileCheck %s -+ -+; Address Space 10 is non-integral. The optimizer is not allowed to use -+; ptrtoint/inttoptr instructions. Make sure that this doesn't happen -+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:10:11:12" -+target triple = "x86_64-unknown-linux-gnu" -+ -+define void @japi1__unsafe_getindex_65028(i64 addrspace(10)* %arg) { -+; CHECK-NOT: inttoptr -+; CHECK-NOT: ptrtoint -+; How exactly SCEV chooses to materialize isn't all that important, as -+; long as it doesn't try to round-trip through integers. As of this writing, -+; it emits a byte-wise gep, which is fine. -+; CHECK: getelementptr i64, i64 addrspace(10)* {{.*}}, i64 {{.*}} -+top: -+ br label %L86 -+ -+L86: ; preds = %L86, %top -+ %i.0 = phi i64 [ 0, %top ], [ %tmp, %L86 ] -+ %tmp = add i64 %i.0, 1 -+ br i1 undef, label %L86, label %if29 -+ -+if29: ; preds = %L86 -+ %tmp1 = shl i64 %tmp, 1 -+ %tmp2 = add i64 %tmp1, -2 -+ br label %if31 -+ -+if31: ; preds = %if38, %if29 -+ %"#temp#1.sroa.0.022" = phi i64 [ 0, %if29 ], [ %tmp3, %if38 ] -+ br label %L119 -+ -+L119: ; preds = %L119, %if31 -+ %i5.0 = phi i64 [ %"#temp#1.sroa.0.022", %if31 ], [ %tmp3, %L119 ] -+ %tmp3 = add i64 %i5.0, 1 -+ br i1 undef, label %L119, label %if38 -+ -+if38: ; preds = %L119 -+ %tmp4 = add i64 %tmp2, %i5.0 -+ %tmp5 = getelementptr i64, i64 addrspace(10)* %arg, i64 %tmp4 -+ %tmp6 = load i64, i64 addrspace(10)* %tmp5 -+ br i1 undef, label %done, label %if31 -+ -+done: ; preds = %if38 -+ ret void -+} -diff --git a/unittests/Analysis/ScalarEvolutionTest.cpp b/unittests/Analysis/ScalarEvolutionTest.cpp -index f4370842edb..1af241fdfbe 100644 ---- a/unittests/Analysis/ScalarEvolutionTest.cpp -+++ b/unittests/Analysis/ScalarEvolutionTest.cpp -@@ -7,21 +7,22 @@ - // - //===----------------------------------------------------------------------===// - --#include "llvm/Analysis/ScalarEvolutionExpander.h" --#include "llvm/Analysis/ScalarEvolutionExpressions.h" -+#include "llvm/ADT/SmallVector.h" - #include "llvm/Analysis/AssumptionCache.h" - #include "llvm/Analysis/LoopInfo.h" --#include "llvm/Analysis/TargetLibraryInfo.h" --#include "llvm/ADT/SmallVector.h" - #include "llvm/Analysis/LoopInfo.h" -+#include "llvm/Analysis/ScalarEvolutionExpander.h" -+#include "llvm/Analysis/ScalarEvolutionExpressions.h" -+#include "llvm/Analysis/TargetLibraryInfo.h" - #include "llvm/AsmParser/Parser.h" - #include "llvm/IR/Constants.h" - #include "llvm/IR/Dominators.h" - #include "llvm/IR/GlobalVariable.h" -+#include "llvm/IR/IRBuilder.h" - #include "llvm/IR/InstIterator.h" - #include "llvm/IR/LLVMContext.h" --#include "llvm/IR/Module.h" - #include "llvm/IR/LegacyPassManager.h" -+#include "llvm/IR/Module.h" - #include "llvm/IR/Verifier.h" - #include "llvm/Support/SourceMgr.h" - #include "gtest/gtest.h" --- -2.13.1 - diff --git a/deps/patches/llvm-D33179.patch b/deps/patches/llvm-D33179.patch deleted file mode 100644 index 2be915018de24..0000000000000 --- a/deps/patches/llvm-D33179.patch +++ /dev/null @@ -1,64 +0,0 @@ -From b1a005ba688397ca360e89cd6c6f51f232d6c25e Mon Sep 17 00:00:00 2001 -From: Keno Fischer -Date: Fri, 19 May 2017 18:42:20 -0400 -Subject: [PATCH] [Sink] Fix predicate in legality check - -Summary: -isSafeToSpeculativelyExecute is the wrong predicate to use here. -All that checks for is whether it is safe to hoist a value due to -unaligned/un-dereferencable accesses. However, not only are we doing -sinking rather than hoisting, our concern is that the location -we're loading from may have been modified. Instead forbid sinking -any load across a critical edge. - -Reviewers: majnemer - -Subscribers: llvm-commits - -Differential Revision: https://reviews.llvm.org/D33179 ---- - lib/Transforms/Scalar/Sink.cpp | 2 +- - test/Transforms/Sink/badloadsink.ll | 18 ++++++++++++++++++ - 2 files changed, 19 insertions(+), 1 deletion(-) - create mode 100644 test/Transforms/Sink/badloadsink.ll - -diff --git a/lib/Transforms/Scalar/Sink.cpp b/lib/Transforms/Scalar/Sink.cpp -index 102e9ea..5210f16 100644 ---- a/lib/Transforms/Scalar/Sink.cpp -+++ b/lib/Transforms/Scalar/Sink.cpp -@@ -114,7 +114,7 @@ static bool IsAcceptableTarget(Instruction *Inst, BasicBlock *SuccToSinkTo, - if (SuccToSinkTo->getUniquePredecessor() != Inst->getParent()) { - // We cannot sink a load across a critical edge - there may be stores in - // other code paths. -- if (!isSafeToSpeculativelyExecute(Inst)) -+ if (isa(Inst)) - return false; - - // We don't want to sink across a critical edge if we don't dominate the -diff --git a/test/Transforms/Sink/badloadsink.ll b/test/Transforms/Sink/badloadsink.ll -new file mode 100644 -index 0000000..e3f4884 ---- /dev/null -+++ b/test/Transforms/Sink/badloadsink.ll -@@ -0,0 +1,18 @@ -+; RUN: opt < %s -basicaa -sink -S | FileCheck %s -+declare void @foo(i64 *) -+define i64 @sinkload(i1 %cmp) { -+; CHECK-LABEL: @sinkload -+top: -+ %a = alloca i64 -+; CHECK: call void @foo(i64* %a) -+; CHECK-NEXT: %x = load i64, i64* %a -+ call void @foo(i64* %a) -+ %x = load i64, i64* %a -+ br i1 %cmp, label %A, label %B -+A: -+ store i64 0, i64 *%a -+ br label %B -+B: -+; CHECK-NOT: load i64, i64 *%a -+ ret i64 %x -+} --- -2.9.3 - diff --git a/deps/patches/llvm-D37939-Mem2Reg-Also-handle-memcpy.patch b/deps/patches/llvm-D37939-Mem2Reg-Also-handle-memcpy.patch deleted file mode 100644 index b8753b0439ba0..0000000000000 --- a/deps/patches/llvm-D37939-Mem2Reg-Also-handle-memcpy.patch +++ /dev/null @@ -1,365 +0,0 @@ -From da4504b2d3c6629fbd58634bf76f1b85939d07cf Mon Sep 17 00:00:00 2001 -From: Keno Fischer -Date: Fri, 15 Sep 2017 18:30:59 -0400 -Subject: [PATCH] [Mem2Reg] Also handle memcpy - -Summary: -In julia, when we know we're moving data between two memory locations, -we always emit that as a memcpy rather than a load/store pair. However, -this can give worse optimization results in certain cases because some -optimizations that can handle load/store pairs cannot handle memcpys. -Mem2reg is one of these optimizations. This patch adds rudamentary -support for mem2reg for recognizing memcpys that cover the whole alloca -we're promoting. While several more sophisticated passes (SROA, GVN) -can get similar optimizations, it is preferable to have these kinds -of cases caught early to expose optimization opportunities before -getting to these later passes. The approach taken here is to split -the memcpy into a load/store pair early (after legality analysis) -and retain the rest of the analysis only on loads/stores. It would -be possible of course to leave the memcpy as is and generate the -left over load or store only on demand. However, that would entail -a significantly larger patch for unclear benefit. - -Reviewers: chandlerc, dberlin - -Subscribers: llvm-commits - -Differential Revision: https://reviews.llvm.org/D37939 ---- - lib/Transforms/Utils/PromoteMemoryToRegister.cpp | 166 ++++++++++++++++++++--- - test/Transforms/Mem2Reg/memcpy.ll | 101 ++++++++++++++ - 2 files changed, 251 insertions(+), 16 deletions(-) - create mode 100644 test/Transforms/Mem2Reg/memcpy.ll - -diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp -index ac28f59..b08a0a1 100644 ---- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp -+++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp -@@ -49,6 +49,58 @@ STATISTIC(NumSingleStore, "Number of alloca's promoted with a single store"); - STATISTIC(NumDeadAlloca, "Number of dead alloca's removed"); - STATISTIC(NumPHIInsert, "Number of PHI nodes inserted"); - -+static bool isSplittableMemCpy(const MemCpyInst *MCI, const AllocaInst *AI) { -+ // Punt if this alloca is an array allocation -+ if (AI->isArrayAllocation()) -+ return false; -+ if (MCI->isVolatile()) -+ return false; -+ Value *Length = MCI->getLength(); -+ if (!isa(Length)) -+ return false; -+ // Anything less than the full alloca, we leave for SROA -+ const DataLayout &DL = AI->getModule()->getDataLayout(); -+ size_t AIElSize = DL.getTypeAllocSize(AI->getAllocatedType()); -+ if (cast(Length)->getZExtValue() != AIElSize) -+ return false; -+ // If the other argument is also an alloca, we need to be sure that either -+ // the types are bitcastable, or the other alloca is not eligible for -+ // promotion (e.g. because the memcpy is for less than the whole size of -+ // that alloca), otherwise we risk turning an allocatable alloca into a -+ // non-allocatable one when splitting the memcpy. -+ AllocaInst *OtherAI = dyn_cast( -+ AI == MCI->getSource() ? MCI->getDest() : MCI->getSource()); -+ if (OtherAI) { -+ if (!CastInst::isBitCastable(AI->getAllocatedType(), -+ OtherAI->getAllocatedType()) && -+ DL.getTypeAllocSize(OtherAI->getAllocatedType()) == AIElSize) -+ return false; -+ } -+ return true; -+} -+ -+/// Look at the result of a bitcast and see if it's only used by lifetime -+/// intrinsics or splittable memcpys. This is needed, because IRBuilder -+/// will always insert a bitcast to i8* for these intrinsics. -+static bool onlyHasCanonicalizableUsers(const AllocaInst *AI, const Value *V) { -+ for (const User *U : V->users()) { -+ const IntrinsicInst *II = dyn_cast(U); -+ if (!II) -+ return false; -+ -+ if (isa(II)) { -+ if (!isSplittableMemCpy(cast(II), AI)) -+ return false; -+ continue; -+ } -+ -+ if (II->getIntrinsicID() != Intrinsic::lifetime_start && -+ II->getIntrinsicID() != Intrinsic::lifetime_end) -+ return false; -+ } -+ return true; -+} -+ - bool llvm::isAllocaPromotable(const AllocaInst *AI) { - // FIXME: If the memory unit is of pointer or integer type, we can permit - // assignments to subsections of the memory unit. -@@ -68,6 +120,9 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) { - // not have any meaning for a local alloca. - if (SI->isVolatile()) - return false; -+ } else if (const MemCpyInst *MCI = dyn_cast(U)) { -+ if (!isSplittableMemCpy(MCI, AI)) -+ return false; - } else if (const IntrinsicInst *II = dyn_cast(U)) { - if (II->getIntrinsicID() != Intrinsic::lifetime_start && - II->getIntrinsicID() != Intrinsic::lifetime_end) -@@ -75,7 +130,7 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) { - } else if (const BitCastInst *BCI = dyn_cast(U)) { - if (BCI->getType() != Type::getInt8PtrTy(U->getContext(), AS)) - return false; -- if (!onlyUsedByLifetimeMarkers(BCI)) -+ if (!onlyHasCanonicalizableUsers(AI, BCI)) - return false; - } else if (const GetElementPtrInst *GEPI = dyn_cast(U)) { - if (GEPI->getType() != Type::getInt8PtrTy(U->getContext(), AS)) -@@ -181,7 +235,13 @@ public: - /// This code only looks at accesses to allocas. - static bool isInterestingInstruction(const Instruction *I) { -+ if (isa(I)) { -+ const MemCpyInst *MCI = cast(I); -+ return isa(MCI->getSource()) || -+ isa(MCI->getDest()); -+ } else { - return (isa(I) && isa(I->getOperand(0))) || - (isa(I) && isa(I->getOperand(1))); - } -+ } - - /// Get or calculate the index of the specified instruction. -@@ -208,6 +264,25 @@ public: - return It->second; - } - -+ // When we split a memcpy intrinsic, we need to update the numbering in this -+ // struct. To make sure the relative ordering remains the same, we give both -+ // the LI and the SI the number that the MCI used to have (if they are both -+ // interesting). This means that they will have equal numbers, which usually -+ // can't happen. However, since they can never reference the same alloca -+ // (since memcpy operands may not overlap), this is fine, because we will -+ // never compare instruction indices for instructions that operate on distinct -+ // allocas. -+ void splitMemCpy(MemCpyInst *MCI, LoadInst *LI, StoreInst *SI) { -+ DenseMap::iterator It = -+ InstNumbers.find(MCI); -+ if (It == InstNumbers.end()) -+ return; -+ unsigned MemCpyNumber = It->second; -+ InstNumbers[LI] = MemCpyNumber; -+ InstNumbers[SI] = MemCpyNumber; -+ deleteValue(MCI); -+ } -+ - void deleteValue(const Instruction *I) { InstNumbers.erase(I); } - - void clear() { InstNumbers.clear(); } -@@ -305,9 +380,58 @@ static void addAssumeNonNull(AssumptionCache *AC, LoadInst *LI) { - AC->registerAssumption(CI); - } - --static void removeLifetimeIntrinsicUsers(AllocaInst *AI) { -- // Knowing that this alloca is promotable, we know that it's safe to kill all -- // instructions except for load and store. -+/// Split a memcpy instruction into the corresponding load/store. It is a little -+/// more complicated than one might imagine, because we need to deal with the -+/// fact that the side of the copy we're not currently processing might also -+/// be a promotable alloca. We need to be careful to not break the promotable -+/// predicate for that other alloca (if any). -+static void doMemCpySplit(LargeBlockInfo &LBI, MemCpyInst *MCI, -+ AllocaInst *AI) { -+ AAMDNodes AA; -+ MCI->getAAMetadata(AA); -+ Value *MCISrc = MCI->getSource(); -+ Type *LoadType = AI->getAllocatedType(); -+ AllocaInst *SrcAI = dyn_cast(MCISrc); -+ if (SrcAI && SrcAI->getType() != AI->getType()) { -+ if (CastInst::isBitCastable(SrcAI->getAllocatedType(), LoadType)) -+ LoadType = SrcAI->getAllocatedType(); -+ } -+ if (cast(MCISrc->getType())->getElementType() != LoadType) -+ MCISrc = CastInst::Create( -+ Instruction::BitCast, MCISrc, -+ LoadType->getPointerTo( -+ cast(MCISrc->getType())->getAddressSpace()), -+ "", MCI); -+ // This might add to the end of the use list, but that's fine. At worst, -+ // we'd not visit the instructions we insert here, but we don't care -+ // about them in this loop anyway. -+ LoadInst *LI = new LoadInst(LoadType, MCISrc, "", MCI->isVolatile(), -+ MCI->getAlignment(), MCI); -+ Value *Val = LI; -+ Value *MCIDest = MCI->getDest(); -+ AllocaInst *DestAI = dyn_cast(MCIDest); -+ Type *DestElTy = DestAI ? DestAI->getAllocatedType() : AI->getAllocatedType(); -+ if (LI->getType() != DestElTy && -+ CastInst::isBitCastable(LI->getType(), DestElTy)) -+ Val = CastInst::Create(Instruction::BitCast, Val, DestElTy, "", MCI); -+ if (cast(MCIDest->getType())->getElementType() != Val->getType()) -+ MCIDest = CastInst::Create( -+ Instruction::BitCast, MCIDest, -+ Val->getType()->getPointerTo( -+ cast(MCIDest->getType())->getAddressSpace()), -+ "", MCI); -+ StoreInst *SI = -+ new StoreInst(Val, MCIDest, MCI->isVolatile(), MCI->getAlignment(), MCI); -+ LI->setAAMetadata(AA); -+ SI->setAAMetadata(AA); -+ LBI.splitMemCpy(MCI, LI, SI); -+ MCI->eraseFromParent(); -+} -+ -+static void canonicalizeUsers(LargeBlockInfo &LBI, AllocaInst *AI) { -+ // Knowing that this alloca is promotable, we know that it's safe to split -+ // MTIs into load/store and to kill all other instructions except for -+ // load and store. - - for (auto UI = AI->user_begin(), UE = AI->user_end(); UI != UE;) { - Instruction *I = cast(*UI); -@@ -315,14 +439,24 @@ static void removeLifetimeIntrinsicUsers(AllocaInst *AI) { - if (isa(I) || isa(I)) - continue; - -+ if (isa(I)) { -+ MemCpyInst *MCI = cast(I); -+ doMemCpySplit(LBI, MCI, AI); -+ continue; -+ } -+ - if (!I->getType()->isVoidTy()) { -- // The only users of this bitcast/GEP instruction are lifetime intrinsics. -- // Follow the use/def chain to erase them now instead of leaving it for -- // dead code elimination later. -+ // The only users of this bitcast/GEP instruction are lifetime/memcpy -+ // intrinsics. Split memcpys and delete lifetime intrinsics. - for (auto UUI = I->user_begin(), UUE = I->user_end(); UUI != UUE;) { - Instruction *Inst = cast(*UUI); - ++UUI; -- Inst->eraseFromParent(); -+ if (isa(Inst)) { -+ doMemCpySplit(LBI, cast(Inst), AI); -+ } else { -+ // Must be a lifetime intrinsic -+ Inst->eraseFromParent(); -+ } - } - } - I->eraseFromParent(); -@@ -542,7 +676,7 @@ void PromoteMem2Reg::run() { - assert(AI->getParent()->getParent() == &F && - "All allocas should be in the same function, which is same as DF!"); - -- removeLifetimeIntrinsicUsers(AI); -+ canonicalizeUsers(LBI, AI); - - if (AI->use_empty()) { - // If there are no uses of the alloca, just delete it now. -diff --git a/test/Transforms/Mem2Reg/memcpy.ll b/test/Transforms/Mem2Reg/memcpy.ll -new file mode 100644 -index 0000000..fbc4096 ---- /dev/null -+++ b/test/Transforms/Mem2Reg/memcpy.ll -@@ -0,0 +1,101 @@ -+; RUN: opt < %s -mem2reg -S | FileCheck %s -+ -+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" -+ -+declare void @llvm.memcpy.p0i128.p0i64.i32(i128 *, i64 *, i32, i32, i1) -+declare void @llvm.memcpy.p0i8.p0i8.i32(i8 *, i8 *, i32, i32, i1) -+declare void @llvm.memcpy.p0i64.p0i64.i32(i64 *, i64 *, i32, i32, i1) -+declare void @llvm.memcpy.p0f64.p0i64.i32(double *, i64 *, i32, i32, i1) -+ -+define i128 @test_cpy_different(i64) { -+; CHECK-LABEL: @test_cpy_different -+; CHECK-NOT: alloca i64 -+; CHECK: store i64 %0 -+ %a = alloca i64 -+ %b = alloca i128 -+ store i128 0, i128 *%b -+ store i64 %0, i64 *%a -+ call void @llvm.memcpy.p0i128.p0i64.i32(i128 *%b, i64 *%a, i32 8, i32 0, i1 0) -+ %loaded = load i128, i128 *%b -+ ret i128 %loaded -+} -+ -+define i64 @test_cpy_same(i64) { -+; CHECK-LABEL: @test_cpy_same -+; CHECK-NOT: alloca -+; CHECK: ret i64 %0 -+ %a = alloca i64 -+ %b = alloca i64 -+ store i64 %0, i64 *%a -+ call void @llvm.memcpy.p0i64.p0i64.i32(i64 *%b, i64 *%a, i32 8, i32 0, i1 0) -+ %loaded = load i64, i64 *%b -+ ret i64 %loaded -+} -+ -+define double @test_cpy_different_type(i64) { -+; CHECK-LABEL: @test_cpy_different_type -+; CHECK-NOT: alloca -+; CHECK: bitcast i64 %0 to double -+ %a = alloca i64 -+ %b = alloca double -+ store i64 %0, i64 *%a -+ call void @llvm.memcpy.p0f64.p0i64.i32(double *%b, i64 *%a, i32 8, i32 0, i1 0) -+ %loaded = load double, double *%b -+ ret double %loaded -+} -+ -+define i128 @test_cpy_differenti8(i64) { -+; CHECK-LABEL: @test_cpy_differenti8 -+; CHECK-NOT: alloca i64 -+; CHECK: store i64 %0 -+ %a = alloca i64 -+ %b = alloca i128 -+ store i128 0, i128 *%b -+ store i64 %0, i64 *%a -+ %acast = bitcast i64* %a to i8* -+ %bcast = bitcast i128* %b to i8* -+ call void @llvm.memcpy.p0i8.p0i8.i32(i8 *%bcast, i8 *%acast, i32 8, i32 0, i1 0) -+ %loaded = load i128, i128 *%b -+ ret i128 %loaded -+} -+ -+define i64 @test_cpy_samei8(i64) { -+; CHECK-LABEL: @test_cpy_samei8 -+; CHECK-NOT: alloca -+; CHECK: ret i64 %0 -+ %a = alloca i64 -+ %b = alloca i64 -+ store i64 %0, i64 *%a -+ %acast = bitcast i64* %a to i8* -+ %bcast = bitcast i64* %b to i8* -+ call void @llvm.memcpy.p0i8.p0i8.i32(i8 *%bcast, i8 *%acast, i32 8, i32 0, i1 0) -+ %loaded = load i64, i64 *%b -+ ret i64 %loaded -+} -+ -+define double @test_cpy_different_typei8(i64) { -+; CHECK-LABEL: @test_cpy_different_typei8 -+; CHECK-NOT: alloca -+; CHECK: bitcast i64 %0 to double -+ %a = alloca i64 -+ %b = alloca double -+ store i64 %0, i64 *%a -+ %acast = bitcast i64* %a to i8* -+ %bcast = bitcast double* %b to i8* -+ call void @llvm.memcpy.p0i8.p0i8.i32(i8 *%bcast, i8 *%acast, i32 8, i32 0, i1 0) -+ %loaded = load double, double *%b -+ ret double %loaded -+} -+ -+define i64 @test_cpy_differenti8_reverse(i128) { -+; CHECK-LABEL: @test_cpy_differenti8_reverse -+; CHECK-NOT: alloca i64 -+ %a = alloca i64 -+ %b = alloca i128 -+ store i128 %0, i128 *%b -+ %acast = bitcast i64* %a to i8* -+ %bcast = bitcast i128* %b to i8* -+ call void @llvm.memcpy.p0i8.p0i8.i32(i8 *%acast, i8 *%bcast, i32 8, i32 0, i1 0) -+ %loaded = load i64, i64 *%a -+ ret i64 %loaded -+} --- -2.9.3 - diff --git a/deps/patches/llvm-D38765-gvn_5.0.patch b/deps/patches/llvm-D38765-gvn_5.0.patch deleted file mode 100644 index 15c81dd8fd8d1..0000000000000 --- a/deps/patches/llvm-D38765-gvn_5.0.patch +++ /dev/null @@ -1,51 +0,0 @@ -From c65eb3a4b70a119da41ff2d3ebce0b037f92cba7 Mon Sep 17 00:00:00 2001 -From: Davide Italiano -Date: Wed, 11 Oct 2017 04:21:51 +0000 -Subject: [PATCH] [GVN] Don't replace constants with constants. - -This fixes PR34908. Patch by Alex Crichton! - -Differential Revision: https://reviews.llvm.org/D38765 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315429 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Transforms/Scalar/GVN.cpp | 5 +++++ - test/Transforms/GVN/pr34908.ll | 13 +++++++++++++ - 2 files changed, 18 insertions(+) - create mode 100644 test/Transforms/GVN/pr34908.ll - -diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp -index 4e24d755c26..c3cc2375e3b 100644 ---- a/lib/Transforms/Scalar/GVN.cpp -+++ b/lib/Transforms/Scalar/GVN.cpp -@@ -1362,6 +1362,11 @@ bool GVN::processAssumeIntrinsic(IntrinsicInst *IntrinsicI) { - } - markInstructionForDeletion(IntrinsicI); - return false; -+ } else if (isa(V)) { -+ // If it's not false, and constant, it must evaluate to true. This means our -+ // assume is assume(true), and thus, pointless, and we don't want to do -+ // anything more here. -+ return false; - } - - Constant *True = ConstantInt::getTrue(V->getContext()); -diff --git a/test/Transforms/GVN/pr34908.ll b/test/Transforms/GVN/pr34908.ll -new file mode 100644 -index 00000000000..c2b58ad34a6 ---- /dev/null -+++ b/test/Transforms/GVN/pr34908.ll -@@ -0,0 +1,13 @@ -+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -+; RUN: opt < %s -gvn -S | FileCheck %s -+ -+define i1 @foo() { -+; CHECK-LABEL: @foo( -+; CHECK-NEXT: call void @llvm.assume(i1 undef) -+; CHECK-NEXT: ret i1 undef -+; -+ call void @llvm.assume(i1 undef) -+ ret i1 undef -+} -+ -+declare void @llvm.assume(i1) diff --git a/deps/patches/llvm-D39297-musl-dynamiclibrary-pre5.patch b/deps/patches/llvm-D39297-musl-dynamiclibrary-pre5.patch deleted file mode 100644 index 2ed33c9969f9f..0000000000000 --- a/deps/patches/llvm-D39297-musl-dynamiclibrary-pre5.patch +++ /dev/null @@ -1,40 +0,0 @@ -From ae8900a8833835309aecb0a3d947c2ae46fd86c3 Mon Sep 17 00:00:00 2001 -From: Keno Fischer -Date: Thu, 26 Oct 2017 16:44:13 +0000 -Subject: [PATCH] [DynamicLibrary] Fix build on musl libc - -Summary: -On musl libc, stdin/out/err are defined as `FILE* const` globals, -and their address is not implicitly convertible to void *, -or at least gcc 6 doesn't allow it, giving errors like: - -``` -error: cannot initialize return object of type 'void *' with an rvalue of type 'FILE *const *' (aka '_IO_FILE *const *') - EXPLICIT_SYMBOL(stderr); - ^~~~~~~~~~~~~~~~~~~~~~~ -``` - -Add an explicit cast to fix that problem. - -Reviewers: marsupial, krytarowski, dim -Reviewed By: dim -Differential Revision: https://reviews.llvm.org/D39297 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316672 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Support/Unix/DynamicLibrary.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/Support/Unix/DynamicLibrary.inc b/lib/Support/Unix/DynamicLibrary.inc -index f05103ccd1eb..029451f347e8 100644 ---- a/lib/Support/DynamicLibrary.cpp -+++ b/lib/Support/DynamicLibrary.cpp -@@ -71,7 +71,7 @@ void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) { - - // This macro returns the address of a well-known, explicit symbol - #define EXPLICIT_SYMBOL(SYM) \ -- if (!strcmp(symbolName, #SYM)) return &SYM -+ if (!strcmp(symbolName, #SYM)) return (void*)&SYM - - // On linux we have a weird situation. The stderr/out/in symbols are both - // macros and global variables because of standards requirements. So, we diff --git a/deps/patches/llvm-D39297-musl-dynamiclibrary.patch b/deps/patches/llvm-D39297-musl-dynamiclibrary.patch deleted file mode 100644 index f1956d841b39c..0000000000000 --- a/deps/patches/llvm-D39297-musl-dynamiclibrary.patch +++ /dev/null @@ -1,40 +0,0 @@ -From ae8900a8833835309aecb0a3d947c2ae46fd86c3 Mon Sep 17 00:00:00 2001 -From: Keno Fischer -Date: Thu, 26 Oct 2017 16:44:13 +0000 -Subject: [PATCH] [DynamicLibrary] Fix build on musl libc - -Summary: -On musl libc, stdin/out/err are defined as `FILE* const` globals, -and their address is not implicitly convertible to void *, -or at least gcc 6 doesn't allow it, giving errors like: - -``` -error: cannot initialize return object of type 'void *' with an rvalue of type 'FILE *const *' (aka '_IO_FILE *const *') - EXPLICIT_SYMBOL(stderr); - ^~~~~~~~~~~~~~~~~~~~~~~ -``` - -Add an explicit cast to fix that problem. - -Reviewers: marsupial, krytarowski, dim -Reviewed By: dim -Differential Revision: https://reviews.llvm.org/D39297 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316672 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Support/Unix/DynamicLibrary.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/Support/Unix/DynamicLibrary.inc b/lib/Support/Unix/DynamicLibrary.inc -index f05103ccd1eb..029451f347e8 100644 ---- a/lib/Support/Unix/DynamicLibrary.inc -+++ b/lib/Support/Unix/DynamicLibrary.inc -@@ -71,7 +71,7 @@ void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) { - // Must declare the symbols in the global namespace. - static void *DoSearch(const char* SymbolName) { - #define EXPLICIT_SYMBOL(SYM) \ -- extern void *SYM; if (!strcmp(SymbolName, #SYM)) return &SYM -+ extern void *SYM; if (!strcmp(SymbolName, #SYM)) return (void*)&SYM - - // If this is darwin, it has some funky issues, try to solve them here. Some - // important symbols are marked 'private external' which doesn't allow diff --git a/deps/patches/llvm-D9168_argument_alignment.patch b/deps/patches/llvm-D9168_argument_alignment.patch deleted file mode 100644 index 8166cc379f419..0000000000000 --- a/deps/patches/llvm-D9168_argument_alignment.patch +++ /dev/null @@ -1,98 +0,0 @@ -Index: lib/Target/NVPTX/NVPTXISelLowering.h -=================================================================== ---- a/lib/Target/NVPTX/NVPTXISelLowering.h -+++ b/lib/Target/NVPTX/NVPTXISelLowering.h -@@ -539,7 +539,8 @@ - SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; - - unsigned getArgumentAlignment(SDValue Callee, const ImmutableCallSite *CS, -- Type *Ty, unsigned Idx) const; -+ Type *Ty, unsigned Idx, -+ const DataLayout &DL) const; - }; - } // namespace llvm - -Index: lib/Target/NVPTX/NVPTXISelLowering.cpp -=================================================================== ---- a/lib/Target/NVPTX/NVPTXISelLowering.cpp -+++ b/lib/Target/NVPTX/NVPTXISelLowering.cpp -@@ -1024,11 +1024,15 @@ - return O.str(); - } - --unsigned --NVPTXTargetLowering::getArgumentAlignment(SDValue Callee, -- const ImmutableCallSite *CS, -- Type *Ty, -- unsigned Idx) const { -+unsigned NVPTXTargetLowering::getArgumentAlignment(SDValue Callee, -+ const ImmutableCallSite *CS, -+ Type *Ty, unsigned Idx, -+ const DataLayout &DL) const { -+ if (!CS) { -+ // CallSite is zero, fallback to ABI type alignment -+ return DL.getABITypeAlignment(Ty); -+ } -+ - unsigned Align = 0; - const Value *DirectCallee = CS->getCalledFunction(); - -@@ -1046,7 +1050,7 @@ - - const Value *CalleeV = cast(CalleeI)->getCalledValue(); - // Ignore any bitcast instructions -- while(isa(CalleeV)) { -+ while (isa(CalleeV)) { - const ConstantExpr *CE = cast(CalleeV); - if (!CE->isCast()) - break; -@@ -1069,7 +1073,6 @@ - - // Call is indirect or alignment information is not available, fall back to - // the ABI type alignment -- auto &DL = CS->getCaller()->getParent()->getDataLayout(); - return DL.getABITypeAlignment(Ty); - } - -@@ -1126,7 +1129,8 @@ - ComputePTXValueVTs(*this, DAG.getDataLayout(), Ty, vtparts, &Offsets, - 0); - -- unsigned align = getArgumentAlignment(Callee, CS, Ty, paramCount + 1); -+ unsigned align = -+ getArgumentAlignment(Callee, CS, Ty, paramCount + 1, DL); - // declare .param .align .b8 .param[]; - unsigned sz = DL.getTypeAllocSize(Ty); - SDVTList DeclareParamVTs = DAG.getVTList(MVT::Other, MVT::Glue); -@@ -1166,7 +1170,8 @@ - } - if (Ty->isVectorTy()) { - EVT ObjectVT = getValueType(DL, Ty); -- unsigned align = getArgumentAlignment(Callee, CS, Ty, paramCount + 1); -+ unsigned align = -+ getArgumentAlignment(Callee, CS, Ty, paramCount + 1, DL); - // declare .param .align .b8 .param[]; - unsigned sz = DL.getTypeAllocSize(Ty); - SDVTList DeclareParamVTs = DAG.getVTList(MVT::Other, MVT::Glue); -@@ -1426,7 +1431,7 @@ - DeclareRetOps); - InFlag = Chain.getValue(1); - } else { -- retAlignment = getArgumentAlignment(Callee, CS, retTy, 0); -+ retAlignment = getArgumentAlignment(Callee, CS, retTy, 0, DL); - SDVTList DeclareRetVTs = DAG.getVTList(MVT::Other, MVT::Glue); - SDValue DeclareRetOps[] = { Chain, - DAG.getConstant(retAlignment, dl, MVT::i32), -@@ -1633,9 +1638,10 @@ - } else { - SmallVector VTs; - SmallVector Offsets; -- ComputePTXValueVTs(*this, DAG.getDataLayout(), retTy, VTs, &Offsets, 0); -+ auto &DL = DAG.getDataLayout(); -+ ComputePTXValueVTs(*this, DL, retTy, VTs, &Offsets, 0); - assert(VTs.size() == Ins.size() && "Bad value decomposition"); -- unsigned RetAlign = getArgumentAlignment(Callee, CS, retTy, 0); -+ unsigned RetAlign = getArgumentAlignment(Callee, CS, retTy, 0, DL); - for (unsigned i = 0, e = Ins.size(); i != e; ++i) { - unsigned sz = VTs[i].getSizeInBits(); - unsigned AlignI = GreatestCommonDivisor64(RetAlign, Offsets[i]); diff --git a/deps/patches/llvm-NVPTX-addrspaces.patch b/deps/patches/llvm-NVPTX-addrspaces.patch deleted file mode 100644 index 006868d61ace0..0000000000000 --- a/deps/patches/llvm-NVPTX-addrspaces.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff -u llvm-3.9.1.orig/lib/Target/NVPTX/NVPTXISelLowering.cpp llvm-3.9.1/lib/Target/NVPTX/NVPTXISelLowering.cpp ---- llvm-3.9.1.orig/lib/Target/NVPTX/NVPTXISelLowering.cpp 2016-07-15 20:27:10.000000000 +0200 -+++ llvm-3.9.1/lib/Target/NVPTX/NVPTXISelLowering.cpp 2017-09-07 04:04:25.540721694 +0200 -@@ -888,6 +910,14 @@ - return TargetLoweringBase::getPreferredVectorAction(VT); - } - -+bool NVPTXTargetLowering::isNoopAddrSpaceCast(unsigned SrcAS, -+ unsigned DestAS) const { -+ assert(SrcAS != DestAS && "Expected different address spaces!"); -+ -+ return (SrcAS == ADDRESS_SPACE_GENERIC || SrcAS > ADDRESS_SPACE_LOCAL) && -+ (DestAS == ADDRESS_SPACE_GENERIC || DestAS > ADDRESS_SPACE_LOCAL); -+} -+ - SDValue - NVPTXTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { - SDLoc dl(Op); -diff -u llvm-3.9.1.orig/lib/Target/NVPTX/NVPTXISelLowering.h llvm-3.9.1/lib/Target/NVPTX/NVPTXISelLowering.h ---- llvm-3.9.1.orig/lib/Target/NVPTX/NVPTXISelLowering.h 2016-06-12 17:39:02.000000000 +0200 -+++ llvm-3.9.1/lib/Target/NVPTX/NVPTXISelLowering.h 2017-09-07 04:03:39.591373952 +0200 -@@ -442,6 +442,8 @@ - const NVPTXSubtarget &STI); - SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; - -+ bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override; -+ - SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; - - const char *getTargetNodeName(unsigned Opcode) const override; diff --git a/deps/patches/llvm-PR22923.patch b/deps/patches/llvm-PR22923.patch deleted file mode 100644 index c48533bcc4d89..0000000000000 --- a/deps/patches/llvm-PR22923.patch +++ /dev/null @@ -1,151 +0,0 @@ -From e060ffb4b20e294ecb8429bd8a925f9f12b63b17 Mon Sep 17 00:00:00 2001 -From: Hal Finkel -Date: Mon, 29 Aug 2016 22:25:36 +0000 -Subject: [PATCH] [PowerPC] Fix i8/i16 atomics for little-Endian targets - without partword atomics - -For little-Endian PowerPC, we generally target only P8 and later by default. -However, generic (older) 64-bit configurations are still an option, and in that -case, partword atomics are not available (e.g. stbcx.). To lower i8/i16 atomics -without true i8/i16 atomic operations, we emulate using i32 atomics in -combination with a bunch of shifting and masking, etc. The amount by which to -shift in little-Endian mode is different from the amount in big-Endian mode (it -is inverted -- meaning we can leave off the xor when computing the amount). - -Fixes PR22923. - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280022 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Target/PowerPC/PPCISelLowering.cpp | 18 ++++++++++++------ - test/CodeGen/PowerPC/atomic-2.ll | 15 ++++++++++++++- - 2 files changed, 26 insertions(+), 7 deletions(-) - -diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp -index e89b6ca..f895b06 100644 ---- a/lib/Target/PowerPC/PPCISelLowering.cpp -+++ b/lib/Target/PowerPC/PPCISelLowering.cpp -@@ -8513,6 +8513,7 @@ PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr &MI, - // registers without caring whether they're 32 or 64, but here we're - // doing actual arithmetic on the addresses. - bool is64bit = Subtarget.isPPC64(); -+ bool isLittleEndian = Subtarget.isLittleEndian(); - unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO; - - const BasicBlock *LLVM_BB = BB->getBasicBlock(); -@@ -8542,7 +8543,8 @@ PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr &MI, - : &PPC::GPRCRegClass; - unsigned PtrReg = RegInfo.createVirtualRegister(RC); - unsigned Shift1Reg = RegInfo.createVirtualRegister(RC); -- unsigned ShiftReg = RegInfo.createVirtualRegister(RC); -+ unsigned ShiftReg = -+ isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(RC); - unsigned Incr2Reg = RegInfo.createVirtualRegister(RC); - unsigned MaskReg = RegInfo.createVirtualRegister(RC); - unsigned Mask2Reg = RegInfo.createVirtualRegister(RC); -@@ -8587,8 +8589,9 @@ PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr &MI, - } - BuildMI(BB, dl, TII->get(PPC::RLWINM), Shift1Reg).addReg(Ptr1Reg) - .addImm(3).addImm(27).addImm(is8bit ? 28 : 27); -- BuildMI(BB, dl, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg) -- .addReg(Shift1Reg).addImm(is8bit ? 24 : 16); -+ if (!isLittleEndian) -+ BuildMI(BB, dl, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg) -+ .addReg(Shift1Reg).addImm(is8bit ? 24 : 16); - if (is64bit) - BuildMI(BB, dl, TII->get(PPC::RLDICR), PtrReg) - .addReg(Ptr1Reg).addImm(0).addImm(61); -@@ -9293,6 +9296,7 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, - // since we're actually doing arithmetic on them. Other registers - // can be 32-bit. - bool is64bit = Subtarget.isPPC64(); -+ bool isLittleEndian = Subtarget.isLittleEndian(); - bool is8bit = MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8; - - unsigned dest = MI.getOperand(0).getReg(); -@@ -9319,7 +9323,8 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, - : &PPC::GPRCRegClass; - unsigned PtrReg = RegInfo.createVirtualRegister(RC); - unsigned Shift1Reg = RegInfo.createVirtualRegister(RC); -- unsigned ShiftReg = RegInfo.createVirtualRegister(RC); -+ unsigned ShiftReg = -+ isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(RC); - unsigned NewVal2Reg = RegInfo.createVirtualRegister(RC); - unsigned NewVal3Reg = RegInfo.createVirtualRegister(RC); - unsigned OldVal2Reg = RegInfo.createVirtualRegister(RC); -@@ -9374,8 +9379,9 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, - } - BuildMI(BB, dl, TII->get(PPC::RLWINM), Shift1Reg).addReg(Ptr1Reg) - .addImm(3).addImm(27).addImm(is8bit ? 28 : 27); -- BuildMI(BB, dl, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg) -- .addReg(Shift1Reg).addImm(is8bit ? 24 : 16); -+ if (!isLittleEndian) -+ BuildMI(BB, dl, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg) -+ .addReg(Shift1Reg).addImm(is8bit ? 24 : 16); - if (is64bit) - BuildMI(BB, dl, TII->get(PPC::RLDICR), PtrReg) - .addReg(Ptr1Reg).addImm(0).addImm(61); -diff --git a/test/CodeGen/PowerPC/atomic-2.ll b/test/CodeGen/PowerPC/atomic-2.ll -index 1857d5d..bafabdb 100644 ---- a/test/CodeGen/PowerPC/atomic-2.ll -+++ b/test/CodeGen/PowerPC/atomic-2.ll -@@ -1,4 +1,5 @@ --; RUN: llc < %s -march=ppc64 | FileCheck %s -+; RUN: llc < %s -march=ppc64 | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE -+; RUN: llc < %s -march=ppc64le | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE - ; RUN: llc < %s -march=ppc64 -mcpu=pwr7 | FileCheck %s - ; RUN: llc < %s -march=ppc64 -mcpu=pwr8 | FileCheck %s -check-prefix=CHECK-P8U - -@@ -12,6 +13,8 @@ define i64 @exchange_and_add(i64* %mem, i64 %val) nounwind { - - define i8 @exchange_and_add8(i8* %mem, i8 %val) nounwind { - ; CHECK-LABEL: exchange_and_add8: -+; CHECK-BE: xori -+; CHECK-LE-NOT: xori - ; CHECK-P8U: lbarx - %tmp = atomicrmw add i8* %mem, i8 %val monotonic - ; CHECK-P8U: stbcx. -@@ -20,6 +23,8 @@ define i8 @exchange_and_add8(i8* %mem, i8 %val) nounwind { - - define i16 @exchange_and_add16(i16* %mem, i16 %val) nounwind { - ; CHECK-LABEL: exchange_and_add16: -+; CHECK-BE: xori -+; CHECK-LE-NOT: xori - ; CHECK-P8U: lharx - %tmp = atomicrmw add i16* %mem, i16 %val monotonic - ; CHECK-P8U: sthcx. -@@ -38,6 +43,8 @@ define i64 @exchange_and_cmp(i64* %mem) nounwind { - - define i8 @exchange_and_cmp8(i8* %mem) nounwind { - ; CHECK-LABEL: exchange_and_cmp8: -+; CHECK-BE: xori -+; CHECK-LE-NOT: xori - ; CHECK-P8U: lbarx - %tmppair = cmpxchg i8* %mem, i8 0, i8 1 monotonic monotonic - %tmp = extractvalue { i8, i1 } %tmppair, 0 -@@ -48,6 +55,8 @@ define i8 @exchange_and_cmp8(i8* %mem) nounwind { - - define i16 @exchange_and_cmp16(i16* %mem) nounwind { - ; CHECK-LABEL: exchange_and_cmp16: -+; CHECK-BE: xori -+; CHECK-LE-NOT: xori - ; CHECK-P8U: lharx - %tmppair = cmpxchg i16* %mem, i16 0, i16 1 monotonic monotonic - %tmp = extractvalue { i16, i1 } %tmppair, 0 -@@ -66,6 +75,8 @@ define i64 @exchange(i64* %mem, i64 %val) nounwind { - - define i8 @exchange8(i8* %mem, i8 %val) nounwind { - ; CHECK-LABEL: exchange8: -+; CHECK-BE: xori -+; CHECK-LE-NOT: xori - ; CHECK-P8U: lbarx - %tmp = atomicrmw xchg i8* %mem, i8 1 monotonic - ; CHECK-P8U: stbcx. -@@ -74,6 +85,8 @@ define i8 @exchange8(i8* %mem, i8 %val) nounwind { - - define i16 @exchange16(i16* %mem, i16 %val) nounwind { - ; CHECK-LABEL: exchange16: -+; CHECK-BE: xori -+; CHECK-LE-NOT: xori - ; CHECK-P8U: lharx - %tmp = atomicrmw xchg i16* %mem, i16 1 monotonic - ; CHECK-P8U: sthcx. diff --git a/deps/patches/llvm-PR276266.patch b/deps/patches/llvm-PR276266.patch deleted file mode 100644 index 576e96e5836d3..0000000000000 --- a/deps/patches/llvm-PR276266.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 64d1e8b748bca22ce205eab7634cc5418c827f18 Mon Sep 17 00:00:00 2001 -From: Marina Yatsina -Date: Thu, 21 Jul 2016 12:37:07 +0000 -Subject: [PATCH 3/5] ExecutionDepsFix - Fix bug in clearance calculation - -The clearance calculation did not take into account registers defined as outputs or clobbers in inline assembly machine instructions because these register defs are implicit. - -Differential Revision: http://reviews.llvm.org/D22580 - - - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276266 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/CodeGen/ExecutionDepsFix.cpp | 2 -- - test/CodeGen/X86/break-false-dep.ll | 10 ++++++++++ - 2 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/lib/CodeGen/ExecutionDepsFix.cpp b/lib/CodeGen/ExecutionDepsFix.cpp -index 566b8d507b2..1fe5f459b69 100644 ---- a/lib/CodeGen/ExecutionDepsFix.cpp -+++ b/lib/CodeGen/ExecutionDepsFix.cpp -@@ -520,8 +520,6 @@ void ExeDepsFix::processDefs(MachineInstr *MI, bool Kill) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg()) - continue; -- if (MO.isImplicit()) -- break; - if (MO.isUse()) - continue; - for (int rx : regIndices(MO.getReg())) { -diff --git a/test/CodeGen/X86/break-false-dep.ll b/test/CodeGen/X86/break-false-dep.ll -index 74a0728f918..a7cda499dab 100644 ---- a/test/CodeGen/X86/break-false-dep.ll -+++ b/test/CodeGen/X86/break-false-dep.ll -@@ -199,3 +199,13 @@ for.end16: ; preds = %for.inc14 - ;AVX-NEXT: vmulsd {{.*}}, [[XMM0]], [[XMM0]] - ;AVX-NEXT: vmovsd [[XMM0]], - } -+ -+define double @inlineasmdep(i64 %arg) { -+top: -+ tail call void asm sideeffect "", "~{xmm0},~{dirflag},~{fpsr},~{flags}"() -+ %tmp1 = sitofp i64 %arg to double -+ ret double %tmp1 -+;AVX-LABEL:@inlineasmdep -+;AVX: vxorps [[XMM0:%xmm[0-9]+]], [[XMM0]], [[XMM0]] -+;AVX-NEXT: vcvtsi2sdq {{.*}}, [[XMM0]], {{%xmm[0-9]+}} -+} --- -2.11.0 - diff --git a/deps/patches/llvm-PR277939.patch b/deps/patches/llvm-PR277939.patch deleted file mode 100644 index 65e46c32b4848..0000000000000 --- a/deps/patches/llvm-PR277939.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 9790ab8bccdbc71dfcc166860ab6ce9c369bf686 Mon Sep 17 00:00:00 2001 -From: Simon Pilgrim -Date: Sat, 6 Aug 2016 21:21:12 +0000 -Subject: [PATCH 1/5] [X86][AVX2] Improve sign/zero extension on AVX2 targets - -Split extensions to large vectors into 256-bit chunks - the equivalent of what we do with pre-AVX2 into 128-bit chunks - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277939 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Target/X86/X86ISelLowering.cpp | 22 +++++++++++++++------- - test/CodeGen/X86/vec_int_to_fp.ll | 24 ++++++++---------------- - test/CodeGen/X86/vector-sext.ll | 10 ++-------- - 3 files changed, 25 insertions(+), 31 deletions(-) - -diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp -index ca205335013..2bbedd4bd97 100644 ---- a/lib/Target/X86/X86ISelLowering.cpp -+++ b/lib/Target/X86/X86ISelLowering.cpp -@@ -30164,11 +30164,9 @@ static SDValue combineToExtendVectorInReg(SDNode *N, SelectionDAG &DAG, - : DAG.getZeroExtendVectorInReg(ExOp, DL, VT); - } - -- // On pre-AVX2 targets, split into 128-bit nodes of -- // ISD::*_EXTEND_VECTOR_INREG. -- if (!Subtarget.hasInt256() && !(VT.getSizeInBits() % 128)) { -- unsigned NumVecs = VT.getSizeInBits() / 128; -- unsigned NumSubElts = 128 / SVT.getSizeInBits(); -+ auto SplitAndExtendInReg = [&](unsigned SplitSize) { -+ unsigned NumVecs = VT.getSizeInBits() / SplitSize; -+ unsigned NumSubElts = SplitSize / SVT.getSizeInBits(); - EVT SubVT = EVT::getVectorVT(*DAG.getContext(), SVT, NumSubElts); - EVT InSubVT = EVT::getVectorVT(*DAG.getContext(), InSVT, NumSubElts); - -@@ -30176,14 +30174,24 @@ static SDValue combineToExtendVectorInReg(SDNode *N, SelectionDAG &DAG, - for (unsigned i = 0, Offset = 0; i != NumVecs; ++i, Offset += NumSubElts) { - SDValue SrcVec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, InSubVT, N0, - DAG.getIntPtrConstant(Offset, DL)); -- SrcVec = ExtendVecSize(DL, SrcVec, 128); -+ SrcVec = ExtendVecSize(DL, SrcVec, SplitSize); - SrcVec = Opcode == ISD::SIGN_EXTEND - ? DAG.getSignExtendVectorInReg(SrcVec, DL, SubVT) - : DAG.getZeroExtendVectorInReg(SrcVec, DL, SubVT); - Opnds.push_back(SrcVec); - } - return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Opnds); -- } -+ }; -+ -+ // On pre-AVX2 targets, split into 128-bit nodes of -+ // ISD::*_EXTEND_VECTOR_INREG. -+ if (!Subtarget.hasInt256() && !(VT.getSizeInBits() % 128)) -+ return SplitAndExtendInReg(128); -+ -+ // On pre-AVX512 targets, split into 256-bit nodes of -+ // ISD::*_EXTEND_VECTOR_INREG. -+ if (!Subtarget.hasAVX512() && !(VT.getSizeInBits() % 256)) -+ return SplitAndExtendInReg(256); - - return SDValue(); - } -diff --git a/test/CodeGen/X86/vec_int_to_fp.ll b/test/CodeGen/X86/vec_int_to_fp.ll -index 43f5318a607..5d8f91385c7 100644 ---- a/test/CodeGen/X86/vec_int_to_fp.ll -+++ b/test/CodeGen/X86/vec_int_to_fp.ll -@@ -153,8 +153,7 @@ define <2 x double> @sitofp_16i8_to_2f64(<16 x i8> %a) { - ; - ; AVX2-LABEL: sitofp_16i8_to_2f64: - ; AVX2: # BB#0: --; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 --; AVX2-NEXT: vpmovsxwd %xmm0, %ymm0 -+; AVX2-NEXT: vpmovsxbd %xmm0, %ymm0 - ; AVX2-NEXT: vcvtdq2pd %xmm0, %ymm0 - ; AVX2-NEXT: # kill - ; AVX2-NEXT: vzeroupper -@@ -325,8 +324,7 @@ define <4 x double> @sitofp_16i8_to_4f64(<16 x i8> %a) { - ; - ; AVX2-LABEL: sitofp_16i8_to_4f64: - ; AVX2: # BB#0: --; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 --; AVX2-NEXT: vpmovsxwd %xmm0, %ymm0 -+; AVX2-NEXT: vpmovsxbd %xmm0, %ymm0 - ; AVX2-NEXT: vcvtdq2pd %xmm0, %ymm0 - ; AVX2-NEXT: retq - %cvt = sitofp <16 x i8> %a to <16 x double> -@@ -543,8 +541,7 @@ define <2 x double> @uitofp_16i8_to_2f64(<16 x i8> %a) { - ; - ; AVX2-LABEL: uitofp_16i8_to_2f64: - ; AVX2: # BB#0: --; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero --; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero -+; AVX2-NEXT: vpmovzxbd {{.*#+}} ymm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero,xmm0[4],zero,zero,zero,xmm0[5],zero,zero,zero,xmm0[6],zero,zero,zero,xmm0[7],zero,zero,zero - ; AVX2-NEXT: vcvtdq2pd %xmm0, %ymm0 - ; AVX2-NEXT: # kill - ; AVX2-NEXT: vzeroupper -@@ -778,8 +775,7 @@ define <4 x double> @uitofp_16i8_to_4f64(<16 x i8> %a) { - ; - ; AVX2-LABEL: uitofp_16i8_to_4f64: - ; AVX2: # BB#0: --; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero --; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero -+; AVX2-NEXT: vpmovzxbd {{.*#+}} ymm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero,xmm0[4],zero,zero,zero,xmm0[5],zero,zero,zero,xmm0[6],zero,zero,zero,xmm0[7],zero,zero,zero - ; AVX2-NEXT: vcvtdq2pd %xmm0, %ymm0 - ; AVX2-NEXT: retq - %cvt = uitofp <16 x i8> %a to <16 x double> -@@ -958,8 +954,7 @@ define <4 x float> @sitofp_16i8_to_4f32(<16 x i8> %a) { - ; - ; AVX2-LABEL: sitofp_16i8_to_4f32: - ; AVX2: # BB#0: --; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 --; AVX2-NEXT: vpmovsxwd %xmm0, %ymm0 -+; AVX2-NEXT: vpmovsxbd %xmm0, %ymm0 - ; AVX2-NEXT: vcvtdq2ps %ymm0, %ymm0 - ; AVX2-NEXT: # kill - ; AVX2-NEXT: vzeroupper -@@ -1134,8 +1129,7 @@ define <8 x float> @sitofp_16i8_to_8f32(<16 x i8> %a) { - ; - ; AVX2-LABEL: sitofp_16i8_to_8f32: - ; AVX2: # BB#0: --; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 --; AVX2-NEXT: vpmovsxwd %xmm0, %ymm0 -+; AVX2-NEXT: vpmovsxbd %xmm0, %ymm0 - ; AVX2-NEXT: vcvtdq2ps %ymm0, %ymm0 - ; AVX2-NEXT: retq - %cvt = sitofp <16 x i8> %a to <16 x float> -@@ -1456,8 +1450,7 @@ define <4 x float> @uitofp_16i8_to_4f32(<16 x i8> %a) { - ; - ; AVX2-LABEL: uitofp_16i8_to_4f32: - ; AVX2: # BB#0: --; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero --; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero -+; AVX2-NEXT: vpmovzxbd {{.*#+}} ymm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero,xmm0[4],zero,zero,zero,xmm0[5],zero,zero,zero,xmm0[6],zero,zero,zero,xmm0[7],zero,zero,zero - ; AVX2-NEXT: vcvtdq2ps %ymm0, %ymm0 - ; AVX2-NEXT: # kill - ; AVX2-NEXT: vzeroupper -@@ -1813,8 +1806,7 @@ define <8 x float> @uitofp_16i8_to_8f32(<16 x i8> %a) { - ; - ; AVX2-LABEL: uitofp_16i8_to_8f32: - ; AVX2: # BB#0: --; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero --; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero -+; AVX2-NEXT: vpmovzxbd {{.*#+}} ymm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero,xmm0[4],zero,zero,zero,xmm0[5],zero,zero,zero,xmm0[6],zero,zero,zero,xmm0[7],zero,zero,zero - ; AVX2-NEXT: vcvtdq2ps %ymm0, %ymm0 - ; AVX2-NEXT: retq - %cvt = uitofp <16 x i8> %a to <16 x float> -diff --git a/test/CodeGen/X86/vector-sext.ll b/test/CodeGen/X86/vector-sext.ll -index 018c5922a43..e29f3e5f91f 100644 ---- a/test/CodeGen/X86/vector-sext.ll -+++ b/test/CodeGen/X86/vector-sext.ll -@@ -407,15 +407,9 @@ define <8 x i64> @sext_16i8_to_8i64(<16 x i8> %A) nounwind uwtable readnone ssp - ; - ; AVX2-LABEL: sext_16i8_to_8i64: - ; AVX2: # BB#0: # %entry --; AVX2-NEXT: vpmovzxbd {{.*#+}} xmm1 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero --; AVX2-NEXT: vpslld $24, %xmm1, %xmm1 --; AVX2-NEXT: vpsrad $24, %xmm1, %xmm1 --; AVX2-NEXT: vpmovsxdq %xmm1, %ymm2 -+; AVX2-NEXT: vpmovsxbq %xmm0, %ymm2 - ; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,2,3] --; AVX2-NEXT: vpmovzxbd {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero --; AVX2-NEXT: vpslld $24, %xmm0, %xmm0 --; AVX2-NEXT: vpsrad $24, %xmm0, %xmm0 --; AVX2-NEXT: vpmovsxdq %xmm0, %ymm1 -+; AVX2-NEXT: vpmovsxbq %xmm0, %ymm1 - ; AVX2-NEXT: vmovdqa %ymm2, %ymm0 - ; AVX2-NEXT: retq - ; --- -2.11.0 - diff --git a/deps/patches/llvm-PR278088.patch b/deps/patches/llvm-PR278088.patch deleted file mode 100644 index 325069326b3ed..0000000000000 --- a/deps/patches/llvm-PR278088.patch +++ /dev/null @@ -1,224 +0,0 @@ -From b01ff685400365f55c5333c29c2227842d61e984 Mon Sep 17 00:00:00 2001 -From: Craig Topper -Date: Tue, 9 Aug 2016 03:06:26 +0000 -Subject: [PATCH 2/5] [X86] Remove unnecessary bitcast from the front of - AVX1Only 256-bit logical operation patterns. - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278088 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Target/X86/X86InstrSSE.td | 8 +++---- - test/CodeGen/X86/WidenArith.ll | 2 +- - test/CodeGen/X86/merge-consecutive-loads-256.ll | 26 ++++++--------------- - test/CodeGen/X86/v8i1-masks.ll | 4 ++-- - test/CodeGen/X86/vec_int_to_fp.ll | 30 ++++++++++++------------- - test/CodeGen/X86/vec_uint_to_fp-fastmath.ll | 26 ++++++++++----------- - 6 files changed, 42 insertions(+), 54 deletions(-) - -diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td -index f91764a67d1..77da22de4d3 100644 ---- a/lib/Target/X86/X86InstrSSE.td -+++ b/lib/Target/X86/X86InstrSSE.td -@@ -2950,13 +2950,13 @@ let isCommutable = 0 in - // AVX1 requires type coercions in order to fold loads directly into logical - // operations. - let Predicates = [HasAVX1Only] in { -- def : Pat<(bc_v8f32 (and VR256:$src1, (loadv4i64 addr:$src2))), -+ def : Pat<(and VR256:$src1, (loadv4i64 addr:$src2)), - (VANDPSYrm VR256:$src1, addr:$src2)>; -- def : Pat<(bc_v8f32 (or VR256:$src1, (loadv4i64 addr:$src2))), -+ def : Pat<(or VR256:$src1, (loadv4i64 addr:$src2)), - (VORPSYrm VR256:$src1, addr:$src2)>; -- def : Pat<(bc_v8f32 (xor VR256:$src1, (loadv4i64 addr:$src2))), -+ def : Pat<(xor VR256:$src1, (loadv4i64 addr:$src2)), - (VXORPSYrm VR256:$src1, addr:$src2)>; -- def : Pat<(bc_v8f32 (X86andnp VR256:$src1, (loadv4i64 addr:$src2))), -+ def : Pat<(X86andnp VR256:$src1, (loadv4i64 addr:$src2)), - (VANDNPSYrm VR256:$src1, addr:$src2)>; - } - -diff --git a/test/CodeGen/X86/WidenArith.ll b/test/CodeGen/X86/WidenArith.ll -index cdd1a2818b2..cc5fcba6670 100644 ---- a/test/CodeGen/X86/WidenArith.ll -+++ b/test/CodeGen/X86/WidenArith.ll -@@ -9,8 +9,8 @@ define <8 x i32> @test(<8 x float> %a, <8 x float> %b) { - ; CHECK-NEXT: vsubps %ymm2, %ymm1, %ymm3 - ; CHECK-NEXT: vcmpltps %ymm1, %ymm0, %ymm0 - ; CHECK-NEXT: vcmpltps %ymm3, %ymm2, %ymm1 --; CHECK-NEXT: vandps {{.*}}(%rip), %ymm1, %ymm1 - ; CHECK-NEXT: vandps %ymm1, %ymm0, %ymm0 -+; CHECK-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0 - ; CHECK-NEXT: retq - %c1 = fadd <8 x float> %a, %b - %b1 = fmul <8 x float> %b, %a -diff --git a/test/CodeGen/X86/merge-consecutive-loads-256.ll b/test/CodeGen/X86/merge-consecutive-loads-256.ll -index 8c2e9372900..dc268d9bdf8 100644 ---- a/test/CodeGen/X86/merge-consecutive-loads-256.ll -+++ b/test/CodeGen/X86/merge-consecutive-loads-256.ll -@@ -547,29 +547,17 @@ define <16 x i16> @merge_16i16_i16_0uu3uuuuuuuuCuEF(i16* %ptr) nounwind uwtable - } - - define <16 x i16> @merge_16i16_i16_0uu3zzuuuuuzCuEF(i16* %ptr) nounwind uwtable noinline ssp { --; AVX1-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF: --; AVX1: # BB#0: --; AVX1-NEXT: vmovaps {{.*#+}} ymm0 = [65535,0,0,65535,0,0,0,0,0,0,0,0,65535,0,65535,65535] --; AVX1-NEXT: vandps (%rdi), %ymm0, %ymm0 --; AVX1-NEXT: retq --; --; AVX2-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF: --; AVX2: # BB#0: --; AVX2-NEXT: vmovups (%rdi), %ymm0 --; AVX2-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0 --; AVX2-NEXT: retq --; --; AVX512F-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF: --; AVX512F: # BB#0: --; AVX512F-NEXT: vmovups (%rdi), %ymm0 --; AVX512F-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0 --; AVX512F-NEXT: retq -+; AVX-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF: -+; AVX: # BB#0: -+; AVX-NEXT: vmovups (%rdi), %ymm0 -+; AVX-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0 -+; AVX-NEXT: retq - ; - ; X32-AVX-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF: - ; X32-AVX: # BB#0: - ; X32-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax --; X32-AVX-NEXT: vmovaps {{.*#+}} ymm0 = [65535,0,0,65535,0,0,0,0,0,0,0,0,65535,0,65535,65535] --; X32-AVX-NEXT: vandps (%eax), %ymm0, %ymm0 -+; X32-AVX-NEXT: vmovups (%eax), %ymm0 -+; X32-AVX-NEXT: vandps {{\.LCPI.*}}, %ymm0, %ymm0 - ; X32-AVX-NEXT: retl - %ptr0 = getelementptr inbounds i16, i16* %ptr, i64 0 - %ptr3 = getelementptr inbounds i16, i16* %ptr, i64 3 -diff --git a/test/CodeGen/X86/v8i1-masks.ll b/test/CodeGen/X86/v8i1-masks.ll -index 0135832ad92..d5c31506e98 100644 ---- a/test/CodeGen/X86/v8i1-masks.ll -+++ b/test/CodeGen/X86/v8i1-masks.ll -@@ -13,8 +13,8 @@ define void @and_masks(<8 x float>* %a, <8 x float>* %b, <8 x float>* %c) nounwi - ; X32-NEXT: vcmpltps %ymm0, %ymm1, %ymm1 - ; X32-NEXT: vmovups (%eax), %ymm2 - ; X32-NEXT: vcmpltps %ymm0, %ymm2, %ymm0 --; X32-NEXT: vandps LCPI0_0, %ymm1, %ymm1 - ; X32-NEXT: vandps %ymm1, %ymm0, %ymm0 -+; X32-NEXT: vandps LCPI0_0, %ymm0, %ymm0 - ; X32-NEXT: vmovaps %ymm0, (%eax) - ; X32-NEXT: vzeroupper - ; X32-NEXT: retl -@@ -26,8 +26,8 @@ define void @and_masks(<8 x float>* %a, <8 x float>* %b, <8 x float>* %c) nounwi - ; X64-NEXT: vcmpltps %ymm0, %ymm1, %ymm1 - ; X64-NEXT: vmovups (%rdx), %ymm2 - ; X64-NEXT: vcmpltps %ymm0, %ymm2, %ymm0 --; X64-NEXT: vandps {{.*}}(%rip), %ymm1, %ymm1 - ; X64-NEXT: vandps %ymm1, %ymm0, %ymm0 -+; X64-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0 - ; X64-NEXT: vmovaps %ymm0, (%rax) - ; X64-NEXT: vzeroupper - ; X64-NEXT: retq -diff --git a/test/CodeGen/X86/vec_int_to_fp.ll b/test/CodeGen/X86/vec_int_to_fp.ll -index 5d8f91385c7..8ea7243664a 100644 ---- a/test/CodeGen/X86/vec_int_to_fp.ll -+++ b/test/CodeGen/X86/vec_int_to_fp.ll -@@ -1694,15 +1694,15 @@ define <8 x float> @uitofp_8i32_to_8f32(<8 x i32> %a) { - ; - ; AVX1-LABEL: uitofp_8i32_to_8f32: - ; AVX1: # BB#0: --; AVX1-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm1 -+; AVX1-NEXT: vpsrld $16, %xmm0, %xmm1 -+; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 -+; AVX1-NEXT: vpsrld $16, %xmm2, %xmm2 -+; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1 - ; AVX1-NEXT: vcvtdq2ps %ymm1, %ymm1 --; AVX1-NEXT: vpsrld $16, %xmm0, %xmm2 --; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 --; AVX1-NEXT: vpsrld $16, %xmm0, %xmm0 --; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm2, %ymm0 -+; AVX1-NEXT: vmulps {{.*}}(%rip), %ymm1, %ymm1 -+; AVX1-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0 - ; AVX1-NEXT: vcvtdq2ps %ymm0, %ymm0 --; AVX1-NEXT: vmulps {{.*}}(%rip), %ymm0, %ymm0 --; AVX1-NEXT: vaddps %ymm1, %ymm0, %ymm0 -+; AVX1-NEXT: vaddps %ymm0, %ymm1, %ymm0 - ; AVX1-NEXT: retq - ; - ; AVX2-LABEL: uitofp_8i32_to_8f32: -@@ -3372,16 +3372,16 @@ define <8 x float> @uitofp_load_8i32_to_8f32(<8 x i32> *%a) { - ; - ; AVX1-LABEL: uitofp_load_8i32_to_8f32: - ; AVX1: # BB#0: --; AVX1-NEXT: vmovaps (%rdi), %ymm0 --; AVX1-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm1 -+; AVX1-NEXT: vmovdqa (%rdi), %ymm0 -+; AVX1-NEXT: vpsrld $16, %xmm0, %xmm1 -+; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 -+; AVX1-NEXT: vpsrld $16, %xmm2, %xmm2 -+; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1 - ; AVX1-NEXT: vcvtdq2ps %ymm1, %ymm1 --; AVX1-NEXT: vpsrld $16, %xmm0, %xmm2 --; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 --; AVX1-NEXT: vpsrld $16, %xmm0, %xmm0 --; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm2, %ymm0 -+; AVX1-NEXT: vmulps {{.*}}(%rip), %ymm1, %ymm1 -+; AVX1-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0 - ; AVX1-NEXT: vcvtdq2ps %ymm0, %ymm0 --; AVX1-NEXT: vmulps {{.*}}(%rip), %ymm0, %ymm0 --; AVX1-NEXT: vaddps %ymm1, %ymm0, %ymm0 -+; AVX1-NEXT: vaddps %ymm0, %ymm1, %ymm0 - ; AVX1-NEXT: retq - ; - ; AVX2-LABEL: uitofp_load_8i32_to_8f32: -diff --git a/test/CodeGen/X86/vec_uint_to_fp-fastmath.ll b/test/CodeGen/X86/vec_uint_to_fp-fastmath.ll -index c0e02bd1599..cb8e2096585 100644 ---- a/test/CodeGen/X86/vec_uint_to_fp-fastmath.ll -+++ b/test/CodeGen/X86/vec_uint_to_fp-fastmath.ll -@@ -78,18 +78,18 @@ define <4 x float> @test_uitofp_v4i32_to_v4f32(<4 x i32> %arg) { - ret <4 x float> %tmp - } - --; AVX: [[MASKCSTADDR_v8:.LCPI[0-9_]+]]: --; AVX-NEXT: .long 65535 # 0xffff --; AVX-NEXT: .long 65535 # 0xffff --; AVX-NEXT: .long 65535 # 0xffff --; AVX-NEXT: .long 65535 # 0xffff -- - ; AVX: [[FPMASKCSTADDR_v8:.LCPI[0-9_]+]]: - ; AVX-NEXT: .long 1199570944 # float 65536 - ; AVX-NEXT: .long 1199570944 # float 65536 - ; AVX-NEXT: .long 1199570944 # float 65536 - ; AVX-NEXT: .long 1199570944 # float 65536 - -+; AVX: [[MASKCSTADDR_v8:.LCPI[0-9_]+]]: -+; AVX-NEXT: .long 65535 # 0xffff -+; AVX-NEXT: .long 65535 # 0xffff -+; AVX-NEXT: .long 65535 # 0xffff -+; AVX-NEXT: .long 65535 # 0xffff -+ - ; AVX2: [[FPMASKCSTADDR_v8:.LCPI[0-9_]+]]: - ; AVX2-NEXT: .long 1199570944 # float 65536 - -@@ -119,15 +119,15 @@ define <8 x float> @test_uitofp_v8i32_to_v8f32(<8 x i32> %arg) { - ; - ; AVX-LABEL: test_uitofp_v8i32_to_v8f32: - ; AVX: # BB#0: --; AVX-NEXT: vandps [[MASKCSTADDR_v8]](%rip), %ymm0, %ymm1 -+; AVX-NEXT: vpsrld $16, %xmm0, %xmm1 -+; AVX-NEXT: vextractf128 $1, %ymm0, %xmm2 -+; AVX-NEXT: vpsrld $16, %xmm2, %xmm2 -+; AVX-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1 - ; AVX-NEXT: vcvtdq2ps %ymm1, %ymm1 --; AVX-NEXT: vpsrld $16, %xmm0, %xmm2 --; AVX-NEXT: vextractf128 $1, %ymm0, %xmm0 --; AVX-NEXT: vpsrld $16, %xmm0, %xmm0 --; AVX-NEXT: vinsertf128 $1, %xmm0, %ymm2, %ymm0 -+; AVX-NEXT: vmulps [[FPMASKCSTADDR_v8]](%rip), %ymm1, %ymm1 -+; AVX-NEXT: vandps [[MASKCSTADDR_v8]](%rip), %ymm0, %ymm0 - ; AVX-NEXT: vcvtdq2ps %ymm0, %ymm0 --; AVX-NEXT: vmulps [[FPMASKCSTADDR_v8]](%rip), %ymm0, %ymm0 --; AVX-NEXT: vaddps %ymm1, %ymm0, %ymm0 -+; AVX-NEXT: vaddps %ymm0, %ymm1, %ymm0 - ; AVX-NEXT: retq - ; - ; AVX2-LABEL: test_uitofp_v8i32_to_v8f32: --- -2.11.0 - diff --git a/deps/patches/llvm-PR278321.patch b/deps/patches/llvm-PR278321.patch deleted file mode 100644 index 709436536f01a..0000000000000 --- a/deps/patches/llvm-PR278321.patch +++ /dev/null @@ -1,1409 +0,0 @@ -From a4ec9b3d6c2c53eb463284db0aa54158fad32701 Mon Sep 17 00:00:00 2001 -From: Marina Yatsina -Date: Thu, 11 Aug 2016 07:32:08 +0000 -Subject: [PATCH 4/5] Avoid false dependencies of undef machine operands - -This patch helps avoid false dependencies on undef registers by updating the machine instructions' undef operand to use a register that the instruction is truly dependent on, or use a register with clearance higher than Pref. - -Pseudo example: - -loop: -xmm0 = ... -xmm1 = vcvtsi2sdl eax, xmm0 -... = inst xmm0 -jmp loop - -In this example, selecting xmm0 as the undef register creates false dependency between loop iterations. -This false dependency cannot be solved by inserting an xor before vcvtsi2sdl because xmm0 is alive at the point of the vcvtsi2sdl instruction. -Selecting a different register instead of xmm0, especially a register that is not used in the loop, will eliminate this problem. - -Differential Revision: https://reviews.llvm.org/D22466 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278321 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/CodeGen/ExecutionDepsFix.cpp | 53 ++++ - lib/Target/X86/X86InstrInfo.cpp | 2 +- - test/CodeGen/X86/break-false-dep.ll | 72 ++++- - test/CodeGen/X86/copy-propagation.ll | 3 +- - test/CodeGen/X86/half.ll | 2 +- - test/CodeGen/X86/vec_int_to_fp.ll | 579 ++++++++++++++++++++--------------- - 6 files changed, 467 insertions(+), 244 deletions(-) - -diff --git a/lib/CodeGen/ExecutionDepsFix.cpp b/lib/CodeGen/ExecutionDepsFix.cpp -index 1fe5f459b69..5f91db9251c 100644 ---- a/lib/CodeGen/ExecutionDepsFix.cpp -+++ b/lib/CodeGen/ExecutionDepsFix.cpp -@@ -203,6 +203,8 @@ private: - void processDefs(MachineInstr*, bool Kill); - void visitSoftInstr(MachineInstr*, unsigned mask); - void visitHardInstr(MachineInstr*, unsigned domain); -+ void pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, -+ unsigned Pref); - bool shouldBreakDependence(MachineInstr*, unsigned OpIdx, unsigned Pref); - void processUndefReads(MachineBasicBlock*); - }; -@@ -473,6 +475,56 @@ void ExeDepsFix::visitInstr(MachineInstr *MI) { - processDefs(MI, !DomP.first); - } - -+/// \brief Helps avoid false dependencies on undef registers by updating the -+/// machine instructions' undef operand to use a register that the instruction -+/// is truly dependent on, or use a register with clearance higher than Pref. -+void ExeDepsFix::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, -+ unsigned Pref) { -+ MachineOperand &MO = MI->getOperand(OpIdx); -+ assert(MO.isUndef() && "Expected undef machine operand"); -+ -+ unsigned OriginalReg = MO.getReg(); -+ -+ // Update only undef operands that are mapped to one register. -+ if (AliasMap[OriginalReg].size() != 1) -+ return; -+ -+ // Get the undef operand's register class -+ const TargetRegisterClass *OpRC = -+ TII->getRegClass(MI->getDesc(), OpIdx, TRI, *MF); -+ -+ // If the instruction has a true dependency, we can hide the false depdency -+ // behind it. -+ for (MachineOperand &CurrMO : MI->operands()) { -+ if (!CurrMO.isReg() || CurrMO.isDef() || CurrMO.isUndef() || -+ !OpRC->contains(CurrMO.getReg())) -+ continue; -+ // We found a true dependency - replace the undef register with the true -+ // dependency. -+ MO.setReg(CurrMO.getReg()); -+ return; -+ } -+ -+ // Go over all registers in the register class and find the register with -+ // max clearance or clearance higher than Pref. -+ unsigned MaxClearance = 0; -+ unsigned MaxClearanceReg = OriginalReg; -+ for (unsigned rx = 0; rx < OpRC->getNumRegs(); ++rx) { -+ unsigned Clearance = CurInstr - LiveRegs[rx].Def; -+ if (Clearance <= MaxClearance) -+ continue; -+ MaxClearance = Clearance; -+ MaxClearanceReg = OpRC->getRegister(rx); -+ -+ if (MaxClearance > Pref) -+ break; -+ } -+ -+ // Update the operand if we found a register with better clearance. -+ if (MaxClearanceReg != OriginalReg) -+ MO.setReg(MaxClearanceReg); -+} -+ - /// \brief Return true to if it makes sense to break dependence on a partial def - /// or undef use. - bool ExeDepsFix::shouldBreakDependence(MachineInstr *MI, unsigned OpIdx, -@@ -510,6 +562,7 @@ void ExeDepsFix::processDefs(MachineInstr *MI, bool Kill) { - unsigned OpNum; - unsigned Pref = TII->getUndefRegClearance(*MI, OpNum, TRI); - if (Pref) { -+ pickBestRegisterForUndef(MI, OpNum, Pref); - if (shouldBreakDependence(MI, OpNum, Pref)) - UndefReads.push_back(std::make_pair(MI, OpNum)); - } -diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp -index 5f0aab9ddc6..9bfe25973ae 100644 ---- a/lib/Target/X86/X86InstrInfo.cpp -+++ b/lib/Target/X86/X86InstrInfo.cpp -@@ -68,7 +68,7 @@ static cl::opt - UndefRegClearance("undef-reg-clearance", - cl::desc("How many idle instructions we would like before " - "certain undef register reads"), -- cl::init(64), cl::Hidden); -+ cl::init(128), cl::Hidden); - - enum { - // Select which memory operand is being unfolded. -diff --git a/test/CodeGen/X86/break-false-dep.ll b/test/CodeGen/X86/break-false-dep.ll -index a7cda499dab..4c5e747f9ca 100644 ---- a/test/CodeGen/X86/break-false-dep.ll -+++ b/test/CodeGen/X86/break-false-dep.ll -@@ -126,6 +126,7 @@ loop: - %i = phi i64 [ 1, %entry ], [ %inc, %loop ] - %s1 = phi i64 [ %vx, %entry ], [ %s2, %loop ] - %fi = sitofp i64 %i to double -+ tail call void asm sideeffect "", "~{xmm0},~{xmm1},~{xmm2},~{xmm3},~{xmm4},~{xmm5},~{xmm6},~{xmm7},~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{xmm12},~{xmm13},~{xmm14},~{xmm15},~{dirflag},~{fpsr},~{flags}"() - %vy = load double, double* %y - %fipy = fadd double %fi, %vy - %iipy = fptosi double %fipy to i64 -@@ -174,6 +175,7 @@ for.body3: - store double %mul11, double* %arrayidx13, align 8 - %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 - %exitcond = icmp eq i64 %indvars.iv.next, 1024 -+ tail call void asm sideeffect "", "~{xmm0},~{xmm1},~{xmm2},~{xmm3},~{xmm4},~{xmm5},~{xmm6},~{xmm7},~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{xmm12},~{xmm13},~{xmm14},~{xmm15},~{dirflag},~{fpsr},~{flags}"() - br i1 %exitcond, label %for.inc14, label %for.body3 - - for.inc14: ; preds = %for.body3 -@@ -193,7 +195,7 @@ for.end16: ; preds = %for.inc14 - ;SSE-NEXT: movsd [[XMM0]], - ;AVX-LABEL:@loopdep3 - ;AVX: vxorps [[XMM0:%xmm[0-9]+]], [[XMM0]] --;AVX-NEXT: vcvtsi2sdl {{.*}}, [[XMM0]], [[XMM0]] -+;AVX-NEXT: vcvtsi2sdl {{.*}}, [[XMM0]], {{%xmm[0-9]+}} - ;AVX-NEXT: vmulsd {{.*}}, [[XMM0]], [[XMM0]] - ;AVX-NEXT: vmulsd {{.*}}, [[XMM0]], [[XMM0]] - ;AVX-NEXT: vmulsd {{.*}}, [[XMM0]], [[XMM0]] -@@ -202,10 +204,76 @@ for.end16: ; preds = %for.inc14 - - define double @inlineasmdep(i64 %arg) { - top: -- tail call void asm sideeffect "", "~{xmm0},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm0},~{xmm1},~{xmm2},~{xmm3},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm4},~{xmm5},~{xmm6},~{xmm7},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm12},~{xmm13},~{xmm14},~{xmm15},~{dirflag},~{fpsr},~{flags}"() - %tmp1 = sitofp i64 %arg to double - ret double %tmp1 - ;AVX-LABEL:@inlineasmdep - ;AVX: vxorps [[XMM0:%xmm[0-9]+]], [[XMM0]], [[XMM0]] - ;AVX-NEXT: vcvtsi2sdq {{.*}}, [[XMM0]], {{%xmm[0-9]+}} - } -+ -+; Make sure we are making a smart choice regarding undef registers and -+; hiding the false dependency behind a true dependency -+define double @truedeps(float %arg) { -+top: -+ tail call void asm sideeffect "", "~{xmm6},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm0},~{xmm1},~{xmm2},~{xmm3},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm4},~{xmm5},~{xmm7},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm12},~{xmm13},~{xmm14},~{xmm15},~{dirflag},~{fpsr},~{flags}"() -+ %tmp1 = fpext float %arg to double -+ ret double %tmp1 -+;AVX-LABEL:@truedeps -+;AVX-NOT: vxorps -+;AVX: vcvtss2sd [[XMM0:%xmm[0-9]+]], [[XMM0]], {{%xmm[0-9]+}} -+} -+ -+; Make sure we are making a smart choice regarding undef registers and -+; choosing the register with the highest clearence -+define double @clearence(i64 %arg) { -+top: -+ tail call void asm sideeffect "", "~{xmm6},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm0},~{xmm1},~{xmm2},~{xmm3},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm4},~{xmm5},~{xmm7},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm12},~{xmm13},~{xmm14},~{xmm15},~{dirflag},~{fpsr},~{flags}"() -+ %tmp1 = sitofp i64 %arg to double -+ ret double %tmp1 -+;AVX-LABEL:@clearence -+;AVX: vxorps [[XMM6:%xmm6]], [[XMM6]], [[XMM6]] -+;AVX-NEXT: vcvtsi2sdq {{.*}}, [[XMM6]], {{%xmm[0-9]+}} -+} -+ -+; Make sure we are making a smart choice regarding undef registers in order to -+; avoid a cyclic dependence on a write to the same register in a previous -+; iteration, especially when we cannot zero out the undef register because it -+; is alive. -+define i64 @loopclearence(i64* nocapture %x, double* nocapture %y) nounwind { -+entry: -+ %vx = load i64, i64* %x -+ br label %loop -+loop: -+ %i = phi i64 [ 1, %entry ], [ %inc, %loop ] -+ %s1 = phi i64 [ %vx, %entry ], [ %s2, %loop ] -+ %fi = sitofp i64 %i to double -+ tail call void asm sideeffect "", "~{xmm0},~{xmm1},~{xmm2},~{xmm3},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm12},~{xmm13},~{xmm14},~{xmm15},~{dirflag},~{fpsr},~{flags}"() -+ %vy = load double, double* %y -+ %fipy = fadd double %fi, %vy -+ %iipy = fptosi double %fipy to i64 -+ %s2 = add i64 %s1, %iipy -+ %inc = add nsw i64 %i, 1 -+ %exitcond = icmp eq i64 %inc, 156250000 -+ br i1 %exitcond, label %ret, label %loop -+ret: -+ ret i64 %s2 -+;AVX-LABEL:@loopclearence -+;Registers 4-7 are not used and therefore one of them should be chosen -+;AVX-NOT: {{%xmm[4-7]}} -+;AVX: vcvtsi2sdq {{.*}}, [[XMM4_7:%xmm[4-7]]], {{%xmm[0-9]+}} -+;AVX-NOT: [[XMM4_7]] -+} -diff --git a/test/CodeGen/X86/copy-propagation.ll b/test/CodeGen/X86/copy-propagation.ll -index 19421a06fa8..dac46c17382 100644 ---- a/test/CodeGen/X86/copy-propagation.ll -+++ b/test/CodeGen/X86/copy-propagation.ll -@@ -26,7 +26,7 @@ target triple = "x86_64-pc-win32-elf" - ; Copy the result in a temporary. - ; Note: Technically the regalloc could have been smarter and this move not required, - ; which would have hidden the bug. --; CHECK-NEXT: vmovapd %xmm0, [[TMP:%xmm[0-9]+]] -+; CHECK: vmovapd %xmm0, [[TMP:%xmm[0-9]+]] - ; Crush xmm0. - ; CHECK-NEXT: vxorps %xmm0, %xmm0, %xmm0 - ; CHECK: movl $339772768, %e[[INDIRECT_CALL2:[a-z]+]] -@@ -37,6 +37,7 @@ target triple = "x86_64-pc-win32-elf" - define double @foo(i64 %arg) { - top: - %tmp = call double inttoptr (i64 339752784 to double (double, double)*)(double 1.000000e+00, double 0.000000e+00) -+ tail call void asm sideeffect "", "x,~{xmm1},~{xmm2},~{xmm3},~{xmm4},~{xmm5},~{xmm6},~{xmm7},~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{xmm12},~{xmm13},~{xmm14},~{xmm15},~{dirflag},~{fpsr},~{flags}"(double %tmp) - %tmp1 = sitofp i64 %arg to double - call void inttoptr (i64 339772768 to void (double, double)*)(double %tmp, double %tmp1) - %tmp3 = fadd double %tmp1, %tmp -diff --git a/test/CodeGen/X86/half.ll b/test/CodeGen/X86/half.ll -index 717ddbfa6fd..739bb146e3a 100644 ---- a/test/CodeGen/X86/half.ll -+++ b/test/CodeGen/X86/half.ll -@@ -299,7 +299,7 @@ define half @test_f80trunc_nodagcombine() #0 { - ; CHECK-F16C-NEXT: movswl (%rsi), %eax - ; CHECK-F16C-NEXT: vmovd %eax, %xmm0 - ; CHECK-F16C-NEXT: vcvtph2ps %xmm0, %xmm0 --; CHECK-F16C-NEXT: vcvtsi2ssl %edi, %xmm0, %xmm1 -+; CHECK-F16C-NEXT: vcvtsi2ssl %edi, %xmm1, %xmm1 - ; CHECK-F16C-NEXT: vcvtps2ph $4, %xmm1, %xmm1 - ; CHECK-F16C-NEXT: vcvtph2ps %xmm1, %xmm1 - ; CHECK-F16C-NEXT: vaddss %xmm1, %xmm0, %xmm0 -diff --git a/test/CodeGen/X86/vec_int_to_fp.ll b/test/CodeGen/X86/vec_int_to_fp.ll -index 8ea7243664a..bb0a93dc848 100644 ---- a/test/CodeGen/X86/vec_int_to_fp.ll -+++ b/test/CodeGen/X86/vec_int_to_fp.ll -@@ -27,10 +27,9 @@ define <2 x double> @sitofp_2i64_to_2f64(<2 x i64> %a) { - ; AVX-LABEL: sitofp_2i64_to_2f64: - ; AVX: # BB#0: - ; AVX-NEXT: vpextrq $1, %xmm0, %rax --; AVX-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm1 -+; AVX-NEXT: vcvtsi2sdq %rax, %xmm1, %xmm1 - ; AVX-NEXT: vmovq %xmm0, %rax --; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm0 -+; AVX-NEXT: vcvtsi2sdq %rax, %xmm2, %xmm0 - ; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] - ; AVX-NEXT: retq - %cvt = sitofp <2 x i64> %a to <2 x double> -@@ -188,15 +187,14 @@ define <4 x double> @sitofp_4i64_to_4f64(<4 x i64> %a) { - ; AVX1: # BB#0: - ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 - ; AVX1-NEXT: vpextrq $1, %xmm1, %rax --; AVX1-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2sdq %rax, %xmm2, %xmm2 - ; AVX1-NEXT: vmovq %xmm1, %rax --; AVX1-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm1 -+; AVX1-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm1 - ; AVX1-NEXT: vunpcklpd {{.*#+}} xmm1 = xmm1[0],xmm2[0] - ; AVX1-NEXT: vpextrq $1, %xmm0, %rax --; AVX1-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm2 - ; AVX1-NEXT: vmovq %xmm0, %rax --; AVX1-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX1-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm0 -+; AVX1-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm0 - ; AVX1-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm2[0] - ; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 - ; AVX1-NEXT: retq -@@ -205,18 +203,33 @@ define <4 x double> @sitofp_4i64_to_4f64(<4 x i64> %a) { - ; AVX2: # BB#0: - ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 - ; AVX2-NEXT: vpextrq $1, %xmm1, %rax --; AVX2-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2sdq %rax, %xmm2, %xmm2 - ; AVX2-NEXT: vmovq %xmm1, %rax --; AVX2-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm1 -+; AVX2-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm1 - ; AVX2-NEXT: vunpcklpd {{.*#+}} xmm1 = xmm1[0],xmm2[0] - ; AVX2-NEXT: vpextrq $1, %xmm0, %rax --; AVX2-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm2 - ; AVX2-NEXT: vmovq %xmm0, %rax --; AVX2-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX2-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm0 -+; AVX2-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm0 - ; AVX2-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm2[0] - ; AVX2-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 - ; AVX2-NEXT: retq -+; -+; AVX512-LABEL: sitofp_4i64_to_4f64: -+; AVX512: # BB#0: -+; AVX512-NEXT: vextracti32x4 $1, %ymm0, %xmm1 -+; AVX512-NEXT: vpextrq $1, %xmm1, %rax -+; AVX512-NEXT: vcvtsi2sdq %rax, %xmm2, %xmm2 -+; AVX512-NEXT: vmovq %xmm1, %rax -+; AVX512-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm1 -+; AVX512-NEXT: vunpcklpd {{.*#+}} xmm1 = xmm1[0],xmm2[0] -+; AVX512-NEXT: vpextrq $1, %xmm0, %rax -+; AVX512-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm2 -+; AVX512-NEXT: vmovq %xmm0, %rax -+; AVX512-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm0 -+; AVX512-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm2[0] -+; AVX512-NEXT: vinsertf32x4 $1, %xmm1, %ymm0, %ymm0 -+; AVX512-NEXT: retq - %cvt = sitofp <4 x i64> %a to <4 x double> - ret <4 x double> %cvt - } -@@ -803,12 +816,11 @@ define <4 x float> @sitofp_2i64_to_4f32(<2 x i64> %a) { - ; AVX-LABEL: sitofp_2i64_to_4f32: - ; AVX: # BB#0: - ; AVX-NEXT: vpextrq $1, %xmm0, %rax --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX-NEXT: vmovq %xmm0, %rax --; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm0 - ; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[2,3] --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm1 - ; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] - ; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] - ; AVX-NEXT: retq -@@ -836,12 +848,11 @@ define <4 x float> @sitofp_4i64_to_4f32_undef(<2 x i64> %a) { - ; AVX-LABEL: sitofp_4i64_to_4f32_undef: - ; AVX: # BB#0: - ; AVX-NEXT: vpextrq $1, %xmm0, %rax --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX-NEXT: vmovq %xmm0, %rax --; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm0 - ; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[2,3] --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm1 - ; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] - ; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] - ; AVX-NEXT: retq -@@ -988,17 +999,16 @@ define <4 x float> @sitofp_4i64_to_4f32(<4 x i64> %a) { - ; AVX1-LABEL: sitofp_4i64_to_4f32: - ; AVX1: # BB#0: - ; AVX1-NEXT: vpextrq $1, %xmm0, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX1-NEXT: vmovq %xmm0, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0],xmm1[0],xmm2[2,3] - ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 - ; AVX1-NEXT: vmovq %xmm0, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm2 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm2[0],xmm1[3] - ; AVX1-NEXT: vpextrq $1, %xmm0, %rax --; AVX1-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm0 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX1-NEXT: vzeroupper - ; AVX1-NEXT: retq -@@ -1006,20 +1016,35 @@ define <4 x float> @sitofp_4i64_to_4f32(<4 x i64> %a) { - ; AVX2-LABEL: sitofp_4i64_to_4f32: - ; AVX2: # BB#0: - ; AVX2-NEXT: vpextrq $1, %xmm0, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX2-NEXT: vmovq %xmm0, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0],xmm1[0],xmm2[2,3] - ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 - ; AVX2-NEXT: vmovq %xmm0, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm2 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm2[0],xmm1[3] - ; AVX2-NEXT: vpextrq $1, %xmm0, %rax --; AVX2-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm0 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX2-NEXT: vzeroupper - ; AVX2-NEXT: retq -+; -+; AVX512-LABEL: sitofp_4i64_to_4f32: -+; AVX512: # BB#0: -+; AVX512-NEXT: vpextrq $1, %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 -+; AVX512-NEXT: vmovq %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0],xmm1[0],xmm2[2,3] -+; AVX512-NEXT: vextracti32x4 $1, %ymm0, %xmm0 -+; AVX512-NEXT: vmovq %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm2 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm2[0],xmm1[3] -+; AVX512-NEXT: vpextrq $1, %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm0 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] -+; AVX512-NEXT: retq - %cvt = sitofp <4 x i64> %a to <4 x float> - ret <4 x float> %cvt - } -@@ -1181,48 +1206,58 @@ define <4 x float> @uitofp_2i64_to_4f32(<2 x i64> %a) { - ; SSE-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] - ; SSE-NEXT: retq - ; --; AVX-LABEL: uitofp_2i64_to_4f32: --; AVX: # BB#0: --; AVX-NEXT: vpextrq $1, %xmm0, %rax --; AVX-NEXT: movl %eax, %ecx --; AVX-NEXT: andl $1, %ecx --; AVX-NEXT: testq %rax, %rax --; AVX-NEXT: js .LBB38_1 --; AVX-NEXT: # BB#2: --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 --; AVX-NEXT: jmp .LBB38_3 --; AVX-NEXT: .LBB38_1: --; AVX-NEXT: shrq %rax --; AVX-NEXT: orq %rax, %rcx --; AVX-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm1 --; AVX-NEXT: vaddss %xmm1, %xmm1, %xmm1 --; AVX-NEXT: .LBB38_3: --; AVX-NEXT: vmovq %xmm0, %rax --; AVX-NEXT: movl %eax, %ecx --; AVX-NEXT: andl $1, %ecx --; AVX-NEXT: testq %rax, %rax --; AVX-NEXT: js .LBB38_4 --; AVX-NEXT: # BB#5: --; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 --; AVX-NEXT: jmp .LBB38_6 --; AVX-NEXT: .LBB38_4: --; AVX-NEXT: shrq %rax --; AVX-NEXT: orq %rax, %rcx --; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm0 --; AVX-NEXT: vaddss %xmm0, %xmm0, %xmm0 --; AVX-NEXT: .LBB38_6: --; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[2,3] --; AVX-NEXT: vxorps %xmm1, %xmm1, %xmm1 --; AVX-NEXT: testq %rax, %rax --; AVX-NEXT: js .LBB38_8 --; AVX-NEXT: # BB#7: --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 --; AVX-NEXT: .LBB38_8: --; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] --; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] --; AVX-NEXT: retq -+; AVX1-LABEL: uitofp_2i64_to_4f32: -+; AVX1: # BB#0: -+; AVX1-NEXT: vpextrq $1, %xmm0, %rax -+; AVX1-NEXT: movl %eax, %ecx -+; AVX1-NEXT: andl $1, %ecx -+; AVX1-NEXT: testq %rax, %rax -+; AVX1-NEXT: js .LBB38_1 -+; AVX1-NEXT: # BB#2: -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 -+; AVX1-NEXT: jmp .LBB38_3 -+; AVX1-NEXT: .LBB38_1: -+; AVX1-NEXT: shrq %rax -+; AVX1-NEXT: orq %rax, %rcx -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm1, %xmm1 -+; AVX1-NEXT: vaddss %xmm1, %xmm1, %xmm1 -+; AVX1-NEXT: .LBB38_3: -+; AVX1-NEXT: vmovq %xmm0, %rax -+; AVX1-NEXT: movl %eax, %ecx -+; AVX1-NEXT: andl $1, %ecx -+; AVX1-NEXT: testq %rax, %rax -+; AVX1-NEXT: js .LBB38_4 -+; AVX1-NEXT: # BB#5: -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm0 -+; AVX1-NEXT: jmp .LBB38_6 -+; AVX1-NEXT: .LBB38_4: -+; AVX1-NEXT: shrq %rax -+; AVX1-NEXT: orq %rax, %rcx -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm2, %xmm0 -+; AVX1-NEXT: vaddss %xmm0, %xmm0, %xmm0 -+; AVX1-NEXT: .LBB38_6: -+; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[2,3] -+; AVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1 -+; AVX1-NEXT: testq %rax, %rax -+; AVX1-NEXT: js .LBB38_8 -+; AVX1-NEXT: # BB#7: -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm1 -+; AVX1-NEXT: .LBB38_8: -+; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] -+; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] -+; AVX1-NEXT: retq -+; -+; AVX512-LABEL: uitofp_2i64_to_4f32: -+; AVX512: # BB#0: -+; AVX512-NEXT: vpextrq $1, %xmm0, %rax -+; AVX512-NEXT: vcvtusi2ssq %rax, %xmm0, %xmm1 -+; AVX512-NEXT: vmovq %xmm0, %rax -+; AVX512-NEXT: vcvtusi2ssq %rax, %xmm0, %xmm0 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[2,3] -+; AVX512-NEXT: vcvtusi2ssq %rax, %xmm0, %xmm1 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] -+; AVX512-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] -+; AVX512-NEXT: retq - %cvt = uitofp <2 x i64> %a to <2 x float> - %ext = shufflevector <2 x float> %cvt, <2 x float> undef, <4 x i32> - ret <4 x float> %ext -@@ -1277,48 +1312,58 @@ define <4 x float> @uitofp_4i64_to_4f32_undef(<2 x i64> %a) { - ; SSE-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] - ; SSE-NEXT: retq - ; --; AVX-LABEL: uitofp_4i64_to_4f32_undef: --; AVX: # BB#0: --; AVX-NEXT: vpextrq $1, %xmm0, %rax --; AVX-NEXT: movl %eax, %ecx --; AVX-NEXT: andl $1, %ecx --; AVX-NEXT: testq %rax, %rax --; AVX-NEXT: js .LBB39_1 --; AVX-NEXT: # BB#2: --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 --; AVX-NEXT: jmp .LBB39_3 --; AVX-NEXT: .LBB39_1: --; AVX-NEXT: shrq %rax --; AVX-NEXT: orq %rax, %rcx --; AVX-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm1 --; AVX-NEXT: vaddss %xmm1, %xmm1, %xmm1 --; AVX-NEXT: .LBB39_3: --; AVX-NEXT: vmovq %xmm0, %rax --; AVX-NEXT: movl %eax, %ecx --; AVX-NEXT: andl $1, %ecx --; AVX-NEXT: testq %rax, %rax --; AVX-NEXT: js .LBB39_4 --; AVX-NEXT: # BB#5: --; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 --; AVX-NEXT: jmp .LBB39_6 --; AVX-NEXT: .LBB39_4: --; AVX-NEXT: shrq %rax --; AVX-NEXT: orq %rax, %rcx --; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm0 --; AVX-NEXT: vaddss %xmm0, %xmm0, %xmm0 --; AVX-NEXT: .LBB39_6: --; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[2,3] --; AVX-NEXT: vxorps %xmm1, %xmm1, %xmm1 --; AVX-NEXT: testq %rax, %rax --; AVX-NEXT: js .LBB39_8 --; AVX-NEXT: # BB#7: --; AVX-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 --; AVX-NEXT: .LBB39_8: --; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] --; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] --; AVX-NEXT: retq -+; AVX1-LABEL: uitofp_4i64_to_4f32_undef: -+; AVX1: # BB#0: -+; AVX1-NEXT: vpextrq $1, %xmm0, %rax -+; AVX1-NEXT: movl %eax, %ecx -+; AVX1-NEXT: andl $1, %ecx -+; AVX1-NEXT: testq %rax, %rax -+; AVX1-NEXT: js .LBB39_1 -+; AVX1-NEXT: # BB#2: -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 -+; AVX1-NEXT: jmp .LBB39_3 -+; AVX1-NEXT: .LBB39_1: -+; AVX1-NEXT: shrq %rax -+; AVX1-NEXT: orq %rax, %rcx -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm1, %xmm1 -+; AVX1-NEXT: vaddss %xmm1, %xmm1, %xmm1 -+; AVX1-NEXT: .LBB39_3: -+; AVX1-NEXT: vmovq %xmm0, %rax -+; AVX1-NEXT: movl %eax, %ecx -+; AVX1-NEXT: andl $1, %ecx -+; AVX1-NEXT: testq %rax, %rax -+; AVX1-NEXT: js .LBB39_4 -+; AVX1-NEXT: # BB#5: -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm0 -+; AVX1-NEXT: jmp .LBB39_6 -+; AVX1-NEXT: .LBB39_4: -+; AVX1-NEXT: shrq %rax -+; AVX1-NEXT: orq %rax, %rcx -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm2, %xmm0 -+; AVX1-NEXT: vaddss %xmm0, %xmm0, %xmm0 -+; AVX1-NEXT: .LBB39_6: -+; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[2,3] -+; AVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1 -+; AVX1-NEXT: testq %rax, %rax -+; AVX1-NEXT: js .LBB39_8 -+; AVX1-NEXT: # BB#7: -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm1 -+; AVX1-NEXT: .LBB39_8: -+; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] -+; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] -+; AVX1-NEXT: retq -+; -+; AVX512-LABEL: uitofp_4i64_to_4f32_undef: -+; AVX512: # BB#0: -+; AVX512-NEXT: vpextrq $1, %xmm0, %rax -+; AVX512-NEXT: vcvtusi2ssq %rax, %xmm0, %xmm1 -+; AVX512-NEXT: vmovq %xmm0, %rax -+; AVX512-NEXT: vcvtusi2ssq %rax, %xmm0, %xmm0 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[2,3] -+; AVX512-NEXT: vcvtusi2ssq %rax, %xmm0, %xmm1 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] -+; AVX512-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] -+; AVX512-NEXT: retq - %ext = shufflevector <2 x i64> %a, <2 x i64> undef, <4 x i32> - %cvt = uitofp <4 x i64> %ext to <4 x float> - ret <4 x float> %cvt -@@ -1539,12 +1584,12 @@ define <4 x float> @uitofp_4i64_to_4f32(<4 x i64> %a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB45_1 - ; AVX1-NEXT: # BB#2: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX1-NEXT: jmp .LBB45_3 - ; AVX1-NEXT: .LBB45_1: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm1 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm1, %xmm1 - ; AVX1-NEXT: vaddss %xmm1, %xmm1, %xmm1 - ; AVX1-NEXT: .LBB45_3: - ; AVX1-NEXT: vmovq %xmm0, %rax -@@ -1553,12 +1598,12 @@ define <4 x float> @uitofp_4i64_to_4f32(<4 x i64> %a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB45_4 - ; AVX1-NEXT: # BB#5: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 - ; AVX1-NEXT: jmp .LBB45_6 - ; AVX1-NEXT: .LBB45_4: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm2, %xmm2 - ; AVX1-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX1-NEXT: .LBB45_6: - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0],xmm1[0],xmm2[2,3] -@@ -1569,12 +1614,12 @@ define <4 x float> @uitofp_4i64_to_4f32(<4 x i64> %a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB45_7 - ; AVX1-NEXT: # BB#8: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm2 - ; AVX1-NEXT: jmp .LBB45_9 - ; AVX1-NEXT: .LBB45_7: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm3, %xmm2 - ; AVX1-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX1-NEXT: .LBB45_9: - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm2[0],xmm1[3] -@@ -1584,16 +1629,14 @@ define <4 x float> @uitofp_4i64_to_4f32(<4 x i64> %a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB45_10 - ; AVX1-NEXT: # BB#11: --; AVX1-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm0 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX1-NEXT: vzeroupper - ; AVX1-NEXT: retq - ; AVX1-NEXT: .LBB45_10: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm0 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm3, %xmm0 - ; AVX1-NEXT: vaddss %xmm0, %xmm0, %xmm0 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX1-NEXT: vzeroupper -@@ -1607,12 +1650,12 @@ define <4 x float> @uitofp_4i64_to_4f32(<4 x i64> %a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB45_1 - ; AVX2-NEXT: # BB#2: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX2-NEXT: jmp .LBB45_3 - ; AVX2-NEXT: .LBB45_1: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm1 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm1, %xmm1 - ; AVX2-NEXT: vaddss %xmm1, %xmm1, %xmm1 - ; AVX2-NEXT: .LBB45_3: - ; AVX2-NEXT: vmovq %xmm0, %rax -@@ -1621,12 +1664,12 @@ define <4 x float> @uitofp_4i64_to_4f32(<4 x i64> %a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB45_4 - ; AVX2-NEXT: # BB#5: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 - ; AVX2-NEXT: jmp .LBB45_6 - ; AVX2-NEXT: .LBB45_4: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm2, %xmm2 - ; AVX2-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX2-NEXT: .LBB45_6: - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0],xmm1[0],xmm2[2,3] -@@ -1637,12 +1680,12 @@ define <4 x float> @uitofp_4i64_to_4f32(<4 x i64> %a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB45_7 - ; AVX2-NEXT: # BB#8: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm2 - ; AVX2-NEXT: jmp .LBB45_9 - ; AVX2-NEXT: .LBB45_7: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm3, %xmm2 - ; AVX2-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX2-NEXT: .LBB45_9: - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm2[0],xmm1[3] -@@ -1652,16 +1695,14 @@ define <4 x float> @uitofp_4i64_to_4f32(<4 x i64> %a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB45_10 - ; AVX2-NEXT: # BB#11: --; AVX2-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm0 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX2-NEXT: vzeroupper - ; AVX2-NEXT: retq - ; AVX2-NEXT: .LBB45_10: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm0 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm3, %xmm0 - ; AVX2-NEXT: vaddss %xmm0, %xmm0, %xmm0 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX2-NEXT: vzeroupper -@@ -1831,16 +1872,25 @@ define <2 x double> @sitofp_load_2i64_to_2f64(<2 x i64> *%a) { - ; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] - ; SSE-NEXT: retq - ; --; AVX-LABEL: sitofp_load_2i64_to_2f64: --; AVX: # BB#0: --; AVX-NEXT: vmovdqa (%rdi), %xmm0 --; AVX-NEXT: vpextrq $1, %xmm0, %rax --; AVX-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm1 --; AVX-NEXT: vmovq %xmm0, %rax --; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm0 --; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] --; AVX-NEXT: retq -+; AVX1-LABEL: sitofp_load_2i64_to_2f64: -+; AVX1: # BB#0: -+; AVX1-NEXT: vmovdqa (%rdi), %xmm0 -+; AVX1-NEXT: vpextrq $1, %xmm0, %rax -+; AVX1-NEXT: vcvtsi2sdq %rax, %xmm1, %xmm1 -+; AVX1-NEXT: vmovq %xmm0, %rax -+; AVX1-NEXT: vcvtsi2sdq %rax, %xmm2, %xmm0 -+; AVX1-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] -+; AVX1-NEXT: retq -+; -+; AVX512-LABEL: sitofp_load_2i64_to_2f64: -+; AVX512: # BB#0: -+; AVX512-NEXT: vmovdqa64 (%rdi), %xmm0 -+; AVX512-NEXT: vpextrq $1, %xmm0, %rax -+; AVX512-NEXT: vcvtsi2sdq %rax, %xmm1, %xmm1 -+; AVX512-NEXT: vmovq %xmm0, %rax -+; AVX512-NEXT: vcvtsi2sdq %rax, %xmm2, %xmm0 -+; AVX512-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] -+; AVX512-NEXT: retq - %ld = load <2 x i64>, <2 x i64> *%a - %cvt = sitofp <2 x i64> %ld to <2 x double> - ret <2 x double> %cvt -@@ -1930,15 +1980,14 @@ define <4 x double> @sitofp_load_4i64_to_4f64(<4 x i64> *%a) { - ; AVX1-NEXT: vmovaps (%rdi), %ymm0 - ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 - ; AVX1-NEXT: vpextrq $1, %xmm1, %rax --; AVX1-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2sdq %rax, %xmm2, %xmm2 - ; AVX1-NEXT: vmovq %xmm1, %rax --; AVX1-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm1 -+; AVX1-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm1 - ; AVX1-NEXT: vunpcklpd {{.*#+}} xmm1 = xmm1[0],xmm2[0] - ; AVX1-NEXT: vpextrq $1, %xmm0, %rax --; AVX1-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm2 - ; AVX1-NEXT: vmovq %xmm0, %rax --; AVX1-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX1-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm0 -+; AVX1-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm0 - ; AVX1-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm2[0] - ; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 - ; AVX1-NEXT: retq -@@ -1948,18 +1997,34 @@ define <4 x double> @sitofp_load_4i64_to_4f64(<4 x i64> *%a) { - ; AVX2-NEXT: vmovdqa (%rdi), %ymm0 - ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 - ; AVX2-NEXT: vpextrq $1, %xmm1, %rax --; AVX2-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2sdq %rax, %xmm2, %xmm2 - ; AVX2-NEXT: vmovq %xmm1, %rax --; AVX2-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm1 -+; AVX2-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm1 - ; AVX2-NEXT: vunpcklpd {{.*#+}} xmm1 = xmm1[0],xmm2[0] - ; AVX2-NEXT: vpextrq $1, %xmm0, %rax --; AVX2-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm2 - ; AVX2-NEXT: vmovq %xmm0, %rax --; AVX2-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX2-NEXT: vcvtsi2sdq %rax, %xmm0, %xmm0 -+; AVX2-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm0 - ; AVX2-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm2[0] - ; AVX2-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 - ; AVX2-NEXT: retq -+; -+; AVX512-LABEL: sitofp_load_4i64_to_4f64: -+; AVX512: # BB#0: -+; AVX512-NEXT: vmovdqa64 (%rdi), %ymm0 -+; AVX512-NEXT: vextracti32x4 $1, %ymm0, %xmm1 -+; AVX512-NEXT: vpextrq $1, %xmm1, %rax -+; AVX512-NEXT: vcvtsi2sdq %rax, %xmm2, %xmm2 -+; AVX512-NEXT: vmovq %xmm1, %rax -+; AVX512-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm1 -+; AVX512-NEXT: vunpcklpd {{.*#+}} xmm1 = xmm1[0],xmm2[0] -+; AVX512-NEXT: vpextrq $1, %xmm0, %rax -+; AVX512-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm2 -+; AVX512-NEXT: vmovq %xmm0, %rax -+; AVX512-NEXT: vcvtsi2sdq %rax, %xmm3, %xmm0 -+; AVX512-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm2[0] -+; AVX512-NEXT: vinsertf32x4 $1, %xmm1, %ymm0, %ymm0 -+; AVX512-NEXT: retq - %ld = load <4 x i64>, <4 x i64> *%a - %cvt = sitofp <4 x i64> %ld to <4 x double> - ret <4 x double> %cvt -@@ -2365,17 +2430,16 @@ define <4 x float> @sitofp_load_4i64_to_4f32(<4 x i64> *%a) { - ; AVX1: # BB#0: - ; AVX1-NEXT: vmovdqa (%rdi), %ymm0 - ; AVX1-NEXT: vpextrq $1, %xmm0, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX1-NEXT: vmovq %xmm0, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0],xmm1[0],xmm2[2,3] - ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 - ; AVX1-NEXT: vmovq %xmm0, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm2 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm2[0],xmm1[3] - ; AVX1-NEXT: vpextrq $1, %xmm0, %rax --; AVX1-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm0 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX1-NEXT: vzeroupper - ; AVX1-NEXT: retq -@@ -2384,20 +2448,36 @@ define <4 x float> @sitofp_load_4i64_to_4f32(<4 x i64> *%a) { - ; AVX2: # BB#0: - ; AVX2-NEXT: vmovdqa (%rdi), %ymm0 - ; AVX2-NEXT: vpextrq $1, %xmm0, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX2-NEXT: vmovq %xmm0, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0],xmm1[0],xmm2[2,3] - ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 - ; AVX2-NEXT: vmovq %xmm0, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm2 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm2[0],xmm1[3] - ; AVX2-NEXT: vpextrq $1, %xmm0, %rax --; AVX2-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm0 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX2-NEXT: vzeroupper - ; AVX2-NEXT: retq -+; -+; AVX512-LABEL: sitofp_load_4i64_to_4f32: -+; AVX512: # BB#0: -+; AVX512-NEXT: vmovdqa64 (%rdi), %ymm0 -+; AVX512-NEXT: vpextrq $1, %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 -+; AVX512-NEXT: vmovq %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0],xmm1[0],xmm2[2,3] -+; AVX512-NEXT: vextracti32x4 $1, %ymm0, %xmm0 -+; AVX512-NEXT: vmovq %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm2 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm2[0],xmm1[3] -+; AVX512-NEXT: vpextrq $1, %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm0 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] -+; AVX512-NEXT: retq - %ld = load <4 x i64>, <4 x i64> *%a - %cvt = sitofp <4 x i64> %ld to <4 x float> - ret <4 x float> %cvt -@@ -2503,29 +2583,28 @@ define <8 x float> @sitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX1-NEXT: vmovdqa (%rdi), %ymm0 - ; AVX1-NEXT: vmovdqa 32(%rdi), %ymm1 - ; AVX1-NEXT: vpextrq $1, %xmm1, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 - ; AVX1-NEXT: vmovq %xmm1, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm3 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm2 = xmm3[0],xmm2[0],xmm3[2,3] - ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 - ; AVX1-NEXT: vmovq %xmm1, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm3 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm2 = xmm2[0,1],xmm3[0],xmm2[3] - ; AVX1-NEXT: vpextrq $1, %xmm1, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm1 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0,1,2],xmm1[0] - ; AVX1-NEXT: vpextrq $1, %xmm0, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm2 - ; AVX1-NEXT: vmovq %xmm0, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm3 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm2 = xmm3[0],xmm2[0],xmm3[2,3] - ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 - ; AVX1-NEXT: vmovq %xmm0, %rax --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm3 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm2 = xmm2[0,1],xmm3[0],xmm2[3] - ; AVX1-NEXT: vpextrq $1, %xmm0, %rax --; AVX1-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm0 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[0] - ; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 - ; AVX1-NEXT: retq -@@ -2535,32 +2614,62 @@ define <8 x float> @sitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX2-NEXT: vmovdqa (%rdi), %ymm0 - ; AVX2-NEXT: vmovdqa 32(%rdi), %ymm1 - ; AVX2-NEXT: vpextrq $1, %xmm1, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 - ; AVX2-NEXT: vmovq %xmm1, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm3 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm2 = xmm3[0],xmm2[0],xmm3[2,3] - ; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 - ; AVX2-NEXT: vmovq %xmm1, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm3 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm2 = xmm2[0,1],xmm3[0],xmm2[3] - ; AVX2-NEXT: vpextrq $1, %xmm1, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm1 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0,1,2],xmm1[0] - ; AVX2-NEXT: vpextrq $1, %xmm0, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm2 - ; AVX2-NEXT: vmovq %xmm0, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm3 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm2 = xmm3[0],xmm2[0],xmm3[2,3] - ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 - ; AVX2-NEXT: vmovq %xmm0, %rax --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm3 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm2 = xmm2[0,1],xmm3[0],xmm2[3] - ; AVX2-NEXT: vpextrq $1, %xmm0, %rax --; AVX2-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm0 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[0] - ; AVX2-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 - ; AVX2-NEXT: retq -+; -+; AVX512-LABEL: sitofp_load_8i64_to_8f32: -+; AVX512: # BB#0: -+; AVX512-NEXT: vmovdqa64 (%rdi), %zmm0 -+; AVX512-NEXT: vextracti32x4 $2, %zmm0, %xmm1 -+; AVX512-NEXT: vpextrq $1, %xmm1, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 -+; AVX512-NEXT: vmovq %xmm1, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm1 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[2,3] -+; AVX512-NEXT: vextracti32x4 $3, %zmm0, %xmm2 -+; AVX512-NEXT: vmovq %xmm2, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm3 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm3[0],xmm1[3] -+; AVX512-NEXT: vpextrq $1, %xmm2, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm2 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1,2],xmm2[0] -+; AVX512-NEXT: vpextrq $1, %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm2 -+; AVX512-NEXT: vmovq %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm3 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm2 = xmm3[0],xmm2[0],xmm3[2,3] -+; AVX512-NEXT: vextracti32x4 $1, %zmm0, %xmm0 -+; AVX512-NEXT: vmovq %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm3 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm2 = xmm2[0,1],xmm3[0],xmm2[3] -+; AVX512-NEXT: vpextrq $1, %xmm0, %rax -+; AVX512-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm0 -+; AVX512-NEXT: vinsertps {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[0] -+; AVX512-NEXT: vinsertf32x4 $1, %xmm1, %ymm0, %ymm0 -+; AVX512-NEXT: retq - %ld = load <8 x i64>, <8 x i64> *%a - %cvt = sitofp <8 x i64> %ld to <8 x float> - ret <8 x float> %cvt -@@ -2733,12 +2842,12 @@ define <4 x float> @uitofp_load_4i64_to_4f32(<4 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB74_1 - ; AVX1-NEXT: # BB#2: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX1-NEXT: jmp .LBB74_3 - ; AVX1-NEXT: .LBB74_1: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm1 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm1, %xmm1 - ; AVX1-NEXT: vaddss %xmm1, %xmm1, %xmm1 - ; AVX1-NEXT: .LBB74_3: - ; AVX1-NEXT: vmovq %xmm0, %rax -@@ -2747,12 +2856,12 @@ define <4 x float> @uitofp_load_4i64_to_4f32(<4 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB74_4 - ; AVX1-NEXT: # BB#5: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 - ; AVX1-NEXT: jmp .LBB74_6 - ; AVX1-NEXT: .LBB74_4: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm2, %xmm2 - ; AVX1-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX1-NEXT: .LBB74_6: - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0],xmm1[0],xmm2[2,3] -@@ -2763,12 +2872,12 @@ define <4 x float> @uitofp_load_4i64_to_4f32(<4 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB74_7 - ; AVX1-NEXT: # BB#8: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm2 - ; AVX1-NEXT: jmp .LBB74_9 - ; AVX1-NEXT: .LBB74_7: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm3, %xmm2 - ; AVX1-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX1-NEXT: .LBB74_9: - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm2[0],xmm1[3] -@@ -2778,16 +2887,14 @@ define <4 x float> @uitofp_load_4i64_to_4f32(<4 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB74_10 - ; AVX1-NEXT: # BB#11: --; AVX1-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm0 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX1-NEXT: vzeroupper - ; AVX1-NEXT: retq - ; AVX1-NEXT: .LBB74_10: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm0 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm3, %xmm0 - ; AVX1-NEXT: vaddss %xmm0, %xmm0, %xmm0 - ; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX1-NEXT: vzeroupper -@@ -2802,12 +2909,12 @@ define <4 x float> @uitofp_load_4i64_to_4f32(<4 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB74_1 - ; AVX2-NEXT: # BB#2: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX2-NEXT: jmp .LBB74_3 - ; AVX2-NEXT: .LBB74_1: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm1 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm1, %xmm1 - ; AVX2-NEXT: vaddss %xmm1, %xmm1, %xmm1 - ; AVX2-NEXT: .LBB74_3: - ; AVX2-NEXT: vmovq %xmm0, %rax -@@ -2816,12 +2923,12 @@ define <4 x float> @uitofp_load_4i64_to_4f32(<4 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB74_4 - ; AVX2-NEXT: # BB#5: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm2, %xmm2 - ; AVX2-NEXT: jmp .LBB74_6 - ; AVX2-NEXT: .LBB74_4: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm2, %xmm2 - ; AVX2-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX2-NEXT: .LBB74_6: - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm2[0],xmm1[0],xmm2[2,3] -@@ -2832,12 +2939,12 @@ define <4 x float> @uitofp_load_4i64_to_4f32(<4 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB74_7 - ; AVX2-NEXT: # BB#8: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm2 - ; AVX2-NEXT: jmp .LBB74_9 - ; AVX2-NEXT: .LBB74_7: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm3, %xmm2 - ; AVX2-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX2-NEXT: .LBB74_9: - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm2[0],xmm1[3] -@@ -2847,16 +2954,14 @@ define <4 x float> @uitofp_load_4i64_to_4f32(<4 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB74_10 - ; AVX2-NEXT: # BB#11: --; AVX2-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm0 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm0 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX2-NEXT: vzeroupper - ; AVX2-NEXT: retq - ; AVX2-NEXT: .LBB74_10: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm0 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm3, %xmm0 - ; AVX2-NEXT: vaddss %xmm0, %xmm0, %xmm0 - ; AVX2-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] - ; AVX2-NEXT: vzeroupper -@@ -3094,12 +3199,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB78_1 - ; AVX1-NEXT: # BB#2: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX1-NEXT: jmp .LBB78_3 - ; AVX1-NEXT: .LBB78_1: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm1 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm1, %xmm1 - ; AVX1-NEXT: vaddss %xmm1, %xmm1, %xmm1 - ; AVX1-NEXT: .LBB78_3: - ; AVX1-NEXT: vmovq %xmm2, %rax -@@ -3108,12 +3213,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB78_4 - ; AVX1-NEXT: # BB#5: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm3 - ; AVX1-NEXT: jmp .LBB78_6 - ; AVX1-NEXT: .LBB78_4: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm3 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm3, %xmm3 - ; AVX1-NEXT: vaddss %xmm3, %xmm3, %xmm3 - ; AVX1-NEXT: .LBB78_6: - ; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm2 -@@ -3123,12 +3228,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB78_7 - ; AVX1-NEXT: # BB#8: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm4 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm4 - ; AVX1-NEXT: jmp .LBB78_9 - ; AVX1-NEXT: .LBB78_7: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm4 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm4, %xmm4 - ; AVX1-NEXT: vaddss %xmm4, %xmm4, %xmm4 - ; AVX1-NEXT: .LBB78_9: - ; AVX1-NEXT: vpextrq $1, %xmm2, %rax -@@ -3137,12 +3242,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB78_10 - ; AVX1-NEXT: # BB#11: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm5, %xmm2 - ; AVX1-NEXT: jmp .LBB78_12 - ; AVX1-NEXT: .LBB78_10: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm5, %xmm2 - ; AVX1-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX1-NEXT: .LBB78_12: - ; AVX1-NEXT: vpextrq $1, %xmm0, %rax -@@ -3151,12 +3256,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB78_13 - ; AVX1-NEXT: # BB#14: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm5 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm5, %xmm5 - ; AVX1-NEXT: jmp .LBB78_15 - ; AVX1-NEXT: .LBB78_13: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm5 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm5, %xmm5 - ; AVX1-NEXT: vaddss %xmm5, %xmm5, %xmm5 - ; AVX1-NEXT: .LBB78_15: - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm3[0],xmm1[0],xmm3[2,3] -@@ -3166,12 +3271,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB78_16 - ; AVX1-NEXT: # BB#17: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm6, %xmm3 - ; AVX1-NEXT: jmp .LBB78_18 - ; AVX1-NEXT: .LBB78_16: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm3 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm6, %xmm3 - ; AVX1-NEXT: vaddss %xmm3, %xmm3, %xmm3 - ; AVX1-NEXT: .LBB78_18: - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm4[0],xmm1[3] -@@ -3183,14 +3288,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB78_19 - ; AVX1-NEXT: # BB#20: --; AVX1-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm5 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm6, %xmm5 - ; AVX1-NEXT: jmp .LBB78_21 - ; AVX1-NEXT: .LBB78_19: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm0 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm6, %xmm0 - ; AVX1-NEXT: vaddss %xmm0, %xmm0, %xmm5 - ; AVX1-NEXT: .LBB78_21: - ; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm2[0] -@@ -3201,12 +3304,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX1-NEXT: testq %rax, %rax - ; AVX1-NEXT: js .LBB78_22 - ; AVX1-NEXT: # BB#23: --; AVX1-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rax, %xmm6, %xmm2 - ; AVX1-NEXT: jmp .LBB78_24 - ; AVX1-NEXT: .LBB78_22: - ; AVX1-NEXT: shrq %rax - ; AVX1-NEXT: orq %rax, %rcx --; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX1-NEXT: vcvtsi2ssq %rcx, %xmm6, %xmm2 - ; AVX1-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX1-NEXT: .LBB78_24: - ; AVX1-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1,2],xmm2[0] -@@ -3223,12 +3326,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB78_1 - ; AVX2-NEXT: # BB#2: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm1 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm1, %xmm1 - ; AVX2-NEXT: jmp .LBB78_3 - ; AVX2-NEXT: .LBB78_1: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm1 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm1, %xmm1 - ; AVX2-NEXT: vaddss %xmm1, %xmm1, %xmm1 - ; AVX2-NEXT: .LBB78_3: - ; AVX2-NEXT: vmovq %xmm2, %rax -@@ -3237,12 +3340,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB78_4 - ; AVX2-NEXT: # BB#5: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm3, %xmm3 - ; AVX2-NEXT: jmp .LBB78_6 - ; AVX2-NEXT: .LBB78_4: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm3 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm3, %xmm3 - ; AVX2-NEXT: vaddss %xmm3, %xmm3, %xmm3 - ; AVX2-NEXT: .LBB78_6: - ; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm2 -@@ -3252,12 +3355,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB78_7 - ; AVX2-NEXT: # BB#8: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm4 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm4, %xmm4 - ; AVX2-NEXT: jmp .LBB78_9 - ; AVX2-NEXT: .LBB78_7: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm4 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm4, %xmm4 - ; AVX2-NEXT: vaddss %xmm4, %xmm4, %xmm4 - ; AVX2-NEXT: .LBB78_9: - ; AVX2-NEXT: vpextrq $1, %xmm2, %rax -@@ -3266,12 +3369,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB78_10 - ; AVX2-NEXT: # BB#11: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm5, %xmm2 - ; AVX2-NEXT: jmp .LBB78_12 - ; AVX2-NEXT: .LBB78_10: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm5, %xmm2 - ; AVX2-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX2-NEXT: .LBB78_12: - ; AVX2-NEXT: vpextrq $1, %xmm0, %rax -@@ -3280,12 +3383,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB78_13 - ; AVX2-NEXT: # BB#14: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm5 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm5, %xmm5 - ; AVX2-NEXT: jmp .LBB78_15 - ; AVX2-NEXT: .LBB78_13: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm5 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm5, %xmm5 - ; AVX2-NEXT: vaddss %xmm5, %xmm5, %xmm5 - ; AVX2-NEXT: .LBB78_15: - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm3[0],xmm1[0],xmm3[2,3] -@@ -3295,12 +3398,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB78_16 - ; AVX2-NEXT: # BB#17: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm3 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm6, %xmm3 - ; AVX2-NEXT: jmp .LBB78_18 - ; AVX2-NEXT: .LBB78_16: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm3 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm6, %xmm3 - ; AVX2-NEXT: vaddss %xmm3, %xmm3, %xmm3 - ; AVX2-NEXT: .LBB78_18: - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],xmm4[0],xmm1[3] -@@ -3312,14 +3415,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB78_19 - ; AVX2-NEXT: # BB#20: --; AVX2-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm5 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm6, %xmm5 - ; AVX2-NEXT: jmp .LBB78_21 - ; AVX2-NEXT: .LBB78_19: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vxorps %xmm0, %xmm0, %xmm0 --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm0 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm6, %xmm0 - ; AVX2-NEXT: vaddss %xmm0, %xmm0, %xmm5 - ; AVX2-NEXT: .LBB78_21: - ; AVX2-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm2[0] -@@ -3330,12 +3431,12 @@ define <8 x float> @uitofp_load_8i64_to_8f32(<8 x i64> *%a) { - ; AVX2-NEXT: testq %rax, %rax - ; AVX2-NEXT: js .LBB78_22 - ; AVX2-NEXT: # BB#23: --; AVX2-NEXT: vcvtsi2ssq %rax, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rax, %xmm6, %xmm2 - ; AVX2-NEXT: jmp .LBB78_24 - ; AVX2-NEXT: .LBB78_22: - ; AVX2-NEXT: shrq %rax - ; AVX2-NEXT: orq %rax, %rcx --; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm0, %xmm2 -+; AVX2-NEXT: vcvtsi2ssq %rcx, %xmm6, %xmm2 - ; AVX2-NEXT: vaddss %xmm2, %xmm2, %xmm2 - ; AVX2-NEXT: .LBB78_24: - ; AVX2-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1,2],xmm2[0] --- -2.11.0 - diff --git a/deps/patches/llvm-PR278923.patch b/deps/patches/llvm-PR278923.patch deleted file mode 100644 index 486777711193a..0000000000000 --- a/deps/patches/llvm-PR278923.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 77eee1c0f05c587e7fb8a9a2064908d7333dcfb9 Mon Sep 17 00:00:00 2001 -From: Marina Yatsina -Date: Wed, 17 Aug 2016 11:40:21 +0000 -Subject: [PATCH 5/5] Fixing bug committed in rev. 278321 - -In theory the indices of RC (and thus the index used for LiveRegs) may differ from the indices of OpRC. -Fixed the code to extract the correct RC index. -OpRC contains the first X consecutive elements of RC, and thus their indices are currently de facto the same, therefore a test cannot be added at this point. - -Differential Revision: https://reviews.llvm.org/D23491 - - - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278923 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - include/llvm/Target/TargetRegisterInfo.h | 6 ++++++ - lib/CodeGen/ExecutionDepsFix.cpp | 9 ++++++--- - 2 files changed, 12 insertions(+), 3 deletions(-) - -diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h -index e5a6c8ed2f2..e5642493928 100644 ---- a/include/llvm/Target/TargetRegisterInfo.h -+++ b/include/llvm/Target/TargetRegisterInfo.h -@@ -17,6 +17,7 @@ - #define LLVM_TARGET_TARGETREGISTERINFO_H - - #include "llvm/ADT/ArrayRef.h" -+#include "llvm/ADT/iterator_range.h" - #include "llvm/CodeGen/MachineBasicBlock.h" - #include "llvm/CodeGen/MachineValueType.h" - #include "llvm/IR/CallingConv.h" -@@ -86,6 +87,11 @@ public: - - /// Return the number of registers in this class. - unsigned getNumRegs() const { return MC->getNumRegs(); } -+ -+ iterator_range::const_iterator> -+ getRegisters() const { -+ return make_range(MC->begin(), MC->end()); -+ } - - /// Return the specified register in the class. - unsigned getRegister(unsigned i) const { -diff --git a/lib/CodeGen/ExecutionDepsFix.cpp b/lib/CodeGen/ExecutionDepsFix.cpp -index 5f91db9251c..213dd58a31d 100644 ---- a/lib/CodeGen/ExecutionDepsFix.cpp -+++ b/lib/CodeGen/ExecutionDepsFix.cpp -@@ -509,12 +509,15 @@ void ExeDepsFix::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, - // max clearance or clearance higher than Pref. - unsigned MaxClearance = 0; - unsigned MaxClearanceReg = OriginalReg; -- for (unsigned rx = 0; rx < OpRC->getNumRegs(); ++rx) { -- unsigned Clearance = CurInstr - LiveRegs[rx].Def; -+ for (auto Reg : OpRC->getRegisters()) { -+ assert(AliasMap[Reg].size() == 1 && -+ "Reg is expected to be mapped to a single index"); -+ int RCrx = *regIndices(Reg).begin(); -+ unsigned Clearance = CurInstr - LiveRegs[RCrx].Def; - if (Clearance <= MaxClearance) - continue; - MaxClearance = Clearance; -- MaxClearanceReg = OpRC->getRegister(rx); -+ MaxClearanceReg = Reg; - - if (MaxClearance > Pref) - break; --- -2.11.0 - diff --git a/deps/patches/llvm-PR29010-i386-xmm.patch b/deps/patches/llvm-PR29010-i386-xmm.patch deleted file mode 100644 index b31f70d365cf0..0000000000000 --- a/deps/patches/llvm-PR29010-i386-xmm.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 83260f239481dfb40d325cf35005c20eeb767b6c Mon Sep 17 00:00:00 2001 -From: Marina Yatsina -Date: Wed, 17 Aug 2016 19:07:40 +0000 -Subject: [PATCH] Fix for PR29010 - -This is a fix for https://llvm.org/bugs/show_bug.cgi?id=29010 -Root cause of the bug is that the register class of the machine instruction operand does not fully reflect if this registers that can be allocated. -Both for i386 and x86_64 the operand's register class is VR128RegClass and thus contains xmm0-xmm15, though in i386 we can only use xmm0-xmm8. -In order to get the actual allocable registers of the class we need to use RegisterClassInfo. - -Differential Revision: https://reviews.llvm.org/D23613 - - - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278954 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/CodeGen/ExecutionDepsFix.cpp | 6 +++++- - test/CodeGen/X86/pr29010.ll | 12 ++++++++++++ - 2 files changed, 17 insertions(+), 1 deletion(-) - create mode 100644 test/CodeGen/X86/pr29010.ll - -diff --git a/lib/CodeGen/ExecutionDepsFix.cpp b/lib/CodeGen/ExecutionDepsFix.cpp -index 213dd58a31d..2f173f84d73 100644 ---- a/lib/CodeGen/ExecutionDepsFix.cpp -+++ b/lib/CodeGen/ExecutionDepsFix.cpp -@@ -26,6 +26,7 @@ - #include "llvm/CodeGen/LivePhysRegs.h" - #include "llvm/CodeGen/MachineFunctionPass.h" - #include "llvm/CodeGen/MachineRegisterInfo.h" -+#include "llvm/CodeGen/RegisterClassInfo.h" - #include "llvm/Support/Allocator.h" - #include "llvm/Support/Debug.h" - #include "llvm/Support/raw_ostream.h" -@@ -137,6 +138,7 @@ class ExeDepsFix : public MachineFunctionPass { - MachineFunction *MF; - const TargetInstrInfo *TII; - const TargetRegisterInfo *TRI; -+ RegisterClassInfo RegClassInfo; - std::vector> AliasMap; - const unsigned NumRegs; - LiveReg *LiveRegs; -@@ -509,7 +511,8 @@ void ExeDepsFix::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx, - // max clearance or clearance higher than Pref. - unsigned MaxClearance = 0; - unsigned MaxClearanceReg = OriginalReg; -- for (auto Reg : OpRC->getRegisters()) { -+ ArrayRef Order = RegClassInfo.getOrder(OpRC); -+ for (auto Reg : Order) { - assert(AliasMap[Reg].size() == 1 && - "Reg is expected to be mapped to a single index"); - int RCrx = *regIndices(Reg).begin(); -@@ -785,6 +788,7 @@ bool ExeDepsFix::runOnMachineFunction(MachineFunction &mf) { - MF = &mf; - TII = MF->getSubtarget().getInstrInfo(); - TRI = MF->getSubtarget().getRegisterInfo(); -+ RegClassInfo.runOnMachineFunction(mf); - LiveRegs = nullptr; - assert(NumRegs == RC->getNumRegs() && "Bad regclass"); - -diff --git a/test/CodeGen/X86/pr29010.ll b/test/CodeGen/X86/pr29010.ll -new file mode 100644 -index 00000000000..a2d5ff69a35 ---- /dev/null -+++ b/test/CodeGen/X86/pr29010.ll -@@ -0,0 +1,12 @@ -+; RUN: llc < %s -mtriple=i386-linux -mattr=+avx | FileCheck %s -+ -+; In i386 there are only 8 XMMs (xmm0-xmm7), make sure we we are not creating illegal XMM -+define float @only_xmm0_7(i32 %arg) { -+top: -+ tail call void asm sideeffect "", "~{xmm0},~{xmm1},~{xmm2},~{xmm3},~{dirflag},~{fpsr},~{flags}"() -+ tail call void asm sideeffect "", "~{xmm4},~{xmm5},~{xmm6},~{xmm7},~{dirflag},~{fpsr},~{flags}"() -+ %tmp1 = sitofp i32 %arg to float -+ ret float %tmp1 -+;CHECK-LABEL:@only_xmm0_7 -+;CHECK: vcvtsi2ssl {{.*}}, {{%xmm[0-7]+}}, {{%xmm[0-7]+}} -+} --- -2.13.0 - diff --git a/deps/patches/llvm-PR36292-5.0.patch b/deps/patches/llvm-PR36292-5.0.patch deleted file mode 100644 index 7d5d8d167f533..0000000000000 --- a/deps/patches/llvm-PR36292-5.0.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 94f96f87fa44f2fa2cf86ecb644d3cdc3fc609ad Mon Sep 17 00:00:00 2001 -From: Nemanja Ivanovic -Date: Thu, 22 Feb 2018 03:02:41 +0000 -Subject: [PATCH] [PowerPC] Do not produce invalid CTR loop with an FRem - -An FRem instruction inside a loop should prevent the loop from being converted -into a CTR loop since this is not an operation that is legal on any PPC -subtarget. This will always be a call to a library function which means the -loop will be invalid if this instruction is in the body. - -Fixes PR36292. - - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325739 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Target/PowerPC/PPCCTRLoops.cpp | 5 ++++- - test/CodeGen/PowerPC/pr36292.ll | 46 ++++++++++++++++++++++++++++++++++++++ - 2 files changed, 50 insertions(+), 1 deletion(-) - create mode 100644 test/CodeGen/PowerPC/pr36292.ll - -diff --git a/lib/Target/PowerPC/PPCCTRLoops.cpp b/lib/Target/PowerPC/PPCCTRLoops.cpp -index 53f33ac1fc0..97917a1d096 100644 ---- a/lib/Target/PowerPC/PPCCTRLoops.cpp -+++ b/lib/Target/PowerPC/PPCCTRLoops.cpp -@@ -437,13 +437,16 @@ bool PPCCTRLoops::mightUseCTR(BasicBlock *BB) { - return true; - } - -+ // FREM is always a call. -+ if (J->getOpcode() == Instruction::FRem) -+ return true; -+ - if (STI->useSoftFloat()) { - switch(J->getOpcode()) { - case Instruction::FAdd: - case Instruction::FSub: - case Instruction::FMul: - case Instruction::FDiv: -- case Instruction::FRem: - case Instruction::FPTrunc: - case Instruction::FPExt: - case Instruction::FPToUI: -diff --git a/test/CodeGen/PowerPC/pr36292.ll b/test/CodeGen/PowerPC/pr36292.ll -new file mode 100644 -index 00000000000..a171918b9e0 ---- /dev/null -+++ b/test/CodeGen/PowerPC/pr36292.ll -@@ -0,0 +1,46 @@ -+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-unknown < %s | \ -+; RUN: FileCheck %s --implicit-check-not=mtctr --implicit-check-not=bdnz -+$test = comdat any -+ -+; No CTR loop due to frem (since it is always a call). -+define void @test() #0 comdat { -+; CHECK-LABEL: test: -+; CHECK: ld 29, 0(3) -+; CHECK: ld 30, 40(1) -+; CHECK: xxlxor 31, 31, 31 -+; CHECK: cmpld 30, 29 -+; CHECK-NEXT: bge- 0, .LBB0_2 -+; CHECK-NEXT: .p2align 5 -+; CHECK-NEXT: .LBB0_1: # %bounds.ok -+; CHECK: fmr 1, 31 -+; CHECK-NEXT: lfsx 2, 0, 3 -+; CHECK-NEXT: bl fmodf -+; CHECK-NEXT: nop -+; CHECK-NEXT: addi 30, 30, 1 -+; CHECK-NEXT: stfsx 1, 0, 3 -+; CHECK-NEXT: cmpld 30, 29 -+; CHECK-NEXT: blt+ 0, .LBB0_1 -+; CHECK-NEXT: .LBB0_2: # %bounds.fail -+; CHECK-NEXT: std 30, 40(1) -+ %pos = alloca i64, align 8 -+ br label %forcond -+ -+forcond: ; preds = %bounds.ok, %0 -+ %1 = load i64, i64* %pos -+ %.len1 = load i64, i64* undef -+ %bounds.cmp = icmp ult i64 %1, %.len1 -+ br i1 %bounds.cmp, label %bounds.ok, label %bounds.fail -+ -+bounds.ok: ; preds = %forcond -+ %2 = load float, float* undef -+ %3 = frem float 0.000000e+00, %2 -+ store float %3, float* undef -+ %4 = load i64, i64* %pos -+ %5 = add i64 %4, 1 -+ store i64 %5, i64* %pos -+ br label %forcond -+ -+bounds.fail: ; preds = %forcond -+ unreachable -+} -+ --- -2.16.2 - diff --git a/deps/patches/llvm-PR36292.patch b/deps/patches/llvm-PR36292.patch deleted file mode 100644 index 8d5f72b146ac3..0000000000000 --- a/deps/patches/llvm-PR36292.patch +++ /dev/null @@ -1,96 +0,0 @@ -From bf6e0a9a6dacce55de9f72de06318e7b97b44e3d Mon Sep 17 00:00:00 2001 -From: Nemanja Ivanovic -Date: Thu, 22 Feb 2018 03:02:41 +0000 -Subject: [PATCH] [PowerPC] Do not produce invalid CTR loop with an FRem - -An FRem instruction inside a loop should prevent the loop from being converted -into a CTR loop since this is not an operation that is legal on any PPC -subtarget. This will always be a call to a library function which means the -loop will be invalid if this instruction is in the body. - -Fixes PR36292. - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325739 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - lib/Target/PowerPC/PPCCTRLoops.cpp | 5 ++++- - test/CodeGen/PowerPC/pr36292.ll | 46 ++++++++++++++++++++++++++++++++++++++ - 2 files changed, 50 insertions(+), 1 deletion(-) - create mode 100644 test/CodeGen/PowerPC/pr36292.ll - -diff --git a/lib/Target/PowerPC/PPCCTRLoops.cpp b/lib/Target/PowerPC/PPCCTRLoops.cpp -index 87522663591..6a327781ca2 100644 ---- a/lib/Target/PowerPC/PPCCTRLoops.cpp -+++ b/lib/Target/PowerPC/PPCCTRLoops.cpp -@@ -435,13 +435,16 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) { - return true; - } - -+ // FREM is always a call. -+ if (J->getOpcode() == Instruction::FRem) -+ return true; -+ - if (TM->getSubtargetImpl(*BB->getParent())->getTargetLowering()->useSoftFloat()) { - switch(J->getOpcode()) { - case Instruction::FAdd: - case Instruction::FSub: - case Instruction::FMul: - case Instruction::FDiv: -- case Instruction::FRem: - case Instruction::FPTrunc: - case Instruction::FPExt: - case Instruction::FPToUI: -diff --git a/test/CodeGen/PowerPC/pr36292.ll b/test/CodeGen/PowerPC/pr36292.ll -new file mode 100644 -index 00000000000..a171918b9e0 ---- /dev/null -+++ b/test/CodeGen/PowerPC/pr36292.ll -@@ -0,0 +1,46 @@ -+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-unknown < %s | \ -+; RUN: FileCheck %s --implicit-check-not=mtctr --implicit-check-not=bdnz -+$test = comdat any -+ -+; No CTR loop due to frem (since it is always a call). -+define void @test() #0 comdat { -+; CHECK-LABEL: test: -+; CHECK: ld 29, 0(3) -+; CHECK: ld 30, 40(1) -+; CHECK: xxlxor 31, 31, 31 -+; CHECK: cmpld 30, 29 -+; CHECK-NEXT: bge- 0, .LBB0_2 -+; CHECK-NEXT: .p2align 5 -+; CHECK-NEXT: .LBB0_1: # %bounds.ok -+; CHECK: fmr 1, 31 -+; CHECK-NEXT: lfsx 2, 0, 3 -+; CHECK-NEXT: bl fmodf -+; CHECK-NEXT: nop -+; CHECK-NEXT: addi 30, 30, 1 -+; CHECK-NEXT: stfsx 1, 0, 3 -+; CHECK-NEXT: cmpld 30, 29 -+; CHECK-NEXT: blt+ 0, .LBB0_1 -+; CHECK-NEXT: .LBB0_2: # %bounds.fail -+; CHECK-NEXT: std 30, 40(1) -+ %pos = alloca i64, align 8 -+ br label %forcond -+ -+forcond: ; preds = %bounds.ok, %0 -+ %1 = load i64, i64* %pos -+ %.len1 = load i64, i64* undef -+ %bounds.cmp = icmp ult i64 %1, %.len1 -+ br i1 %bounds.cmp, label %bounds.ok, label %bounds.fail -+ -+bounds.ok: ; preds = %forcond -+ %2 = load float, float* undef -+ %3 = frem float 0.000000e+00, %2 -+ store float %3, float* undef -+ %4 = load i64, i64* %pos -+ %5 = add i64 %4, 1 -+ store i64 %5, i64* %pos -+ br label %forcond -+ -+bounds.fail: ; preds = %forcond -+ unreachable -+} -+ --- -2.16.2 - diff --git a/deps/patches/llvm-VNCoercion-signatures.patch b/deps/patches/llvm-VNCoercion-signatures.patch deleted file mode 100644 index 5b8923ee47678..0000000000000 --- a/deps/patches/llvm-VNCoercion-signatures.patch +++ /dev/null @@ -1,60 +0,0 @@ -From a0946a413f7ee14ed26c48a249b2a326ade70a42 Mon Sep 17 00:00:00 2001 -From: Daniel Berlin -Date: Sat, 11 Mar 2017 00:51:01 +0000 -Subject: [PATCH 6/7] VNCoercion: Make the function signatures all consistent - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297537 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - include/llvm/Transforms/Utils/VNCoercion.h | 2 +- - lib/Transforms/Scalar/GVN.cpp | 2 +- - lib/Transforms/Utils/VNCoercion.cpp | 3 +-- - 3 files changed, 3 insertions(+), 4 deletions(-) - -diff --git a/include/llvm/Transforms/Utils/VNCoercion.h b/include/llvm/Transforms/Utils/VNCoercion.h -index d3c998fa8a8..edc63ca38db 100644 ---- a/include/llvm/Transforms/Utils/VNCoercion.h -+++ b/include/llvm/Transforms/Utils/VNCoercion.h -@@ -53,7 +53,7 @@ Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, - /// On success, it returns the offset into DepSI that extraction would start. - /// On failure, it returns -1. - int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, -- StoreInst *DepSI); -+ StoreInst *DepSI, const DataLayout &DL); - - /// This function determines whether a value for the pointer LoadPtr can be - /// extracted from the load at DepLI. -diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp -index 132c7297d77..7b8948c065b 100644 ---- a/lib/Transforms/Scalar/GVN.cpp -+++ b/lib/Transforms/Scalar/GVN.cpp -@@ -830,7 +830,7 @@ bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo, - // Can't forward from non-atomic to atomic without violating memory model. - if (Address && LI->isAtomic() <= DepSI->isAtomic()) { - int Offset = -- analyzeLoadFromClobberingStore(LI->getType(), Address, DepSI); -+ analyzeLoadFromClobberingStore(LI->getType(), Address, DepSI, DL); - if (Offset != -1) { - Res = AvailableValue::get(DepSI->getValueOperand(), Offset); - return true; -diff --git a/lib/Transforms/Utils/VNCoercion.cpp b/lib/Transforms/Utils/VNCoercion.cpp -index 9d2eab19ded..6fa9aca8436 100644 ---- a/lib/Transforms/Utils/VNCoercion.cpp -+++ b/lib/Transforms/Utils/VNCoercion.cpp -@@ -195,13 +195,12 @@ static int analyzeLoadFromClobberingWrite(Type *LoadTy, Value *LoadPtr, - /// This function is called when we have a - /// memdep query of a load that ends up being a clobbering store. - int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, -- StoreInst *DepSI) { -+ StoreInst *DepSI, const DataLayout &DL) { - // Cannot handle reading from store of first-class aggregate yet. - if (DepSI->getValueOperand()->getType()->isStructTy() || - DepSI->getValueOperand()->getType()->isArrayTy()) - return -1; - -- const DataLayout &DL = DepSI->getModule()->getDataLayout(); - Value *StorePtr = DepSI->getPointerOperand(); - uint64_t StoreSize = - DL.getTypeSizeInBits(DepSI->getValueOperand()->getType()); --- -2.13.1 - diff --git a/deps/patches/llvm-VNCoercion-template.patch b/deps/patches/llvm-VNCoercion-template.patch deleted file mode 100644 index 6aa87a1cf3a33..0000000000000 --- a/deps/patches/llvm-VNCoercion-template.patch +++ /dev/null @@ -1,410 +0,0 @@ -From 67cb3073f40c0d02334e161a1c9c749be777f411 Mon Sep 17 00:00:00 2001 -From: Daniel Berlin -Date: Mon, 20 Mar 2017 16:08:29 +0000 -Subject: [PATCH 7/7] Templatize parts of VNCoercion, and add constant-only - versions of the functions to be used in NewGVN. NFCI. - -Summary: -This is ground work for the changes to enable coercion in NewGVN. -GVN doesn't care if they end up constant because it eliminates as it goes. -NewGVN cares. - -IRBuilder and ConstantFolder deliberately present the same interface, -so we use this to our advantage to templatize our functions to make -them either constant only or not. - -Reviewers: davide - -Subscribers: llvm-commits, Prazek - -Differential Revision: https://reviews.llvm.org/D30928 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298262 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - include/llvm/Transforms/Utils/VNCoercion.h | 14 ++- - lib/Transforms/Scalar/GVN.cpp | 2 +- - lib/Transforms/Utils/VNCoercion.cpp | 177 ++++++++++++++++++----------- - 3 files changed, 124 insertions(+), 69 deletions(-) - -diff --git a/include/llvm/Transforms/Utils/VNCoercion.h b/include/llvm/Transforms/Utils/VNCoercion.h -index edc63ca38db..1baa9b66e49 100644 ---- a/include/llvm/Transforms/Utils/VNCoercion.h -+++ b/include/llvm/Transforms/Utils/VNCoercion.h -@@ -76,13 +76,21 @@ int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, - /// inserts instructions to do so at InsertPt, and returns the extracted value. - Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, - Instruction *InsertPt, const DataLayout &DL); -+// This is the same as getStoreValueForLoad, except it performs no insertion -+// It only allows constant inputs. -+Constant *getConstantStoreValueForLoad(Constant *SrcVal, unsigned Offset, -+ Type *LoadTy, const DataLayout &DL); - - /// If analyzeLoadFromClobberingLoad returned an offset, this function can be - /// used to actually perform the extraction of the bits from the load, including - /// any necessary load widening. It inserts instructions to do so at InsertPt, - /// and returns the extracted value. - Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy, -- Instruction *InsertPt); -+ Instruction *InsertPt, const DataLayout &DL); -+// This is the same as getLoadValueForLoad, except it is given the load value as -+// a constant. It returns nullptr if it would require widening the load. -+Constant *getConstantLoadValueForLoad(Constant *SrcVal, unsigned Offset, -+ Type *LoadTy, const DataLayout &DL); - - /// If analyzeLoadFromClobberingMemInst returned an offset, this function can be - /// used to actually perform the extraction of the bits from the memory -@@ -91,6 +99,10 @@ Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy, - Value *getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, - Type *LoadTy, Instruction *InsertPt, - const DataLayout &DL); -+// This is the same as getStoreValueForLoad, except it performs no insertion. -+// It returns nullptr if it cannot produce a constant. -+Constant *getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, -+ Type *LoadTy, const DataLayout &DL); - } - } - #endif -diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp -index 7b8948c065b..91118ee7e39 100644 ---- a/lib/Transforms/Scalar/GVN.cpp -+++ b/lib/Transforms/Scalar/GVN.cpp -@@ -748,7 +748,7 @@ Value *AvailableValue::MaterializeAdjustedValue(LoadInst *LI, - if (Load->getType() == LoadTy && Offset == 0) { - Res = Load; - } else { -- Res = getLoadValueForLoad(Load, Offset, LoadTy, InsertPt); -+ Res = getLoadValueForLoad(Load, Offset, LoadTy, InsertPt, DL); - // We would like to use gvn.markInstructionForDeletion here, but we can't - // because the load is already memoized into the leader map table that GVN - // tracks. It is potentially possible to remove the load from the table, -diff --git a/lib/Transforms/Utils/VNCoercion.cpp b/lib/Transforms/Utils/VNCoercion.cpp -index 6fa9aca8436..60d9ede2c48 100644 ---- a/lib/Transforms/Utils/VNCoercion.cpp -+++ b/lib/Transforms/Utils/VNCoercion.cpp -@@ -32,17 +32,12 @@ bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, - return true; - } - --/// If we saw a store of a value to memory, and --/// then a load from a must-aliased pointer of a different type, try to coerce --/// the stored value. LoadedTy is the type of the load we want to replace. --/// IRB is IRBuilder used to insert new instructions. --/// --/// If we can't do it, return null. --Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, -- IRBuilder<> &IRB, const DataLayout &DL) { -+template -+static T *coerceAvailableValueToLoadTypeHelper(T *StoredVal, Type *LoadedTy, -+ HelperClass &Helper, -+ const DataLayout &DL) { - assert(canCoerceMustAliasedValueToLoad(StoredVal, LoadedTy, DL) && - "precondition violation - materialization can't fail"); -- - if (auto *C = dyn_cast(StoredVal)) - if (auto *FoldedStoredVal = ConstantFoldConstant(C, DL)) - StoredVal = FoldedStoredVal; -@@ -58,12 +53,12 @@ Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, - // Pointer to Pointer -> use bitcast. - if (StoredValTy->getScalarType()->isPointerTy() && - LoadedTy->getScalarType()->isPointerTy()) { -- StoredVal = IRB.CreateBitCast(StoredVal, LoadedTy); -+ StoredVal = Helper.CreateBitCast(StoredVal, LoadedTy); - } else { - // Convert source pointers to integers, which can be bitcast. - if (StoredValTy->getScalarType()->isPointerTy()) { - StoredValTy = DL.getIntPtrType(StoredValTy); -- StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy); -+ StoredVal = Helper.CreatePtrToInt(StoredVal, StoredValTy); - } - - Type *TypeToCastTo = LoadedTy; -@@ -71,11 +66,11 @@ Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, - TypeToCastTo = DL.getIntPtrType(TypeToCastTo); - - if (StoredValTy != TypeToCastTo) -- StoredVal = IRB.CreateBitCast(StoredVal, TypeToCastTo); -+ StoredVal = Helper.CreateBitCast(StoredVal, TypeToCastTo); - - // Cast to pointer if the load needs a pointer type. - if (LoadedTy->getScalarType()->isPointerTy()) -- StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy); -+ StoredVal = Helper.CreateIntToPtr(StoredVal, LoadedTy); - } - - if (auto *C = dyn_cast(StoredVal)) -@@ -84,7 +79,6 @@ Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, - - return StoredVal; - } -- - // If the loaded value is smaller than the available value, then we can - // extract out a piece from it. If the available value is too small, then we - // can't do anything. -@@ -94,13 +88,13 @@ Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, - // Convert source pointers to integers, which can be manipulated. - if (StoredValTy->getScalarType()->isPointerTy()) { - StoredValTy = DL.getIntPtrType(StoredValTy); -- StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy); -+ StoredVal = Helper.CreatePtrToInt(StoredVal, StoredValTy); - } - - // Convert vectors and fp to integer, which can be manipulated. - if (!StoredValTy->isIntegerTy()) { - StoredValTy = IntegerType::get(StoredValTy->getContext(), StoredValSize); -- StoredVal = IRB.CreateBitCast(StoredVal, StoredValTy); -+ StoredVal = Helper.CreateBitCast(StoredVal, StoredValTy); - } - - // If this is a big-endian system, we need to shift the value down to the low -@@ -108,20 +102,21 @@ Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, - if (DL.isBigEndian()) { - uint64_t ShiftAmt = DL.getTypeStoreSizeInBits(StoredValTy) - - DL.getTypeStoreSizeInBits(LoadedTy); -- StoredVal = IRB.CreateLShr(StoredVal, ShiftAmt, "tmp"); -+ StoredVal = Helper.CreateLShr( -+ StoredVal, ConstantInt::get(StoredVal->getType(), ShiftAmt)); - } - - // Truncate the integer to the right size now. - Type *NewIntTy = IntegerType::get(StoredValTy->getContext(), LoadedValSize); -- StoredVal = IRB.CreateTrunc(StoredVal, NewIntTy, "trunc"); -+ StoredVal = Helper.CreateTruncOrBitCast(StoredVal, NewIntTy); - - if (LoadedTy != NewIntTy) { - // If the result is a pointer, inttoptr. - if (LoadedTy->getScalarType()->isPointerTy()) -- StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy, "inttoptr"); -+ StoredVal = Helper.CreateIntToPtr(StoredVal, LoadedTy); - else - // Otherwise, bitcast. -- StoredVal = IRB.CreateBitCast(StoredVal, LoadedTy, "bitcast"); -+ StoredVal = Helper.CreateBitCast(StoredVal, LoadedTy); - } - - if (auto *C = dyn_cast(StoredVal)) -@@ -131,10 +126,21 @@ Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, - return StoredVal; - } - --/// This function is called when we have a --/// memdep query of a load that ends up being a clobbering memory write (store, --/// memset, memcpy, memmove). This means that the write *may* provide bits used --/// by the load but we can't be sure because the pointers don't mustalias. -+/// If we saw a store of a value to memory, and -+/// then a load from a must-aliased pointer of a different type, try to coerce -+/// the stored value. LoadedTy is the type of the load we want to replace. -+/// IRB is IRBuilder used to insert new instructions. -+/// -+/// If we can't do it, return null. -+Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, -+ IRBuilder<> &IRB, const DataLayout &DL) { -+ return coerceAvailableValueToLoadTypeHelper(StoredVal, LoadedTy, IRB, DL); -+} -+ -+/// This function is called when we have a memdep query of a load that ends up -+/// being a clobbering memory write (store, memset, memcpy, memmove). This -+/// means that the write *may* provide bits used by the load but we can't be -+/// sure because the pointers don't must-alias. - /// - /// Check this case to see if there is anything more we can do before we give - /// up. This returns -1 if we have to give up, or a byte number in the stored -@@ -291,13 +297,10 @@ int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, - return -1; - } - --/// This function is called when we have a --/// memdep query of a load that ends up being a clobbering store. This means --/// that the store provides bits used by the load but we the pointers don't --/// mustalias. Check this case to see if there is anything more we can do --/// before we give up. --Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, -- Instruction *InsertPt, const DataLayout &DL) { -+template -+static T *getStoreValueForLoadHelper(T *SrcVal, unsigned Offset, Type *LoadTy, -+ HelperClass &Helper, -+ const DataLayout &DL) { - LLVMContext &Ctx = SrcVal->getType()->getContext(); - - // If two pointers are in the same address space, they have the same size, -@@ -311,17 +314,12 @@ Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, - - uint64_t StoreSize = (DL.getTypeSizeInBits(SrcVal->getType()) + 7) / 8; - uint64_t LoadSize = (DL.getTypeSizeInBits(LoadTy) + 7) / 8; -- -- IRBuilder<> Builder(InsertPt); -- - // Compute which bits of the stored value are being used by the load. Convert - // to an integer type to start with. - if (SrcVal->getType()->getScalarType()->isPointerTy()) -- SrcVal = -- Builder.CreatePtrToInt(SrcVal, DL.getIntPtrType(SrcVal->getType())); -+ SrcVal = Helper.CreatePtrToInt(SrcVal, DL.getIntPtrType(SrcVal->getType())); - if (!SrcVal->getType()->isIntegerTy()) -- SrcVal = -- Builder.CreateBitCast(SrcVal, IntegerType::get(Ctx, StoreSize * 8)); -+ SrcVal = Helper.CreateBitCast(SrcVal, IntegerType::get(Ctx, StoreSize * 8)); - - // Shift the bits to the least significant depending on endianness. - unsigned ShiftAmt; -@@ -329,25 +327,42 @@ Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, - ShiftAmt = Offset * 8; - else - ShiftAmt = (StoreSize - LoadSize - Offset) * 8; -- - if (ShiftAmt) -- SrcVal = Builder.CreateLShr(SrcVal, ShiftAmt); -+ SrcVal = Helper.CreateLShr(SrcVal, -+ ConstantInt::get(SrcVal->getType(), ShiftAmt)); - - if (LoadSize != StoreSize) -- SrcVal = Builder.CreateTrunc(SrcVal, IntegerType::get(Ctx, LoadSize * 8)); -+ SrcVal = Helper.CreateTruncOrBitCast(SrcVal, -+ IntegerType::get(Ctx, LoadSize * 8)); -+ return SrcVal; -+} -+ -+/// This function is called when we have a memdep query of a load that ends up -+/// being a clobbering store. This means that the store provides bits used by -+/// the load but the pointers don't must-alias. Check this case to see if -+/// there is anything more we can do before we give up. -+Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, -+ Instruction *InsertPt, const DataLayout &DL) { - -- return coerceAvailableValueToLoadType(SrcVal, LoadTy, Builder, DL); -+ IRBuilder<> Builder(InsertPt); -+ SrcVal = getStoreValueForLoadHelper(SrcVal, Offset, LoadTy, Builder, DL); -+ return coerceAvailableValueToLoadTypeHelper(SrcVal, LoadTy, Builder, DL); - } - --/// This function is called when we have a --/// memdep query of a load that ends up being a clobbering load. This means --/// that the load *may* provide bits used by the load but we can't be sure --/// because the pointers don't mustalias. Check this case to see if there is --/// anything more we can do before we give up. --Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy, -- Instruction *InsertPt) { -+Constant *getConstantStoreValueForLoad(Constant *SrcVal, unsigned Offset, -+ Type *LoadTy, const DataLayout &DL) { -+ ConstantFolder F; -+ SrcVal = getStoreValueForLoadHelper(SrcVal, Offset, LoadTy, F, DL); -+ return coerceAvailableValueToLoadTypeHelper(SrcVal, LoadTy, F, DL); -+} - -- const DataLayout &DL = SrcVal->getModule()->getDataLayout(); -+/// This function is called when we have a memdep query of a load that ends up -+/// being a clobbering load. This means that the load *may* provide bits used -+/// by the load but we can't be sure because the pointers don't must-alias. -+/// Check this case to see if there is anything more we can do before we give -+/// up. -+Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy, -+ Instruction *InsertPt, const DataLayout &DL) { - // If Offset+LoadTy exceeds the size of SrcVal, then we must be wanting to - // widen SrcVal out to a larger load. - unsigned SrcValStoreSize = DL.getTypeStoreSize(SrcVal->getType()); -@@ -362,7 +377,6 @@ Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy, - NewLoadSize = NextPowerOf2(NewLoadSize); - - Value *PtrVal = SrcVal->getPointerOperand(); -- - // Insert the new load after the old load. This ensures that subsequent - // memdep queries will find the new load. We can't easily remove the old - // load completely because it is already in the value numbering table. -@@ -393,44 +407,51 @@ Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy, - return getStoreValueForLoad(SrcVal, Offset, LoadTy, InsertPt, DL); - } - --/// This function is called when we have a --/// memdep query of a load that ends up being a clobbering mem intrinsic. --Value *getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, -- Type *LoadTy, Instruction *InsertPt, -- const DataLayout &DL) { -+Constant *getConstantLoadValueForLoad(Constant *SrcVal, unsigned Offset, -+ Type *LoadTy, const DataLayout &DL) { -+ unsigned SrcValStoreSize = DL.getTypeStoreSize(SrcVal->getType()); -+ unsigned LoadSize = DL.getTypeStoreSize(LoadTy); -+ if (Offset + LoadSize > SrcValStoreSize) -+ return nullptr; -+ return getConstantStoreValueForLoad(SrcVal, Offset, LoadTy, DL); -+} -+ -+template -+T *getMemInstValueForLoadHelper(MemIntrinsic *SrcInst, unsigned Offset, -+ Type *LoadTy, HelperClass &Helper, -+ const DataLayout &DL) { - LLVMContext &Ctx = LoadTy->getContext(); - uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy) / 8; - -- IRBuilder<> Builder(InsertPt); -- - // We know that this method is only called when the mem transfer fully - // provides the bits for the load. - if (MemSetInst *MSI = dyn_cast(SrcInst)) { - // memset(P, 'x', 1234) -> splat('x'), even if x is a variable, and - // independently of what the offset is. -- Value *Val = MSI->getValue(); -+ T *Val = cast(MSI->getValue()); - if (LoadSize != 1) -- Val = Builder.CreateZExt(Val, IntegerType::get(Ctx, LoadSize * 8)); -- -- Value *OneElt = Val; -+ Val = -+ Helper.CreateZExtOrBitCast(Val, IntegerType::get(Ctx, LoadSize * 8)); -+ T *OneElt = Val; - - // Splat the value out to the right number of bits. - for (unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) { - // If we can double the number of bytes set, do it. - if (NumBytesSet * 2 <= LoadSize) { -- Value *ShVal = Builder.CreateShl(Val, NumBytesSet * 8); -- Val = Builder.CreateOr(Val, ShVal); -+ T *ShVal = Helper.CreateShl( -+ Val, ConstantInt::get(Val->getType(), NumBytesSet * 8)); -+ Val = Helper.CreateOr(Val, ShVal); - NumBytesSet <<= 1; - continue; - } - - // Otherwise insert one byte at a time. -- Value *ShVal = Builder.CreateShl(Val, 1 * 8); -- Val = Builder.CreateOr(OneElt, ShVal); -+ T *ShVal = Helper.CreateShl(Val, ConstantInt::get(Val->getType(), 1 * 8)); -+ Val = Helper.CreateOr(OneElt, ShVal); - ++NumBytesSet; - } - -- return coerceAvailableValueToLoadType(Val, LoadTy, Builder, DL); -+ return coerceAvailableValueToLoadTypeHelper(Val, LoadTy, Helper, DL); - } - - // Otherwise, this is a memcpy/memmove from a constant global. -@@ -449,5 +470,27 @@ Value *getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, - Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS)); - return ConstantFoldLoadFromConstPtr(Src, LoadTy, DL); - } -+ -+/// This function is called when we have a -+/// memdep query of a load that ends up being a clobbering mem intrinsic. -+Value *getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, -+ Type *LoadTy, Instruction *InsertPt, -+ const DataLayout &DL) { -+ IRBuilder<> Builder(InsertPt); -+ return getMemInstValueForLoadHelper>(SrcInst, Offset, -+ LoadTy, Builder, DL); -+} -+ -+Constant *getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, -+ Type *LoadTy, const DataLayout &DL) { -+ // The only case analyzeLoadFromClobberingMemInst cannot be converted to a -+ // constant is when it's a memset of a non-constant. -+ if (auto *MSI = dyn_cast(SrcInst)) -+ if (!isa(MSI->getValue())) -+ return nullptr; -+ ConstantFolder F; -+ return getMemInstValueForLoadHelper(SrcInst, Offset, -+ LoadTy, F, DL); -+} - } // namespace VNCoercion - } // namespace llvm --- -2.13.1 - diff --git a/deps/patches/llvm-Yet-another-fix.patch b/deps/patches/llvm-Yet-another-fix.patch deleted file mode 100644 index 39823be1cd918..0000000000000 --- a/deps/patches/llvm-Yet-another-fix.patch +++ /dev/null @@ -1,40 +0,0 @@ -From e92be5eb5c60dfdeb5d41d81c82f0aca0c1e4aa9 Mon Sep 17 00:00:00 2001 -From: Yichao Yu -Date: Sat, 17 Jun 2017 17:29:53 -0400 -Subject: [PATCH] 4.0 fix - ---- - lib/CodeGen/CodeGenPrepare.cpp | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp -index 44d6b3e264c..4177819e989 100644 ---- a/lib/CodeGen/CodeGenPrepare.cpp -+++ b/lib/CodeGen/CodeGenPrepare.cpp -@@ -4067,6 +4067,23 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, - // non-integral pointers, so in that case bail out now. - if (DL->isNonIntegralPointerType(Addr->getType())) - return false; -+ if (AddrMode.BaseReg) { -+ Type *BaseTy = AddrMode.BaseReg->getType(); -+ if (BaseTy->isPointerTy() && DL->isNonIntegralPointerType(BaseTy)) { -+ return false; -+ } -+ } -+ if (AddrMode.Scale) { -+ Type *ScaleTy = AddrMode.ScaledReg->getType(); -+ if (ScaleTy->isPointerTy() && DL->isNonIntegralPointerType(ScaleTy)) { -+ return false; -+ } -+ } -+ if (AddrMode.BaseGV) { -+ if (DL->isNonIntegralPointerType(AddrMode.BaseGV->getType())) { -+ return false; -+ } -+ } - - DEBUG(dbgs() << "CGP: SINKING nonlocal addrmode: " << AddrMode << " for " - << *MemoryInst << "\n"); --- -2.13.1 - diff --git a/deps/patches/llvm-arm-fix-prel31.patch b/deps/patches/llvm-arm-fix-prel31.patch deleted file mode 100644 index a823ce62b0cdb..0000000000000 --- a/deps/patches/llvm-arm-fix-prel31.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 6cef9adffcf9af3c632e58e0d7d4d6e1d0525980 Mon Sep 17 00:00:00 2001 -From: Yichao Yu -Date: Thu, 29 Sep 2016 22:41:57 -0400 -Subject: [PATCH] Fix PREL31 relocation on ARM - -This is a 31bits relative relocation instead of a 32bits absolute relocation. ---- - lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 4 ++++ - .../RuntimeDyld/ARM/ELF_ARM_EXIDX_relocations.s | 23 ++++++++++++++++++++++ - 2 files changed, 27 insertions(+) - create mode 100644 test/ExecutionEngine/RuntimeDyld/ARM/ELF_ARM_EXIDX_relocations.s - -diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp -index 6929732..2e0d168 100644 ---- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp -+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp -@@ -463,7 +463,11 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, - - case ELF::R_ARM_NONE: - break; -+ // Write a 31bit signed offset - case ELF::R_ARM_PREL31: -+ *TargetPtr &= 0x80000000; -+ *TargetPtr |= (Value - FinalAddress) & ~0x80000000; -+ break; - case ELF::R_ARM_TARGET1: - case ELF::R_ARM_ABS32: - *TargetPtr = Value; -diff --git a/test/ExecutionEngine/RuntimeDyld/ARM/ELF_ARM_EXIDX_relocations.s b/test/ExecutionEngine/RuntimeDyld/ARM/ELF_ARM_EXIDX_relocations.s -new file mode 100644 -index 0000000..eb07b00 ---- /dev/null -+++ b/test/ExecutionEngine/RuntimeDyld/ARM/ELF_ARM_EXIDX_relocations.s -@@ -0,0 +1,23 @@ -+# RUN: llvm-mc -triple=arm-linux-gnueabihf -filetype=obj -o %T/reloc.o %s -+# RUN: llvm-rtdyld -triple=arm-linux-gnueabihf -verify -map-section reloc.o,.ARM.exidx=0x6000 -map-section reloc.o,.text=0x4000 -dummy-extern __aeabi_unwind_cpp_pr0=0x1234 -check=%s %T/reloc.o -+ -+ .text -+ .syntax unified -+ .eabi_attribute 67, "2.09" @ Tag_conformance -+ .cpu cortex-a8 -+ .fpu neon -+ .file "reloc.c" -+ .globl g -+ .align 2 -+ .type g,%function -+g: -+ .fnstart -+ movw r0, #1 -+ bx lr -+ .Lfunc_end0: -+ .size g, .Lfunc_end0-g -+ .fnend -+ -+# rtdyld-check: *{4}(section_addr(reloc.o, .ARM.exidx)) = (g - (section_addr(reloc.o, .ARM.exidx))) & 0x7fffffff -+# Compat unwind info: finish(0xb0), finish(0xb0), finish(0xb0) -+# rtdyld-check: *{4}(section_addr(reloc.o, .ARM.exidx) + 0x4) = 0x80b0b0b0 --- -2.10.0 - diff --git a/deps/patches/llvm-loadcse-addrspace_4.0.patch b/deps/patches/llvm-loadcse-addrspace_4.0.patch deleted file mode 100644 index 2728d6830aab0..0000000000000 --- a/deps/patches/llvm-loadcse-addrspace_4.0.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 01ae2614aa184fcf88b0880f5944a23da6f215db Mon Sep 17 00:00:00 2001 -From: Yichao Yu -Date: Sun, 18 Jun 2017 16:45:38 -0400 -Subject: [PATCH] Disable LoadCSE and Store forwarding between different - address space or between non-integral pointer and integers. - ---- - lib/Analysis/Loads.cpp | 30 ++++++++++++++++++++++++++++++ - 1 file changed, 30 insertions(+) - -diff --git a/lib/Analysis/Loads.cpp b/lib/Analysis/Loads.cpp -index e46541e6538..971ce37a4a5 100644 ---- a/lib/Analysis/Loads.cpp -+++ b/lib/Analysis/Loads.cpp -@@ -362,6 +362,21 @@ Value *llvm::FindAvailableLoadedValue(LoadInst *Load, - if (LI->isAtomic() < Load->isAtomic()) - return nullptr; - -+ if (Load->getType()->isPointerTy()) { -+ PointerType *Ty1 = cast(Load->getType()); -+ if (PointerType *Ty2 = dyn_cast(LI->getType())) { -+ if (Ty1->getAddressSpace() != Ty2->getAddressSpace()) { -+ return nullptr; -+ } -+ } -+ else if (DL.isNonIntegralPointerType(Ty1)) { -+ return nullptr; -+ } -+ } -+ else if (DL.isNonIntegralPointerType(LI->getType())) { -+ return nullptr; -+ } -+ - if (IsLoadCSE) - *IsLoadCSE = true; - return LI; -@@ -381,6 +396,21 @@ Value *llvm::FindAvailableLoadedValue(LoadInst *Load, - if (SI->isAtomic() < Load->isAtomic()) - return nullptr; - -+ if (Load->getType()->isPointerTy()) { -+ PointerType *Ty1 = cast(Load->getType()); -+ if (PointerType *Ty2 = dyn_cast(SI->getValueOperand()->getType())) { -+ if (Ty1->getAddressSpace() != Ty2->getAddressSpace()) { -+ return nullptr; -+ } -+ } -+ else if (DL.isNonIntegralPointerType(Ty1)) { -+ return nullptr; -+ } -+ } -+ else if (DL.isNonIntegralPointerType(SI->getValueOperand()->getType())) { -+ return nullptr; -+ } -+ - if (IsLoadCSE) - *IsLoadCSE = false; - return SI->getOperand(0); --- -2.13.1 - diff --git a/deps/patches/llvm-loadcse-addrspace_5.0.patch b/deps/patches/llvm-loadcse-addrspace_5.0.patch deleted file mode 100644 index fccb8bb37281e..0000000000000 --- a/deps/patches/llvm-loadcse-addrspace_5.0.patch +++ /dev/null @@ -1,104 +0,0 @@ -From b252987fe34a314524428d27a85a87fdd746e0b5 Mon Sep 17 00:00:00 2001 -From: Yichao Yu -Date: Sun, 18 Jun 2017 16:45:38 -0400 -Subject: [PATCH 2/4] Disable LoadCSE and Store forwarding between different - address space or between non-integral pointer and integers. - ---- - lib/Analysis/Loads.cpp | 30 +++++++++++++++++++ - .../InstCombine/non-integral-pointers.ll | 34 ++++++++++++++++++++++ - 2 files changed, 64 insertions(+) - -diff --git a/lib/Analysis/Loads.cpp b/lib/Analysis/Loads.cpp -index 591b0fc481d..e9c8be82b03 100644 ---- a/lib/Analysis/Loads.cpp -+++ b/lib/Analysis/Loads.cpp -@@ -380,6 +380,21 @@ Value *llvm::FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy, - if (LI->isAtomic() < AtLeastAtomic) - return nullptr; - -+ if (AccessTy->isPointerTy()) { -+ PointerType *Ty1 = cast(AccessTy); -+ if (PointerType *Ty2 = dyn_cast(LI->getType())) { -+ if (Ty1->getAddressSpace() != Ty2->getAddressSpace()) { -+ return nullptr; -+ } -+ } -+ else if (DL.isNonIntegralPointerType(Ty1)) { -+ return nullptr; -+ } -+ } -+ else if (DL.isNonIntegralPointerType(LI->getType())) { -+ return nullptr; -+ } -+ - if (IsLoadCSE) - *IsLoadCSE = true; - return LI; -@@ -399,6 +414,21 @@ Value *llvm::FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy, - if (SI->isAtomic() < AtLeastAtomic) - return nullptr; - -+ if (AccessTy->isPointerTy()) { -+ PointerType *Ty1 = cast(AccessTy); -+ if (PointerType *Ty2 = dyn_cast(SI->getValueOperand()->getType())) { -+ if (Ty1->getAddressSpace() != Ty2->getAddressSpace()) { -+ return nullptr; -+ } -+ } -+ else if (DL.isNonIntegralPointerType(Ty1)) { -+ return nullptr; -+ } -+ } -+ else if (DL.isNonIntegralPointerType(SI->getValueOperand()->getType())) { -+ return nullptr; -+ } -+ - if (IsLoadCSE) - *IsLoadCSE = false; - return SI->getOperand(0); -diff --git a/test/Transforms/InstCombine/non-integral-pointers.ll b/test/Transforms/InstCombine/non-integral-pointers.ll -index 4f54fe6737d..96a2b2edaf1 100644 ---- a/test/Transforms/InstCombine/non-integral-pointers.ll -+++ b/test/Transforms/InstCombine/non-integral-pointers.ll -@@ -46,3 +46,37 @@ entry: - store i8 addrspace(3)* %val, i8 addrspace(3)** %ptr1 - ret void - } -+ -+define i64 @g(i8 addrspace(4)** %gp) { -+ ; CHECK-LABEL: @g( -+ ; CHECK: load -+ %.pre = load i8 addrspace(4)*, i8 addrspace(4)** %gp, align 8 -+ %v74 = call i8 addrspace(4)* @alloc() -+ %v75 = addrspacecast i8 addrspace(4)* %v74 to i8* -+ %v76 = bitcast i8* %v75 to i8 addrspace(4)** -+ %v77 = getelementptr i8 addrspace(4)*, i8 addrspace(4)** %v76, i64 -1 -+ ; CHECK: store -+ store i8 addrspace(4)* %.pre, i8 addrspace(4)** %v77, align 8 -+ %v80 = bitcast i8 addrspace(4)** %v77 to i64* -+ ; CHECK: load -+ ; CHECK-NOT: ptrtoint -+ %v81 = load i64, i64* %v80, align 8 -+ ret i64 %v81 -+} -+ -+define i64 @g2(i8* addrspace(4)* %gp) { -+ ; CHECK-LABEL: @g2( -+ ; CHECK: load -+ %.pre = load i8*, i8* addrspace(4)* %gp, align 8 -+ %v74 = call i8 addrspace(4)* @alloc() -+ %v76 = bitcast i8 addrspace(4)* %v74 to i8* addrspace(4)* -+ %v77 = getelementptr i8*, i8* addrspace(4)* %v76, i64 -1 -+ ; CHECK: store -+ store i8* %.pre, i8* addrspace(4)* %v77, align 8 -+ %v80 = bitcast i8* addrspace(4)* %v77 to i64 addrspace(4)* -+ ; CHECK-NOT: store -+ %v81 = load i64, i64 addrspace(4)* %v80, align 8 -+ ret i64 %v81 -+} -+ -+declare i8 addrspace(4)* @alloc() --- -2.14.1 - diff --git a/deps/patches/llvm-rL293230-icc17-cmake.patch b/deps/patches/llvm-rL293230-icc17-cmake.patch deleted file mode 100644 index 85b2a2a0b1b9d..0000000000000 --- a/deps/patches/llvm-rL293230-icc17-cmake.patch +++ /dev/null @@ -1,35 +0,0 @@ -From eca8aa608d962e09ea9710670f1c412f608a6f12 Mon Sep 17 00:00:00 2001 -From: Yichao Yu -Date: Thu, 26 Jan 2017 23:50:18 +0000 -Subject: [PATCH] CMake is funky on detecting Intel 17 as GCC compatible. - -Summary: This adds a fallback in case that the Intel compiler is failed to be detected correctly. - -Reviewers: chapuni - -Reviewed By: chapuni - -Subscribers: llvm-commits, mgorny - -Differential Revision: https://reviews.llvm.org/D27610 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293230 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - cmake/modules/DetermineGCCCompatible.cmake | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/cmake/modules/DetermineGCCCompatible.cmake b/cmake/modules/DetermineGCCCompatible.cmake -index 1bf15fcba72..1369ebe9d0e 100644 ---- a/cmake/modules/DetermineGCCCompatible.cmake -+++ b/cmake/modules/DetermineGCCCompatible.cmake -@@ -7,5 +7,7 @@ if(NOT DEFINED LLVM_COMPILER_IS_GCC_COMPATIBLE) - set(LLVM_COMPILER_IS_GCC_COMPATIBLE OFF) - elseif( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) - set(LLVM_COMPILER_IS_GCC_COMPATIBLE ON) -+ elseif( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel" ) -+ set(LLVM_COMPILER_IS_GCC_COMPATIBLE ON) - endif() - endif() --- -2.11.0 - diff --git a/doc/src/devdocs/llvm.md b/doc/src/devdocs/llvm.md index 9ed7da79ba699..bc64345569273 100644 --- a/doc/src/devdocs/llvm.md +++ b/doc/src/devdocs/llvm.md @@ -42,7 +42,7 @@ The default version of LLVM is specified in `deps/Versions.make`. You can overri a file called `Make.user` in the top-level directory and adding a line to it such as: ``` -LLVM_VER = 3.5.0 +LLVM_VER = 6.0.1 ``` Besides the LLVM release numerals, you can also use `LLVM_VER = svn` to build against the latest diff --git a/src/APInt-C.cpp b/src/APInt-C.cpp index 609a086f67411..23ac9678644d8 100644 --- a/src/APInt-C.cpp +++ b/src/APInt-C.cpp @@ -16,10 +16,8 @@ inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align, uint64_t Skew return alignTo(Value, Align, Skew); } -#if JL_LLVM_VERSION >= 50000 const unsigned int integerPartWidth = llvm::APInt::APINT_BITS_PER_WORD; const unsigned int host_char_bit = 8; -#endif /* create "APInt s" from "integerPart *ps" */ #define CREATE(s) \ @@ -351,11 +349,7 @@ void LLVMFPtoInt(unsigned numbits, integerPart *pa, unsigned onumbits, integerPa APFloat::roundingMode rounding_mode = APFloat::rmNearestTiesToEven; unsigned nbytes = RoundUpToAlignment(onumbits, integerPartWidth) / host_char_bit; integerPart *parts = (integerPart*)alloca(nbytes); -#if JL_LLVM_VERSION >= 50000 APFloat::opStatus status = a.convertToInteger(MutableArrayRef(parts, nbytes), onumbits, isSigned, rounding_mode, &isVeryExact); -#else - APFloat::opStatus status = a.convertToInteger(parts, onumbits, isSigned, rounding_mode, &isVeryExact); -#endif memcpy(pr, parts, onumbytes); if (isExact) *isExact = (status == APFloat::opOK); diff --git a/src/APInt-C.h b/src/APInt-C.h index 6aa70380917ef..e71d49e82e99a 100644 --- a/src/APInt-C.h +++ b/src/APInt-C.h @@ -9,11 +9,7 @@ extern "C" { #include "dtypes.h" #ifdef LLVM_VERSION_MAJOR -# if JL_LLVM_VERSION >= 50000 using integerPart = llvm::APInt::WordType; -# else -using llvm::integerPart; -# endif #else typedef void integerPart; #endif diff --git a/src/ccall.cpp b/src/ccall.cpp index 23e8d1c3ad980..a8e41eac6861f 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -206,11 +206,7 @@ static Value *runtime_sym_lookup( // all the arguments without writing assembly directly. // This doesn't matter too much in reality since a single function is usually // not called with multiple signatures. -#if JL_LLVM_VERSION >= 50000 static DenseMap,GlobalVariable*>> allPltMap; @@ -218,11 +214,7 @@ static DenseMap= 50000 const AttributeList &attrs, -#else - const AttributeSet &attrs, -#endif CallingConv::ID cc, const char *f_lib, const char *f_name, GlobalVariable *libptrgv, GlobalVariable *llvmgv, void *symaddr, bool runtime_lib) @@ -262,11 +254,7 @@ static GlobalVariable *emit_plt_thunk( // NoReturn function can trigger LLVM verifier error when declared as // MustTail since other passes might replace the `ret` with // `unreachable` (LLVM should probably accept `unreachable`). -#if JL_LLVM_VERSION >= 50000 if (attrs.hasAttribute(AttributeList::FunctionIndex, -#else - if (attrs.hasAttribute(AttributeSet::FunctionIndex, -#endif Attribute::NoReturn)) { irbuilder.CreateUnreachable(); } @@ -299,11 +287,7 @@ static GlobalVariable *emit_plt_thunk( static Value *emit_plt( jl_codectx_t &ctx, FunctionType *functype, -#if JL_LLVM_VERSION >= 50000 const AttributeList &attrs, -#else - const AttributeSet &attrs, -#endif CallingConv::ID cc, const char *f_lib, const char *f_name) { assert(imaging_mode); @@ -453,11 +437,7 @@ static Value *llvm_type_rewrite( // sizes. Value *from; Value *to; -#if JL_LLVM_VERSION >= 40000 const DataLayout &DL = jl_data_layout; -#else - const DataLayout &DL = jl_ExecutionEngine->getDataLayout(); -#endif if (DL.getTypeAllocSize(target_type) >= DL.getTypeAllocSize(from_type)) { to = emit_static_alloca(ctx, target_type); from = emit_bitcast(ctx, to, from_type->getPointerTo()); @@ -1083,15 +1063,10 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar << jl_string_data(ir) << "\n}"; SMDiagnostic Err = SMDiagnostic(); std::string ir_string = ir_stream.str(); -#if JL_LLVM_VERSION >= 60000 // Do not enable update debug info since it runs the verifier on the whole module // and will error on the function we are currently emitting. bool failed = parseAssemblyInto(llvm::MemoryBufferRef(ir_string, "llvmcall"), *jl_Module, Err, nullptr, /* UpdateDebugInfo */ false); -#else - bool failed = parseAssemblyInto(llvm::MemoryBufferRef(ir_string, "llvmcall"), - *jl_Module, Err); -#endif if (failed) { std::string message = "Failed to parse LLVM Assembly: \n"; llvm::raw_string_ostream stream(message); @@ -1160,11 +1135,7 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar static Value *box_ccall_result(jl_codectx_t &ctx, Value *result, Value *runtime_dt, jl_value_t *rt) { // XXX: need to handle parameterized zero-byte types (singleton) -#if JL_LLVM_VERSION >= 40000 const DataLayout &DL = jl_data_layout; -#else - const DataLayout &DL = jl_ExecutionEngine->getDataLayout(); -#endif unsigned nb = DL.getTypeStoreSize(result->getType()); MDNode *tbaa = jl_is_mutable(rt) ? tbaa_mutab : tbaa_immut; Value *strct = emit_allocobj(ctx, nb, runtime_dt); @@ -1192,11 +1163,7 @@ class function_sig_t { std::vector fargt_isboxed; // vector of whether the llvm output type is a Julia-box for each argument (vararg is the last item, if applicable) Type *fargt_vasig = NULL; // ABI coercion type for vararg list std::vector byRefList; // vector of "byref" parameters (vararg is the last item, if applicable) -#if JL_LLVM_VERSION >= 50000 AttributeList attributes; // vector of function call site attributes (vararg is the last item, if applicable) -#else - AttributeSet attributes; // vector of function call site attributes (vararg is the last item, if applicable) -#endif Type *lrt; // input parameter of the llvm return type (from julia_struct_to_llvm) bool retboxed; // input parameter indicating whether lrt is jl_value_t* Type *prt; // out parameter of the llvm return type for the function signature @@ -1239,11 +1206,7 @@ std::string generate_func_sig(const char *fname) size_t nargt = jl_svec_len(at); assert(rt && !jl_is_abstract_ref_type(rt)); -#if JL_LLVM_VERSION >= 50000 std::vector paramattrs; -#else - std::vector paramattrs; -#endif std::unique_ptr abi; if (llvmcall) abi.reset(new ABI_LLVMLayout()); @@ -1266,11 +1229,7 @@ std::string generate_func_sig(const char *fname) retattrs.addAttribute(Attribute::StructRet); #endif retattrs.addAttribute(Attribute::NoAlias); -#if JL_LLVM_VERSION >= 50000 paramattrs.push_back(std::move(retattrs)); -#else - paramattrs.push_back(AttributeSet::get(jl_LLVMContext, 1, retattrs)); -#endif fargt_sig.push_back(PointerType::get(lrt, 0)); sret = 1; prt = lrt; @@ -1348,11 +1307,7 @@ std::string generate_func_sig(const char *fname) do { // for each arg for which this type applies, add the appropriate LLVM parameter attributes if (i < nargs) { // if vararg, the last declared arg type may not have a corresponding arg value -#if JL_LLVM_VERSION >= 50000 AttributeSet params = AttributeSet::get(jl_LLVMContext, ab); -#else - AttributeSet params = AttributeSet::get(jl_LLVMContext, i + sret + 1, ab); -#endif paramattrs.push_back(params); } i++; @@ -1361,22 +1316,13 @@ std::string generate_func_sig(const char *fname) for (i = 0; i < nargs + sret; ++i) { const auto &as = paramattrs.at(i); -#if JL_LLVM_VERSION >= 50000 if (!as.hasAttributes()) continue; -#else - if (as.isEmpty()) - continue; -#endif attributes = attributes.addAttributes(jl_LLVMContext, i + 1, as); } if (rt == jl_bottom_type) { attributes = attributes.addAttribute(jl_LLVMContext, -#if JL_LLVM_VERSION >= 50000 AttributeList::FunctionIndex, -#else - AttributeSet::FunctionIndex, -#endif Attribute::NoReturn); } return ""; @@ -2091,11 +2037,7 @@ jl_cgval_t function_sig_t::emit_a_ccall( MDNode *tbaa = jl_is_mutable(rt) ? tbaa_mutab : tbaa_immut; int boxalign = jl_datatype_align(rt); // copy the data from the return value to the new struct -#if JL_LLVM_VERSION >= 40000 const DataLayout &DL = jl_data_layout; -#else - const DataLayout &DL = jl_ExecutionEngine->getDataLayout(); -#endif auto resultTy = result->getType(); if (DL.getTypeStoreSize(resultTy) > rtsz) { // ARM and AArch64 can use a LLVM type larger than the julia type. diff --git a/src/cgutils.cpp b/src/cgutils.cpp index c11dc121f9a7c..248cbe4c902e2 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -183,22 +183,12 @@ static DIType *julia_type_to_di(jl_value_t *jt, DIBuilder *dbuilder, bool isboxe return (DIType*)jdt->ditype; if (jl_is_primitivetype(jt)) { uint64_t SizeInBits = jl_datatype_nbits(jdt); -#if JL_LLVM_VERSION >= 40000 llvm::DIType *t = dbuilder->createBasicType( jl_symbol_name(jdt->name->name), SizeInBits, llvm::dwarf::DW_ATE_unsigned); jdt->ditype = t; return t; -#else - llvm::DIType *t = dbuilder->createBasicType( - jl_symbol_name(jdt->name->name), - SizeInBits, - 8 * jl_datatype_align(jdt), - llvm::dwarf::DW_ATE_unsigned); - jdt->ditype = t; - return t; -#endif } if (jl_is_structtype(jt) && jdt->uid && jdt->layout && !jl_is_layout_opaque(jdt->layout)) { size_t ntypes = jl_datatype_nfields(jdt); @@ -241,11 +231,7 @@ static DIType *julia_type_to_di(jl_value_t *jt, DIBuilder *dbuilder, bool isboxe static Value *emit_pointer_from_objref_internal(jl_codectx_t &ctx, Value *V) { CallInst *Call = ctx.builder.CreateCall(prepare_call(pointer_from_objref_func), V); -#if JL_LLVM_VERSION >= 50000 Call->addAttribute(AttributeList::FunctionIndex, Attribute::ReadNone); -#else - Call->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone); -#endif return Call; } @@ -497,12 +483,7 @@ static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua_env, bool *i static unsigned convert_struct_offset(Type *lty, unsigned byte_offset) { - const DataLayout &DL = -#if JL_LLVM_VERSION >= 40000 - jl_data_layout; -#else - jl_ExecutionEngine->getDataLayout(); -#endif + const DataLayout &DL = jl_data_layout; const StructLayout *SL = DL.getStructLayout(cast(lty)); return SL->getElementContainingOffset(byte_offset); } @@ -1373,11 +1354,7 @@ static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, MDNode *tbaa_dst, Va if (sz <= 64) { // The size limit is arbitrary but since we mainly care about floating points and // machine size vectors this should be enough. -#if JL_LLVM_VERSION >= 40000 const DataLayout &DL = jl_data_layout; -#else - const DataLayout &DL = jl_ExecutionEngine->getDataLayout(); -#endif auto srcty = cast(src->getType()); auto srcel = srcty->getElementType(); auto dstty = cast(dst->getType()); @@ -2608,10 +2585,8 @@ static void emit_signal_fence(jl_codectx_t &ctx) // https://llvm.org/bugs/show_bug.cgi?id=27545 ctx.builder.CreateCall(InlineAsm::get(FunctionType::get(T_void, false), "", "~{memory}", true)); -#elif JL_LLVM_VERSION >= 50000 - ctx.builder.CreateFence(AtomicOrdering::SequentiallyConsistent, SyncScope::SingleThread); #else - ctx.builder.CreateFence(AtomicOrdering::SequentiallyConsistent, SingleThread); + ctx.builder.CreateFence(AtomicOrdering::SequentiallyConsistent, SyncScope::SingleThread); #endif } diff --git a/src/codegen.cpp b/src/codegen.cpp index fdfd9bebca3a3..4d00a02d96a11 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -38,11 +38,7 @@ #include // target machine computation -#if JL_LLVM_VERSION >= 60000 #include -#else -#include -#endif #include #include #include @@ -70,11 +66,7 @@ #include // for llvmcall inlining #include #include // for llvmcall validation -#if JL_LLVM_VERSION >= 40000 -# include -#else -# include -#endif +#include // C API #include @@ -112,11 +104,7 @@ namespace llvm { // LLVM version compatibility macros legacy::PassManager *jl_globalPM; -#if JL_LLVM_VERSION >= 40000 #define DIFlagZero (DINode::FlagZero) -#else -#define DIFlagZero (0) -#endif extern "C" { @@ -362,11 +350,7 @@ extern "C" { template static void add_return_attr(T *f, Attribute::AttrKind Kind) { -#if JL_LLVM_VERSION >= 50000 f->addAttribute(AttributeList::ReturnIndex, Kind); -#else - f->addAttribute(AttributeSet::ReturnIndex, Kind); -#endif } static MDNode *best_tbaa(jl_value_t *jt) { @@ -591,9 +575,7 @@ static GlobalVariable *get_pointer_to_constant(Constant *val, StringRef name, Mo static AllocaInst *emit_static_alloca(jl_codectx_t &ctx, Type *lty, int arraysize=1) { return new AllocaInst(lty, -#if JL_LLVM_VERSION >= 50000 0, -#endif ConstantInt::get(T_int32, arraysize), "", /*InsertBefore=*/ctx.ptlsStates); } @@ -1274,11 +1256,7 @@ static void jl_setup_module(Module *m, const jl_cgparams_t *params = &jl_default if (!getModuleFlag(m,"Debug Info Version")) m->addModuleFlag(llvm::Module::Error, "Debug Info Version", llvm::DEBUG_METADATA_VERSION); -#if JL_LLVM_VERSION >= 40000 m->setDataLayout(jl_data_layout); -#else - m->setDataLayout(jl_ExecutionEngine->getDataLayout()); -#endif m->setTargetTriple(jl_TargetMachine->getTargetTriple().str()); } @@ -1311,13 +1289,9 @@ uint64_t jl_get_llvm_fptr(void *function) Function *F = (Function*)function; uint64_t addr = getAddressForFunction(F->getName()); if (!addr) { -#if JL_LLVM_VERSION >= 50000 if (auto exp_addr = jl_ExecutionEngine->findUnmangledSymbol(F->getName()).getAddress()) { addr = exp_addr.get(); } -#else - addr = jl_ExecutionEngine->findUnmangledSymbol(F->getName()).getAddress(); -#endif } return addr; } @@ -3387,11 +3361,7 @@ static jl_cgval_t emit_varinfo(jl_codectx_t &ctx, jl_varinfo_t &vi, jl_sym_t *va ctx.builder.CreateStore(unbox, ssaslot); } else { -#if JL_LLVM_VERSION >= 40000 const DataLayout &DL = jl_data_layout; -#else - const DataLayout &DL = jl_ExecutionEngine->getDataLayout(); -#endif uint64_t sz = DL.getTypeStoreSize(T); emit_memcpy(ctx, ssaslot, tbaa_stack, vi.value, sz, al); } @@ -4270,11 +4240,7 @@ static Function* gen_cfun_wrapper( M = new Module(name, jl_LLVMContext); jl_setup_module(M); } -#if JL_LLVM_VERSION >= 50000 AttributeList attributes = sig.attributes; -#else - AttributeSet attributes = sig.attributes; -#endif FunctionType *functype; if (nest) { // add nest parameter (pointer to jl_value_t* data array) after sret arg @@ -5168,11 +5134,7 @@ static jl_returninfo_t get_specsig_function(Module *M, const std::string &name, rt = T_prjlvalue; } } -#if JL_LLVM_VERSION >= 50000 AttributeList attributes; // function declaration attributes -#else - AttributeSet attributes; // function declaration attributes -#endif if (props.cc == jl_returninfo_t::SRet) { attributes = attributes.addAttribute(jl_LLVMContext, 1, Attribute::StructRet); attributes = attributes.addAttribute(jl_LLVMContext, 1, Attribute::NoAlias); @@ -5445,13 +5407,7 @@ static std::unique_ptr emit_function( // i686 Windows (which uses a 4-byte-aligned stack) AttrBuilder *attr = new AttrBuilder(); attr->addStackAlignmentAttr(16); -#if JL_LLVM_VERSION >= 50000 f->addAttributes(AttributeList::FunctionIndex, *attr); -#else - f->addAttributes(AttributeSet::FunctionIndex, - AttributeSet::get(f->getContext(), - AttributeSet::FunctionIndex, *attr)); -#endif #endif #if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_) f->setHasUWTable(); // force NeedsWinEH @@ -5485,12 +5441,7 @@ static std::unique_ptr emit_function( if (ctx.debug_enabled) { // TODO: Fix when moving to new LLVM version topfile = dbuilder.createFile(filename, "."); -#if JL_LLVM_VERSION >= 40000 DICompileUnit *CU = dbuilder.createCompileUnit(0x01, topfile, "julia", true, "", 0); -#else - DICompileUnit *CU = dbuilder.createCompileUnit(0x01, filename, ".", "julia", true, "", 0); -#endif - DISubroutineType *subrty; if (jl_options.debug_level <= 1) { subrty = jl_di_func_null_sig; @@ -5666,11 +5617,7 @@ static std::unique_ptr emit_function( specsig || // for arguments, give them stack slots if they aren't in `argArray` (otherwise, will use that pointer) (va && (int)i == ctx.vaSlot) || // or it's the va arg tuple i == 0) { // or it is the first argument (which isn't in `argArray`) -#if JL_LLVM_VERSION >= 50000 AllocaInst *av = new AllocaInst(T_prjlvalue, 0, -#else - AllocaInst *av = new AllocaInst(T_prjlvalue, -#endif jl_symbol_name(s), /*InsertBefore*/ctx.ptlsStates); StoreInst *SI = new StoreInst( ConstantPointerNull::get(cast(T_prjlvalue)), av, @@ -5790,11 +5737,7 @@ static std::unique_ptr emit_function( if (ctx.debug_enabled && vi.dinfo && !vi.boxroot && !vi.value.V) { SmallVector addr; addr.push_back(llvm::dwarf::DW_OP_deref); -#if JL_LLVM_VERSION >= 50000 addr.push_back(llvm::dwarf::DW_OP_plus_uconst); -#else - addr.push_back(llvm::dwarf::DW_OP_plus); -#endif addr.push_back((i - 1) * sizeof(void*)); if ((Metadata*)vi.dinfo->getType() != jl_pvalue_dillvmt) addr.push_back(llvm::dwarf::DW_OP_deref); @@ -7416,8 +7359,6 @@ extern "C" void *jl_init_llvm(void) // Make sure we are using the large code model on 64bit // Let LLVM pick a default suitable for jitting on 32bit .setCodeModel(CodeModel::Large) -#elif JL_LLVM_VERSION < 60000 - .setCodeModel(CodeModel::JITDefault) #endif #ifdef DISABLE_OPT .setOptLevel(CodeGenOpt::None) @@ -7464,12 +7405,10 @@ extern "C" void *jl_init_llvm(void) init_julia_llvm_meta(); jl_ExecutionEngine = new JuliaOJIT(*jl_TargetMachine); -// Mark our address spaces as non-integral -#if JL_LLVM_VERSION >= 40000 + // Mark our address spaces as non-integral jl_data_layout = jl_ExecutionEngine->getDataLayout(); std::string DL = jl_data_layout.getStringRepresentation() + "-ni:10:11:12:13"; jl_data_layout.reset(DL); -#endif // Register GDB event listener #ifdef JL_DEBUG_BUILD diff --git a/src/codegen_shared.h b/src/codegen_shared.h index d93b2de8e8a9c..b7b57a3b715a9 100644 --- a/src/codegen_shared.h +++ b/src/codegen_shared.h @@ -18,58 +18,34 @@ enum AddressSpace { static inline void llvm_dump(llvm::Value *v) { -#if JL_LLVM_VERSION >= 50000 v->print(llvm::dbgs(), true); llvm::dbgs() << "\n"; -#else - v->dump(); -#endif } static inline void llvm_dump(llvm::Type *v) { -#if JL_LLVM_VERSION >= 50000 v->print(llvm::dbgs(), true); -#else - v->dump(); -#endif llvm::dbgs() << "\n"; } static inline void llvm_dump(llvm::Function *f) { -#if JL_LLVM_VERSION >= 50000 f->print(llvm::dbgs(), nullptr, false, true); -#else - f->dump(); -#endif } static inline void llvm_dump(llvm::Module *m) { -#if JL_LLVM_VERSION >= 50000 m->print(llvm::dbgs(), nullptr); -#else - m->dump(); -#endif } static inline void llvm_dump(llvm::Metadata *m) { -#if JL_LLVM_VERSION >= 50000 m->print(llvm::dbgs()); llvm::dbgs() << "\n"; -#else - m->dump(); -#endif } static inline void llvm_dump(llvm::DebugLoc *dbg) { -#if JL_LLVM_VERSION >= 50000 dbg->print(llvm::dbgs()); -#else - dbg->dump(); -#endif llvm::dbgs() << "\n"; } diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index 15c33f86524cd..737508301776a 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -16,20 +16,14 @@ #include #include #include -#if JL_LLVM_VERSION >= 50000 #include -#endif #include #include #include using namespace llvm; -#if JL_LLVM_VERSION >= 50000 using llvm_file_magic = file_magic; -#else -using llvm_file_magic = sys::fs::file_magic; -#endif #include "julia.h" #include "julia_internal.h" @@ -404,11 +398,7 @@ class JuliaJITEventListener: public JITEventListener ObjectInfo tmp = {&debugObj, (size_t)SectionSize, (ptrdiff_t)(SectionAddr - SectionLoadAddr), -#if JL_LLVM_VERSION >= 60000 DWARFContext::create(debugObj, &L).release(), -#else - new DWARFContextInMemory(debugObj, &L), -#endif }; objectmap[SectionLoadAddr] = tmp; first = false; @@ -948,11 +938,7 @@ static objfileentry_t &find_object_file(uint64_t fbase, StringRef fname) slide = -(int64_t)fbase; } -#if JL_LLVM_VERSION >= 60000 auto context = DWARFContext::create(*debugobj).release(); -#else - auto context = new DWARFContextInMemory(*debugobj); -#endif auto binary = errorobj->takeBinary(); binary.first.release(); binary.second.release(); diff --git a/src/disasm.cpp b/src/disasm.cpp index c7f74765cba65..e72000da83a57 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -28,13 +28,8 @@ #include "llvm-version.h" #include -#if JL_LLVM_VERSION >= 50000 #include #include -#else -#include -#include -#endif #include #include #include @@ -650,12 +645,7 @@ static void jl_dump_asm_internal( std::unique_ptr MOFI(new MCObjectFileInfo()); MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr); -#if JL_LLVM_VERSION >= 60000 MOFI->InitMCObjectFileInfo(TheTriple, /* PIC */ false, Ctx); -#else - MOFI->InitMCObjectFileInfo(TheTriple, /* PIC */ false, - CodeModel::Default, Ctx); -#endif // Set up Subtarget and Disassembler std::unique_ptr @@ -683,15 +673,8 @@ static void jl_dump_asm_internal( MCAsmBackend *MAB = 0; if (ShowEncoding) { CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); -#if JL_LLVM_VERSION >= 60000 MCTargetOptions Options; MAB = TheTarget->createMCAsmBackend(*STI, *MRI, Options); -#elif JL_LLVM_VERSION >= 40000 - MCTargetOptions Options; - MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, cpu, Options); -#else - MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, cpu); -#endif } // createAsmStreamer expects a unique_ptr to a formatted stream, which means diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index eec4cf75f524b..50ace324ea313 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -281,11 +281,7 @@ static Value *emit_unboxed_coercion(jl_codectx_t &ctx, Type *to, Value *unboxed) Type *ty = unboxed->getType(); bool frompointer = ty->isPointerTy(); bool topointer = to->isPointerTy(); -#if JL_LLVM_VERSION >= 40000 const DataLayout &DL = jl_data_layout; -#else - const DataLayout &DL = jl_ExecutionEngine->getDataLayout(); -#endif if (ty == T_int1 && to == T_int8) { // bools may be stored internally as int8 unboxed = ctx.builder.CreateZExt(unboxed, T_int8); @@ -381,11 +377,7 @@ static Value *emit_unbox(jl_codectx_t &ctx, Type *to, const jl_cgval_t &x, jl_va // appropriate coercion manually. AllocaInst *AI = cast(p); Type *AllocType = AI->getAllocatedType(); -#if JL_LLVM_VERSION >= 40000 const DataLayout &DL = jl_data_layout; -#else - const DataLayout &DL = jl_ExecutionEngine->getDataLayout(); -#endif if (!AI->isArrayAllocation() && (AllocType->isFloatingPointTy() || AllocType->isIntegerTy() || AllocType->isPointerTy()) && (to->isFloatingPointTy() || to->isIntegerTy() || to->isPointerTy()) && @@ -755,18 +747,10 @@ struct math_builder { if (jl_options.fast_math != JL_OPTIONS_FAST_MATH_OFF && (always_fast || jl_options.fast_math == JL_OPTIONS_FAST_MATH_ON)) { -#if JL_LLVM_VERSION >= 60000 fmf.setFast(); -#else - fmf.setUnsafeAlgebra(); -#endif } -#if JL_LLVM_VERSION >= 50000 if (contract) fmf.setAllowContract(true); -#else - assert(!contract); -#endif ctxbuilder.setFastMathFlags(fmf); } IRBuilder<>& operator()() const { return ctxbuilder; } @@ -1079,18 +1063,11 @@ static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **arg return ctx.builder.CreateCall(fmaintr, {x, y, z}); } case muladd_float: { -#if JL_LLVM_VERSION >= 50000 // LLVM 5.0 can create FMA in the backend for contractable fmul and fadd // Emitting fmul and fadd here since they are easier for other LLVM passes to // optimize. auto mathb = math_builder(ctx, false, true); return mathb().CreateFAdd(mathb().CreateFMul(x, y), z); -#else - assert(y->getType() == x->getType()); - assert(z->getType() == y->getType()); - Value *muladdintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::fmuladd, makeArrayRef(t)); - return ctx.builder.CreateCall(muladdintr, {x, y, z}); -#endif } case checked_sadd_int: diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 1a5a02f670b50..f47a2d28a001b 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -28,19 +28,13 @@ #include #include #include -#if JL_LLVM_VERSION >= 40000 #include -#endif namespace llvm { extern Pass *createLowerSimdLoopPass(); } -#if JL_LLVM_VERSION >= 40000 -# include -#else -# include -#endif +#include #include #include @@ -117,27 +111,13 @@ void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level, bool dump PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. PM->add(createEarlyCSEPass()); } -#if JL_LLVM_VERSION < 50000 - PM->add(createBarrierNoopPass()); - PM->add(createLowerExcHandlersPass()); - PM->add(createGCInvariantVerifierPass(false)); - PM->add(createLateLowerGCFramePass()); - PM->add(createLowerPTLSPass(dump_native)); - PM->add(createBarrierNoopPass()); -#endif PM->add(createMemCpyOptPass()); // Remove memcpy / form memset -#if JL_LLVM_VERSION >= 40000 PM->add(createAlwaysInlinerLegacyPass()); // Respect always_inline -#else - PM->add(createAlwaysInlinerPass()); // Respect always_inline -#endif -#if JL_LLVM_VERSION >= 50000 PM->add(createBarrierNoopPass()); PM->add(createLowerExcHandlersPass()); PM->add(createGCInvariantVerifierPass(false)); PM->add(createLateLowerGCFramePass()); PM->add(createLowerPTLSPass(dump_native)); -#endif PM->add(createLowerSimdLoopPass()); // Annotate loop marked with "simdloop" as LLVM parallel loop if (dump_native) PM->add(createMultiVersioningPass()); @@ -153,32 +133,14 @@ void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level, bool dump PM->add(createDeadCodeEliminationPass()); PM->add(createSROAPass()); // Kill useless allocas - // Due to bugs and missing features LLVM < 5.0, does not properly propagate - // our invariants. We need to do GC rooting here. This reduces the - // effectiveness of the optimization, but should retain correctness. -#if JL_LLVM_VERSION < 50000 - PM->add(createLowerExcHandlersPass()); - PM->add(createAllocOptPass()); - PM->add(createLateLowerGCFramePass()); - // Remove dead use of ptls - PM->add(createDeadCodeEliminationPass()); - PM->add(createLowerPTLSPass(dump_native)); -#endif - PM->add(createMemCpyOptPass()); -#if JL_LLVM_VERSION >= 40000 PM->add(createAlwaysInlinerLegacyPass()); // Respect always_inline -#else - PM->add(createAlwaysInlinerPass()); // Respect always_inline -#endif -#if JL_LLVM_VERSION >= 50000 // Running `memcpyopt` between this and `sroa` seems to give `sroa` a hard time // merging the `alloca` for the unboxed data and the `alloca` created by the `alloc_opt` // pass. PM->add(createAllocOptPass()); -#endif PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. // Now that SROA has cleaned up for front-end mess, a lot of control flow should // be more evident - try to clean it up. @@ -198,11 +160,9 @@ void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level, bool dump PM->add(createEarlyCSEPass()); //// **** -#if JL_LLVM_VERSION >= 50000 // Load forwarding above can expose allocations that aren't actually used // remove those before optimizing loops. PM->add(createAllocOptPass()); -#endif PM->add(createLoopIdiomPass()); //// **** PM->add(createLoopRotatePass()); // Rotate loops. #ifdef USE_POLLY @@ -225,10 +185,8 @@ void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level, bool dump PM->add(createSimpleLoopUnrollPass()); // Unroll small loops //PM->add(createLoopStrengthReducePass()); // (jwb added) -#if JL_LLVM_VERSION >= 50000 // Run our own SROA on heap objects before LLVM's PM->add(createAllocOptPass()); -#endif // Re-run SROA after loop-unrolling (useful for small loops that operate, // over the structure of an aggregate) PM->add(createSROAPass()); // Break up aggregate allocas @@ -245,10 +203,8 @@ void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level, bool dump PM->add(createJumpThreadingPass()); // Thread jumps PM->add(createDeadStoreEliminationPass()); // Delete dead stores -#if JL_LLVM_VERSION >= 50000 // More dead allocation (store) deletion before loop optimization PM->add(createAllocOptPass()); -#endif // see if all of the constant folding has exposed more loops // to simplification and deletion // this helps significantly with cleaning up iteration @@ -264,7 +220,6 @@ void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level, bool dump // LowerPTLS removes an indirect call. As a result, it is likely to trigger // LLVM's devirtualization heuristics, which would result in the entire // pass pipeline being re-exectuted. Prevent this by inserting a barrier. -#if JL_LLVM_VERSION >= 50000 PM->add(createBarrierNoopPass()); PM->add(createLowerExcHandlersPass()); PM->add(createGCInvariantVerifierPass(false)); @@ -274,7 +229,6 @@ void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level, bool dump PM->add(createLowerPTLSPass(dump_native)); // Clean up write barrier and ptls lowering PM->add(createCFGSimplificationPass()); -#endif PM->add(createCombineMulAddPass()); } @@ -360,11 +314,7 @@ void JuliaOJIT::DebugObjectRegistrar::registerObject(RTDyldObjHandleT H, const O // note: calling getAddress here eagerly finalizes H // as an alternative, we could store the JITSymbol instead // (which would present a lazy-initializer functor interface instead) -#if JL_LLVM_VERSION >= 50000 JIT.LocalSymbolTable[Name] = (void*)(uintptr_t)cantFail(Sym.getAddress()); -#else - JIT.LocalSymbolTable[Name] = (void*)(uintptr_t)Sym.getAddress(); -#endif } } @@ -372,19 +322,8 @@ template void JuliaOJIT::DebugObjectRegistrar::operator()(RTDyldObjHandleT H, const ObjSetT &Objects, const LoadResult &LOS) { -#if JL_LLVM_VERSION >= 50000 registerObject(H, Objects->getBinary(), static_cast(&LOS)); -#else - auto oit = Objects.begin(); - auto lit = LOS.begin(); - for (; oit != Objects.end(); ++oit, ++lit) { - const auto &Object = (*oit)->getBinary(); - auto &LO = *lit; - - registerObject(H, Object, LO); - } -#endif } @@ -416,9 +355,7 @@ JuliaOJIT::JuliaOJIT(TargetMachine &TM) MemMgr(createRTDyldMemoryManager()), registrar(*this), ObjectLayer( -#if JL_LLVM_VERSION >= 50000 [&] { return MemMgr; }, -#endif std::ref(registrar) ), CompileLayer( @@ -496,14 +433,9 @@ void JuliaOJIT::addModule(std::unique_ptr M) // Step 0: ObjectLinkingLayer has checked whether it is in the current module // Step 1: See if it's something known to the ExecutionEngine if (auto Sym = findSymbol(Name, true)) { -#if JL_LLVM_VERSION >= 40000 // `findSymbol` already eagerly resolved the address // return it directly. return Sym; -#else - return RuntimeDyld::SymbolInfo(Sym.getAddress(), - Sym.getFlags()); -#endif } // Step 2: Search the program symbols if (uint64_t addr = SectionMemoryManager::getSymbolAddressInProcess(Name)) @@ -517,32 +449,17 @@ void JuliaOJIT::addModule(std::unique_ptr M) }, [](const std::string &S) { return nullptr; } ); -#if JL_LLVM_VERSION >= 50000 auto modset = cantFail(CompileLayer.addModule(std::move(M), std::move(Resolver))); -#else - SmallVector,1> Ms; - Ms.push_back(std::move(M)); - auto modset = CompileLayer.addModuleSet(std::move(Ms), MemMgr.get(), - std::move(Resolver)); -#endif // Force LLVM to emit the module so that we can register the symbols // in our lookup table. -#if JL_LLVM_VERSION >= 50000 auto Err = CompileLayer.emitAndFinalize(modset); // Check for errors to prevent LLVM from crashing the program. assert(!Err); -#else - CompileLayer.emitAndFinalize(modset); -#endif } void JuliaOJIT::removeModule(ModuleHandleT H) { -#if JL_LLVM_VERSION >= 50000 (void)CompileLayer.removeModule(H); -#else - (void)CompileLayer.removeModuleSet(H); -#endif } JL_JITSymbol JuliaOJIT::findSymbol(const std::string &Name, bool ExportedSymbolsOnly) @@ -565,22 +482,14 @@ JL_JITSymbol JuliaOJIT::findUnmangledSymbol(const std::string Name) uint64_t JuliaOJIT::getGlobalValueAddress(const std::string &Name) { -#if JL_LLVM_VERSION >= 50000 auto addr = findSymbol(getMangledName(Name), false).getAddress(); return addr ? addr.get() : 0; -#else - return findSymbol(getMangledName(Name), false).getAddress(); -#endif } uint64_t JuliaOJIT::getFunctionAddress(const std::string &Name) { -#if JL_LLVM_VERSION >= 50000 auto addr = findSymbol(getMangledName(Name), false).getAddress(); return addr ? addr.get() : 0; -#else - return findSymbol(getMangledName(Name), false).getAddress(); -#endif } Function *JuliaOJIT::FindFunctionNamed(const std::string &Name) @@ -967,39 +876,15 @@ static void emit_result(std::vector &Archive, SmallVectorImpl< static object::Archive::Kind getDefaultForHost(Triple &triple) { if (triple.isOSDarwin()) -#if JL_LLVM_VERSION >= 50000 return object::Archive::K_DARWIN; -#else - return object::Archive::K_BSD; -#endif return object::Archive::K_GNU; } -#if JL_LLVM_VERSION >= 60000 typedef Error ArchiveWriterError; -#else -typedef std::pair ArchiveWriterError; -template -static void handleAllErrors(ArchiveWriterError E, HandlerT Handler) { - if (E.second) - Handler(E); -} -#endif -#if JL_LLVM_VERSION >= 60000 static void reportWriterError(const ErrorInfoBase &E) { std::string err = E.message(); jl_safe_printf("ERROR: failed to emit output file %s\n", err.c_str()); } -#else -static void reportWriterError(ArchiveWriterError E) { - std::string ContextStr = E.first.str(); - std::string err; - if (!ContextStr.empty()) - err += ContextStr + ": "; - err += E.second.message(); - jl_safe_printf("ERROR: failed to emit output file %s\n", err.c_str()); -} -#endif // takes the running content that has collected in the shadow module and dump it to disk // this builds the object file portion of the sysimage files for fast startup @@ -1066,13 +951,9 @@ void jl_dump_native(const char *bc_fname, const char *unopt_bc_fname, const char // Reset the target triple to make sure it matches the new target machine shadow_output->setTargetTriple(TM->getTargetTriple().str()); -#if JL_LLVM_VERSION >= 40000 DataLayout DL = TM->createDataLayout(); DL.reset(DL.getStringRepresentation() + "-ni:10:11:12:13"); shadow_output->setDataLayout(DL); -#else - shadow_output->setDataLayout(TM->createDataLayout()); -#endif // add metadata information if (imaging_mode) { diff --git a/src/jitlayers.h b/src/jitlayers.h index 6696a69088d90..6f4b8ef5c7b1c 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -10,11 +10,7 @@ #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" #include "llvm/ExecutionEngine/Orc/LambdaResolver.h" #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h" -#if JL_LLVM_VERSION >= 50000 -# include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" -#else -# include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" -#endif +#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" #include "llvm/ExecutionEngine/ObjectMemoryBuffer.h" #include "llvm/ExecutionEngine/JITEventListener.h" @@ -85,21 +81,12 @@ static inline void add_named_global(GlobalObject *gv, T *addr, bool dllimport = } void jl_init_jit(Type *T_pjlvalue_); -#if JL_LLVM_VERSION >= 40000 typedef JITSymbol JL_JITSymbol; // The type that is similar to SymbolInfo on LLVM 4.0 is actually // `JITEvaluatedSymbol`. However, we only use this type when a JITSymbol // is expected. typedef JITSymbol JL_SymbolInfo; -#else -typedef orc::JITSymbol JL_JITSymbol; -typedef RuntimeDyld::SymbolInfo JL_SymbolInfo; -#endif -#if JL_LLVM_VERSION >= 50000 using RTDyldObjHandleT = orc::RTDyldObjectLinkingLayerBase::ObjHandleT; -#else -using RTDyldObjHandleT = orc::ObjectLinkingLayerBase::ObjSetHandleT; -#endif class JuliaOJIT { // Custom object emission notification handler for the JuliaOJIT @@ -126,15 +113,9 @@ class JuliaOJIT { }; public: -#if JL_LLVM_VERSION >= 50000 typedef orc::RTDyldObjectLinkingLayer ObjLayerT; typedef orc::IRCompileLayer CompileLayerT; typedef CompileLayerT::ModuleHandleT ModuleHandleT; -#else - typedef orc::ObjectLinkingLayer> ObjLayerT; - typedef orc::IRCompileLayer CompileLayerT; - typedef CompileLayerT::ModuleSetHandleT ModuleHandleT; -#endif typedef StringMap SymbolTableT; typedef object::OwningBinary OwningObj; diff --git a/src/llvm-alloc-opt.cpp b/src/llvm-alloc-opt.cpp index f1f682afd1244..0b620092e94fb 100644 --- a/src/llvm-alloc-opt.cpp +++ b/src/llvm-alloc-opt.cpp @@ -37,27 +37,12 @@ namespace { static void copyMetadata(Instruction *dest, const Instruction *src) { -#if JL_LLVM_VERSION < 40000 - if (!src->hasMetadata()) - return; - SmallVector,4> TheMDs; - src->getAllMetadataOtherThanDebugLoc(TheMDs); - for (const auto &MD : TheMDs) - dest->setMetadata(MD.first, MD.second); - dest->setDebugLoc(src->getDebugLoc()); -#else dest->copyMetadata(*src); -#endif } static bool isBundleOperand(CallInst *call, unsigned idx) { -#if JL_LLVM_VERSION < 40000 - return call->hasOperandBundles() && idx >= call->getBundleOperandsStartIndex() && - idx < call->getBundleOperandsEndIndex(); -#else return call->isBundleOperand(idx); -#endif } static void removeGCPreserve(CallInst *call, Instruction *val) @@ -908,15 +893,8 @@ void Optimizer::replaceIntrinsicUseWith(IntrinsicInst *call, Intrinsic::ID ID, auto newCall = CallInst::Create(newF, args, "", call); newCall->setTailCallKind(call->getTailCallKind()); auto old_attrs = call->getAttributes(); -#if JL_LLVM_VERSION >= 50000 newCall->setAttributes(AttributeList::get(*pass.ctx, old_attrs.getFnAttributes(), old_attrs.getRetAttributes(), {})); -#else - AttributeSet attr; - attr = attr.addAttributes(*pass.ctx, AttributeSet::ReturnIndex, old_attrs.getRetAttributes()) - .addAttributes(*pass.ctx, AttributeSet::FunctionIndex, old_attrs.getFnAttributes()); - newCall->setAttributes(attr); -#endif newCall->setDebugLoc(call->getDebugLoc()); call->replaceAllUsesWith(newCall); call->eraseFromParent(); @@ -1477,13 +1455,8 @@ bool AllocOpt::doInitialization(Module &M) T_size = sizeof(void*) == 8 ? T_int64 : T_int32; T_pint8 = PointerType::get(T_int8, 0); -#if JL_LLVM_VERSION >= 50000 lifetime_start = Intrinsic::getDeclaration(&M, Intrinsic::lifetime_start, { T_pint8 }); lifetime_end = Intrinsic::getDeclaration(&M, Intrinsic::lifetime_end, { T_pint8 }); -#else - lifetime_start = Intrinsic::getDeclaration(&M, Intrinsic::lifetime_start); - lifetime_end = Intrinsic::getDeclaration(&M, Intrinsic::lifetime_end); -#endif MDNode *tbaa_data; MDNode *tbaa_data_scalar; diff --git a/src/llvm-lower-handlers.cpp b/src/llvm-lower-handlers.cpp index 5caee2b1998bb..b4beddb480fc1 100644 --- a/src/llvm-lower-handlers.cpp +++ b/src/llvm-lower-handlers.cpp @@ -115,14 +115,9 @@ bool LowerExcHandlers::doInitialization(Module &M) { jlenter_func = M.getFunction("jl_enter_handler"); setjmp_func = M.getFunction(jl_setjmp_name); -#if JL_LLVM_VERSION >= 50000 auto T_pint8 = Type::getInt8PtrTy(M.getContext(), 0); lifetime_start = Intrinsic::getDeclaration(&M, Intrinsic::lifetime_start, { T_pint8 }); lifetime_end = Intrinsic::getDeclaration(&M, Intrinsic::lifetime_end, { T_pint8 }); -#else - lifetime_start = Intrinsic::getDeclaration(&M, Intrinsic::lifetime_start); - lifetime_end = Intrinsic::getDeclaration(&M, Intrinsic::lifetime_end); -#endif return true; } @@ -184,9 +179,7 @@ bool LowerExcHandlers::runOnFunction(Function &F) { std::vector buffs; for (int i = 0; i < MaxDepth; ++i) { auto *buff = new AllocaInst(Type::getInt8Ty(F.getContext()), -#if JL_LLVM_VERSION >= 50000 0, -#endif handler_sz, "", firstInst); buff->setAlignment(16); buffs.push_back(buff); diff --git a/src/llvm-muladd.cpp b/src/llvm-muladd.cpp index b426035ce99ca..b054d2ab58e03 100644 --- a/src/llvm-muladd.cpp +++ b/src/llvm-muladd.cpp @@ -49,37 +49,11 @@ static bool checkCombine(Module *m, Instruction *addOp, Value *maybeMul, Value * return false; if (!mulOp->hasOneUse()) return false; -#if JL_LLVM_VERSION >= 50000 // On 5.0+ we only need to mark the mulOp as contract and the backend will do the work for us. auto fmf = mulOp->getFastMathFlags(); fmf.setAllowContract(true); mulOp->copyFastMathFlags(fmf); return false; -#else - IRBuilder<> builder(m->getContext()); - builder.SetInsertPoint(addOp); - auto mul1 = mulOp->getOperand(0); - auto mul2 = mulOp->getOperand(1); - Value *muladdf = Intrinsic::getDeclaration(m, Intrinsic::fmuladd, addOp->getType()); - if (negadd) { - auto newaddend = builder.CreateFNeg(addend); - // Might be a const - if (auto neginst = dyn_cast(newaddend)) - neginst->setHasUnsafeAlgebra(true); - addend = newaddend; - } - Instruction *newv = builder.CreateCall(muladdf, {mul1, mul2, addend}); - newv->setHasUnsafeAlgebra(true); - if (negres) { - // Shouldn't be a constant - newv = cast(builder.CreateFNeg(newv)); - newv->setHasUnsafeAlgebra(true); - } - addOp->replaceAllUsesWith(newv); - addOp->eraseFromParent(); - mulOp->eraseFromParent(); - return true; -#endif } bool CombineMulAdd::runOnFunction(Function &F) @@ -91,22 +65,14 @@ bool CombineMulAdd::runOnFunction(Function &F) it++; switch (I.getOpcode()) { case Instruction::FAdd: { -#if JL_LLVM_VERSION >= 60000 if (!I.isFast()) -#else - if (!I.hasUnsafeAlgebra()) -#endif continue; checkCombine(m, &I, I.getOperand(0), I.getOperand(1), false, false) || checkCombine(m, &I, I.getOperand(1), I.getOperand(0), false, false); break; } case Instruction::FSub: { -#if JL_LLVM_VERSION >= 60000 if (!I.isFast()) -#else - if (!I.hasUnsafeAlgebra()) -#endif continue; checkCombine(m, &I, I.getOperand(0), I.getOperand(1), true, false) || checkCombine(m, &I, I.getOperand(1), I.getOperand(0), true, true); diff --git a/src/llvm-ptls.cpp b/src/llvm-ptls.cpp index 455a251d98ba6..f09df11cd13c7 100644 --- a/src/llvm-ptls.cpp +++ b/src/llvm-ptls.cpp @@ -70,13 +70,8 @@ struct LowerPTLS: public ModulePass { #ifdef JULIA_ENABLE_THREADING void LowerPTLS::set_ptls_attrs(CallInst *ptlsStates) const { -#if JL_LLVM_VERSION >= 50000 ptlsStates->addAttribute(AttributeList::FunctionIndex, Attribute::ReadNone); ptlsStates->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind); -#else - ptlsStates->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone); - ptlsStates->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); -#endif } Instruction *LowerPTLS::emit_ptls_tp(Value *offset, Instruction *insertBefore) const diff --git a/src/llvm-simdloop.cpp b/src/llvm-simdloop.cpp index 683d41d57cc68..dbafcf265d03d 100644 --- a/src/llvm-simdloop.cpp +++ b/src/llvm-simdloop.cpp @@ -164,11 +164,7 @@ void LowerSIMDLoop::enableUnsafeAlgebraIfReduction(PHINode *Phi, Loop *L) const } for (chainVector::const_iterator K=chain.begin(); K!=chain.end(); ++K) { DEBUG(dbgs() << "LSL: marking " << **K << "\n"); -#if JL_LLVM_VERSION >= 60000 (*K)->setFast(true); -#else - (*K)->setHasUnsafeAlgebra(true); -#endif } } diff --git a/src/llvm-version.h b/src/llvm-version.h index fa1dbcf433e21..1572484c09b50 100644 --- a/src/llvm-version.h +++ b/src/llvm-version.h @@ -9,6 +9,6 @@ #define JL_LLVM_VERSION (LLVM_VERSION_MAJOR * 10000 + LLVM_VERSION_MINOR * 100 \ + LLVM_VERSION_PATCH) -#if JL_LLVM_VERSION < 30901 - #error Only LLVM versions >= 3.9.1 are supported by Julia +#if JL_LLVM_VERSION < 60000 + #error Only LLVM versions >= 6.0.0 are supported by Julia #endif diff --git a/src/processor_arm.cpp b/src/processor_arm.cpp index 01b98c2027282..6b96c93898b1b 100644 --- a/src/processor_arm.cpp +++ b/src/processor_arm.cpp @@ -1367,7 +1367,7 @@ const std::pair &jl_get_llvm_disasm_target(void) // RAS is not currently detectable AFAICT auto max_feature = get_max_feature(); static const auto res = get_llvm_target_str(TargetData{host_cpu_name(), - JL_LLVM_VERSION >= 60000 ? "+dotprod,+ras" : "+ras", + "+dotprod,+ras", {max_feature, 0}, {feature_masks & ~max_feature, 0}, 0}); return res; } diff --git a/src/processor_x86.cpp b/src/processor_x86.cpp index a4aa2b2fa4d05..8023172d987f0 100644 --- a/src/processor_x86.cpp +++ b/src/processor_x86.cpp @@ -820,17 +820,6 @@ get_llvm_target_noext(const TargetData &data) features.push_back("+sse2"); features.push_back("+mmx"); features.push_back("+fxsr"); -#if JL_LLVM_VERSION < 50000 -# ifdef _CPU_X86_ - // LLVM has bug on < 5.0 when using avx in 32bit mode. - features.push_back("-avx"); -# endif - // Scatter-gatter can't handle address space on < 5.0 - // This is a base requirement for AVX512 so we have to turn all AVX512 features off - // Gatter is available in AVX2 too but fortunately LLVM doesn't use them. - features.push_back("-avx512f"); - features.push_back("-avx512dq"); -#endif return std::make_pair(std::move(name), std::move(features)); } diff --git a/test/llvmcall.jl b/test/llvmcall.jl index c92d2be67add9..ec1286ce62ce4 100644 --- a/test/llvmcall.jl +++ b/test/llvmcall.jl @@ -179,20 +179,16 @@ module ObjLoadTest end # Test for proper parenting -if Base.libllvm_version >= v"3.6" # llvm 3.6 changed the syntax for a gep, so just ignore this test on older versions - local foo - function foo() - # this IR snippet triggers an optimization relying - # on the llvmcall function having a parent module - Base.llvmcall( - """%1 = getelementptr i64, i64* null, i64 1 - ret void""", - Cvoid, Tuple{}) - end - code_llvm(devnull, foo, ()) -else - @info "Skipping gep parentage test on llvm < 3.6" +local foo +function foo() + # this IR snippet triggers an optimization relying + # on the llvmcall function having a parent module + Base.llvmcall( + """%1 = getelementptr i64, i64* null, i64 1 + ret void""", + Cvoid, Tuple{}) end +code_llvm(devnull, foo, ()) module CcallableRetTypeTest using Base: llvmcall, @ccallable From 4ee0e48462bd6a65cf9d6f805c903ba75721b532 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Thu, 16 Aug 2018 17:25:08 -0400 Subject: [PATCH 030/110] don't include upstreamed patches for 6.0.1 --- deps/llvm.mk | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/deps/llvm.mk b/deps/llvm.mk index 9cc2aa2090530..c8d22926ae8ca 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -390,19 +390,25 @@ $(eval $(call LLVM_PATCH,llvm-D34078-vectorize-fdiv)) $(eval $(call LLVM_PATCH,llvm-6.0-NVPTX-addrspaces)) # NVPTX $(eval $(call LLVM_PATCH,llvm-D42262-jumpthreading-not-i1)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-PPC-addrspaces)) # remove for 7.0 +ifeq ($(LLVM_VER_PATCH), 0) $(eval $(call LLVM_PATCH,llvm-D42260)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-rL326843-missing-header)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-6.0-r327540)) # remove for 7.0 +endif $(eval $(call LLVM_PATCH,llvm-6.0.0_D27296-libssp)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-6.0-D44650)) # mingw32 build fix +ifeq ($(LLVM_VER_PATCH), 0) $(eval $(call LLVM_PATCH,llvm-D45008)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-D45070)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-6.0.0-ifconv-D45819)) # remove for 7.0 +endif $(eval $(call LLVM_PATCH,llvm-D46460)) +ifeq ($(LLVM_VER_PATCH), 0) $(eval $(call LLVM_PATCH,llvm-rL332680)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-rL332682)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-rL332302)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-rL332694)) # remove for 7.0 +endif $(eval $(call LLVM_PATCH,llvm-rL327898)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-6.0-DISABLE_ABI_CHECKS)) $(eval $(call LLVM_PATCH,llvm-OProfile-line-num)) @@ -411,7 +417,9 @@ $(eval $(call LLVM_PATCH,llvm-D49832-SCEVPred)) # Remove for 7.0 $(eval $(call LLVM_PATCH,llvm-rL323946-LSRTy)) # Remove for 7.0 $(eval $(call LLVM_PATCH,llvm-D50010-VNCoercion-ni)) $(eval $(call LLVM_PATCH,llvm-D50167-scev-umin)) +ifeq ($(LLVM_VER_PATCH), 0) $(eval $(call LLVM_PATCH,llvm-windows-race)) +endif endif # LLVM_VER # Independent to the llvm version add a JL prefix to the version map From cc0de4389b6ced991efb83297a4fd47fdba51dc8 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Fri, 17 Aug 2018 00:18:30 +0200 Subject: [PATCH 031/110] fix some exported undefined variables and test this does not happen (#28693) --- stdlib/LinearAlgebra/src/LinearAlgebra.jl | 1 - stdlib/Random/src/Random.jl | 4 +--- test/misc.jl | 8 ++++++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/stdlib/LinearAlgebra/src/LinearAlgebra.jl b/stdlib/LinearAlgebra/src/LinearAlgebra.jl index 0da7dadb67434..f84e56883b436 100644 --- a/stdlib/LinearAlgebra/src/LinearAlgebra.jl +++ b/stdlib/LinearAlgebra/src/LinearAlgebra.jl @@ -133,7 +133,6 @@ export tr, transpose, transpose!, - transpose_type, tril, triu, tril!, diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index 42aebc1344d42..1ac74ad5e64fd 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -23,9 +23,7 @@ export rand!, randn!, shuffle, shuffle!, randperm, randperm!, randcycle, randcycle!, - AbstractRNG, MersenneTwister, RandomDevice, - randjump - + AbstractRNG, MersenneTwister, RandomDevice ## general definitions diff --git a/test/misc.jl b/test/misc.jl index beec7c1033a31..c280fc79d145e 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -678,3 +678,11 @@ end # Just checking that this doesn't stack overflow on construction @test Test27970Empty() == Test27970Empty() end + +@testset "exports of modules" begin + for (_, mod) in Base.loaded_modules + for v in names(mod) + @test isdefined(mod, v) + end + end +end From 1fee8a48f5e5ca78d236228eabab91ae129468c2 Mon Sep 17 00:00:00 2001 From: Danny Hermes Date: Thu, 16 Aug 2018 18:01:32 -0500 Subject: [PATCH 032/110] Use code font for `jl_value_t` in h2 (#28702) By just using text, the underscores around value are interpreted as begin/end italics. --- doc/src/devdocs/object.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/devdocs/object.md b/doc/src/devdocs/object.md index cf9223f768d96..49d1e46724301 100644 --- a/doc/src/devdocs/object.md +++ b/doc/src/devdocs/object.md @@ -1,6 +1,6 @@ # Memory layout of Julia Objects -## Object layout (jl_value_t) +## Object layout (`jl_value_t`) The `jl_value_t` struct is the name for a block of memory owned by the Julia Garbage Collector, representing the data associated with a Julia object in memory. Absent any type information, it From cd5e5a38c5565703bb747c6a66b2d23cf3dd5994 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Fri, 17 Aug 2018 07:55:39 +0200 Subject: [PATCH 033/110] fix REPL completions not always being unique (#28694) * fix REPLcompletions not unique, fix #28692 --- stdlib/REPL/src/REPL.jl | 6 +++--- stdlib/REPL/test/replcompletions.jl | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index 2ce39a860bc51..977c4af6edb92 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -346,7 +346,7 @@ function complete_line(c::REPLCompletionProvider, s) partial = beforecursor(s.input_buffer) full = LineEdit.input_string(s) ret, range, should_complete = completions(full, lastindex(partial)) - return map(completion_text, ret), partial[range], should_complete + return unique!(map(completion_text, ret)), partial[range], should_complete end function complete_line(c::ShellCompletionProvider, s) @@ -354,14 +354,14 @@ function complete_line(c::ShellCompletionProvider, s) partial = beforecursor(s.input_buffer) full = LineEdit.input_string(s) ret, range, should_complete = shell_completions(full, lastindex(partial)) - return map(completion_text, ret), partial[range], should_complete + return unique!(map(completion_text, ret)), partial[range], should_complete end function complete_line(c::LatexCompletions, s) partial = beforecursor(LineEdit.buffer(s)) full = LineEdit.input_string(s) ret, range, should_complete = bslash_completions(full, lastindex(partial))[2] - return map(completion_text, ret), partial[range], should_complete + return unique!(map(completion_text, ret)), partial[range], should_complete end mutable struct REPLHistoryProvider <: HistoryProvider diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index 2d03dbf925d32..2e8ae033ee0d0 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -102,6 +102,11 @@ let s = "" @test s[r] == "" end +let s = "using REP" + c, r = test_complete(s) + @test count(isequal("REPL"), c) == 1 +end + let s = "Comp" c, r = test_complete(s) @test "CompletionFoo" in c From 4bbfab3ee6de07e7a942072944da6d3f6ed970ed Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Thu, 16 Aug 2018 19:52:06 -0400 Subject: [PATCH 034/110] Add GC annotations for array.c --- src/array.c | 6 +++--- src/julia_internal.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/array.c b/src/array.c index 6a893f96cf43e..a3bf9068cb045 100644 --- a/src/array.c +++ b/src/array.c @@ -21,19 +21,19 @@ extern "C" { #define JL_ARRAY_ALIGN(jl_value, nbytes) LLT_ALIGN(jl_value, nbytes) // array constructors --------------------------------------------------------- -char *jl_array_typetagdata(jl_array_t *a) +char *jl_array_typetagdata(jl_array_t *a) JL_NOTSAFEPOINT { assert(jl_array_isbitsunion(a)); return ((char*)jl_array_data(a)) + ((jl_array_ndims(a) == 1 ? (a->maxsize - a->offset) : jl_array_len(a)) * a->elsize) + a->offset; } -JL_DLLEXPORT int jl_array_store_unboxed(jl_value_t *eltype) +JL_DLLEXPORT int jl_array_store_unboxed(jl_value_t *eltype) JL_NOTSAFEPOINT { size_t fsz = 0, al = 0; return jl_islayout_inline(eltype, &fsz, &al); } -STATIC_INLINE jl_value_t *jl_array_owner(jl_array_t *a) +STATIC_INLINE jl_value_t *jl_array_owner(jl_array_t *a JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT { if (a->flags.how == 3) { a = (jl_array_t*)jl_array_data_owner(a); diff --git a/src/julia_internal.h b/src/julia_internal.h index 186b5d7b2b985..d0b0039faff52 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -422,7 +422,7 @@ JL_DLLEXPORT jl_value_t *jl_instantiate_type_in_env(jl_value_t *ty, jl_unionall_ jl_value_t *jl_substitute_var(jl_value_t *t, jl_tvar_t *var, jl_value_t *val); jl_svec_t *jl_outer_unionall_vars(jl_value_t *u); int jl_count_union_components(jl_value_t *v); -jl_value_t *jl_nth_union_component(jl_value_t *v, int i) JL_NOTSAFEPOINT; +jl_value_t *jl_nth_union_component(jl_value_t *v JL_PROPAGATES_ROOT, int i) JL_NOTSAFEPOINT; int jl_find_union_component(jl_value_t *haystack, jl_value_t *needle, unsigned *nth) JL_NOTSAFEPOINT; jl_datatype_t *jl_new_uninitialized_datatype(void); void jl_precompute_memoized_dt(jl_datatype_t *dt); From 28f5c58031640e6d886a2125df4af1e49a2a5017 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Thu, 16 Aug 2018 20:26:37 -0400 Subject: [PATCH 035/110] Add GC annotations to ast.c --- src/ast.c | 101 +++++++++++++++++++++++++++++++------------- src/julia.h | 1 + src/julia_threads.h | 6 +++ src/tls.h | 4 +- 4 files changed, 81 insertions(+), 31 deletions(-) diff --git a/src/ast.c b/src/ast.c index 59ba152bd2d39..d758892961c86 100644 --- a/src/ast.c +++ b/src/ast.c @@ -70,7 +70,7 @@ typedef struct _jl_ast_context_list_t { } jl_ast_context_list_t; STATIC_INLINE void jl_ast_context_list_insert(jl_ast_context_list_t **head, - jl_ast_context_list_t *node) + jl_ast_context_list_t *node) JL_NOTSAFEPOINT { jl_ast_context_list_t *next = *head; if (next) @@ -80,7 +80,7 @@ STATIC_INLINE void jl_ast_context_list_insert(jl_ast_context_list_t **head, *head = node; } -STATIC_INLINE void jl_ast_context_list_delete(jl_ast_context_list_t *node) +STATIC_INLINE void jl_ast_context_list_delete(jl_ast_context_list_t *node) JL_NOTSAFEPOINT { if (node->next) node->next->prev = node->prev; @@ -105,7 +105,11 @@ typedef struct _jl_ast_context_t { static jl_ast_context_t jl_ast_main_ctx; +#ifdef __clang_analyzer__ +jl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED; +#else #define jl_ast_ctx(fl_ctx) container_of(fl_ctx, jl_ast_context_t, fl) +#endif #define jl_ast_context_list_item(node) \ container_of(node, jl_ast_context_t, list) @@ -247,7 +251,7 @@ static jl_mutex_t flisp_lock; static jl_ast_context_list_t *jl_ast_ctx_using = NULL; static jl_ast_context_list_t *jl_ast_ctx_freed = NULL; -static jl_ast_context_t *jl_ast_ctx_enter(void) +static jl_ast_context_t *jl_ast_ctx_enter(void) JL_GLOBALLY_ROOTED JL_NOTSAFEPOINT { jl_ptls_t ptls = jl_get_ptls_states(); JL_SIGATOMIC_BEGIN(); @@ -285,7 +289,7 @@ static jl_ast_context_t *jl_ast_ctx_enter(void) return ctx; } -static void jl_ast_ctx_leave(jl_ast_context_t *ctx) +static void jl_ast_ctx_leave(jl_ast_context_t *ctx) JL_NOTSAFEPOINT { JL_SIGATOMIC_END(); if (--ctx->ref) @@ -646,18 +650,65 @@ static value_t julia_to_list2(fl_context_t *fl_ctx, jl_value_t *a, jl_value_t *b return l; } -static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v) +static int julia_to_scm_noalloc1(fl_context_t *fl_ctx, jl_value_t *v, value_t *retval) JL_NOTSAFEPOINT { if (v == NULL) lerror(fl_ctx, symbol(fl_ctx, "error"), "undefined reference in AST"); - if (jl_is_symbol(v)) - return symbol(fl_ctx, jl_symbol_name((jl_sym_t*)v)); - if (v == jl_true) - return jl_ast_ctx(fl_ctx)->true_sym; - if (v == jl_false) - return jl_ast_ctx(fl_ctx)->false_sym; - if (v == jl_nothing) - return fl_cons(fl_ctx, jl_ast_ctx(fl_ctx)->null_sym, fl_ctx->NIL); + else if (jl_is_symbol(v)) + *retval = symbol(fl_ctx, jl_symbol_name((jl_sym_t*)v)); + else if (v == jl_true) + *retval = jl_ast_ctx(fl_ctx)->true_sym; + else if (v == jl_false) + *retval = jl_ast_ctx(fl_ctx)->false_sym; + else if (v == jl_nothing) + *retval = fl_cons(fl_ctx, jl_ast_ctx(fl_ctx)->null_sym, fl_ctx->NIL); + else + return 0; + return 1; +} + +static value_t julia_to_scm_noalloc2(fl_context_t *fl_ctx, jl_value_t *v) JL_NOTSAFEPOINT +{ + if (jl_is_long(v) && fits_fixnum(jl_unbox_long(v))) + return fixnum(jl_unbox_long(v)); + if (jl_is_ssavalue(v)) + lerror(fl_ctx, symbol(fl_ctx, "error"), "SSAValue objects should not occur in an AST"); + if (jl_is_slot(v)) + lerror(fl_ctx, symbol(fl_ctx, "error"), "Slot objects should not occur in an AST"); + value_t opaque = cvalue(fl_ctx, jl_ast_ctx(fl_ctx)->jvtype, sizeof(void*)); + *(jl_value_t**)cv_data((cvalue_t*)ptr(opaque)) = v; + return opaque; +} + +static value_t julia_to_scm_noalloc(fl_context_t *fl_ctx, jl_value_t *v) JL_NOTSAFEPOINT +{ + value_t retval; + if (julia_to_scm_noalloc1(fl_ctx, v, &retval)) + return retval; + assert(!jl_is_expr(v) && + !jl_typeis(v, jl_linenumbernode_type) && + !jl_typeis(v, jl_gotonode_type) && + !jl_typeis(v, jl_quotenode_type) && + !jl_typeis(v, jl_newvarnode_type) && + !jl_typeis(v, jl_globalref_type)); + return julia_to_scm_noalloc2(fl_ctx, v); +} + +static value_t julia_to_list2_noalloc(fl_context_t *fl_ctx, jl_value_t *a, jl_value_t *b) JL_NOTSAFEPOINT +{ + value_t sa = julia_to_scm_noalloc(fl_ctx, a); + fl_gc_handle(fl_ctx, &sa); + value_t sb = julia_to_scm_noalloc(fl_ctx, b); + value_t l = fl_list2(fl_ctx, sa, sb); + fl_free_gc_handles(fl_ctx, 1); + return l; +} + +static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v) +{ + value_t retval; + if (julia_to_scm_noalloc1(fl_ctx, v, &retval)) + return retval; if (jl_is_expr(v)) { jl_expr_t *ex = (jl_expr_t*)v; value_t args = fl_ctx->NIL; @@ -676,12 +727,12 @@ static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v) return scmv; } // GC Note: jl_fieldref(v, 0) allocates for GotoNode - // but we don't need a GC root here because julia_to_list2 + // but we don't need a GC root here because julia_to_list2_noalloc // shouldn't allocate in this case. if (jl_typeis(v, jl_linenumbernode_type)) { - jl_value_t *file = jl_fieldref_noalloc(v,1); // non-allocating - jl_value_t *line = jl_fieldref(v,0); // allocating - value_t args = julia_to_list2(fl_ctx, line, file); + jl_value_t *file = jl_fieldref_noalloc(v,1); + jl_value_t *line = jl_fieldref(v,0); + value_t args = julia_to_list2_noalloc(fl_ctx, line, file); fl_gc_handle(fl_ctx, &args); value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)line_sym); value_t scmv = fl_cons(fl_ctx, hd, args); @@ -689,11 +740,11 @@ static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v) return scmv; } if (jl_typeis(v, jl_gotonode_type)) - return julia_to_list2(fl_ctx, (jl_value_t*)goto_sym, jl_fieldref(v,0)); + return julia_to_list2_noalloc(fl_ctx, (jl_value_t*)goto_sym, jl_fieldref(v,0)); if (jl_typeis(v, jl_quotenode_type)) - return julia_to_list2(fl_ctx, (jl_value_t*)inert_sym, jl_fieldref(v,0)); + return julia_to_list2(fl_ctx, (jl_value_t*)inert_sym, jl_fieldref_noalloc(v,0)); if (jl_typeis(v, jl_newvarnode_type)) - return julia_to_list2(fl_ctx, (jl_value_t*)newvar_sym, jl_fieldref(v,0)); + return julia_to_list2_noalloc(fl_ctx, (jl_value_t*)newvar_sym, jl_fieldref(v,0)); if (jl_typeis(v, jl_globalref_type)) { jl_module_t *m = jl_globalref_mod(v); jl_sym_t *sym = jl_globalref_name(v); @@ -707,15 +758,7 @@ static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v) fl_free_gc_handles(fl_ctx, 1); return scmv; } - if (jl_is_long(v) && fits_fixnum(jl_unbox_long(v))) - return fixnum(jl_unbox_long(v)); - if (jl_is_ssavalue(v)) - lerror(fl_ctx, symbol(fl_ctx, "error"), "SSAValue objects should not occur in an AST"); - if (jl_is_slot(v)) - lerror(fl_ctx, symbol(fl_ctx, "error"), "Slot objects should not occur in an AST"); - value_t opaque = cvalue(fl_ctx, jl_ast_ctx(fl_ctx)->jvtype, sizeof(void*)); - *(jl_value_t**)cv_data((cvalue_t*)ptr(opaque)) = v; - return opaque; + return julia_to_scm_noalloc2(fl_ctx, v); } // this is used to parse a line of repl input diff --git a/src/julia.h b/src/julia.h index 8916a655ba1a7..4c8b4396b7732 100644 --- a/src/julia.h +++ b/src/julia.h @@ -650,6 +650,7 @@ extern void JL_GC_PUSH2(void *, void *) JL_NOTSAFEPOINT; extern void JL_GC_PUSH3(void *, void *, void *) JL_NOTSAFEPOINT; extern void JL_GC_PUSH4(void *, void *, void *, void *) JL_NOTSAFEPOINT; extern void JL_GC_PUSH5(void *, void *, void *, void *, void *) JL_NOTSAFEPOINT; +extern void JL_GC_PUSH6(void *, void *, void *, void *, void *, void *) JL_NOTSAFEPOINT; extern void _JL_GC_PUSHARGS(jl_value_t **, size_t) JL_NOTSAFEPOINT; // This is necessary, because otherwise the analyzer considers this undefined // behavior and terminates the exploration diff --git a/src/julia_threads.h b/src/julia_threads.h index 01d64d86877ed..b2f99422b50a0 100644 --- a/src/julia_threads.h +++ b/src/julia_threads.h @@ -169,12 +169,18 @@ JL_DLLEXPORT void (jl_cpu_wake)(void); jl_signal_fence(); \ (void)safepoint_load; \ } while (0) +#ifdef __clang_analyzer__ +// This is a sigint safepoint, not a GC safepoint (which +// JL_NOTSAFEPOINT refers to) +void jl_sigint_safepoint(jl_ptls_t tls) JL_NOTSAFEPOINT; +#else #define jl_sigint_safepoint(ptls) do { \ jl_signal_fence(); \ size_t safepoint_load = ptls->safepoint[-1]; \ jl_signal_fence(); \ (void)safepoint_load; \ } while (0) +#endif #ifndef JULIA_ENABLE_THREADING #define jl_gc_state(ptls) ((int8_t)0) STATIC_INLINE int8_t jl_gc_state_set(jl_ptls_t ptls, int8_t state, diff --git a/src/tls.h b/src/tls.h index 55be0a78290fd..3bc7bf7147269 100644 --- a/src/tls.h +++ b/src/tls.h @@ -27,10 +27,10 @@ extern "C" { JL_DLLEXPORT int16_t jl_threadid(void); JL_DLLEXPORT void jl_threading_profile(void); -JL_DLLEXPORT JL_CONST_FUNC jl_ptls_t (jl_get_ptls_states)(void); +JL_DLLEXPORT JL_CONST_FUNC jl_ptls_t (jl_get_ptls_states)(void) JL_GLOBALLY_ROOTED JL_NOTSAFEPOINT; #ifndef JULIA_ENABLE_THREADING -extern JL_DLLEXPORT jl_tls_states_t jl_tls_states; +extern JL_DLLEXPORT jl_tls_states_t jl_tls_states JL_GLOBALLY_ROOTED; #define jl_get_ptls_states() (&jl_tls_states) #else // ifndef JULIA_ENABLE_THREADING typedef jl_ptls_t (*jl_get_ptls_states_func)(void); From 777810b8ea5cb84eacda87ecce5304788f86ebd4 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Thu, 16 Aug 2018 17:45:37 -0400 Subject: [PATCH 036/110] Fix reinterpret performance This fixes #25014 by making it more obvious what's going on to LLVM. Instead of a memcpy loop, we use a ccall to :memcpy and turn this into llvm.memcpy at the IR level, which is enough for LLVM to fold everything away. In the benchmark from #25014, we still see some regressions from 0.6, but that is because it needs to dereference through the pointers in the reinterpret and reshape wrappers. In any real code, that dereferencing should be loop-invariantly moved out of the inner loop. --- base/reinterpretarray.jl | 34 +++++++++++++--------------------- base/reshapedarray.jl | 2 +- src/ccall.cpp | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/base/reinterpretarray.jl b/base/reinterpretarray.jl index 2cde44e9a386d..60b268465c14a 100644 --- a/base/reinterpretarray.jl +++ b/base/reinterpretarray.jl @@ -104,6 +104,8 @@ end _getindex_ra(a, inds[1], tail(inds)) end +@inline _memcpy!(dst, src, n) = ccall(:memcpy, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Csize_t), dst, src, n) + @inline @propagate_inbounds function _getindex_ra(a::ReinterpretArray{T,N,S}, i1::Int, tailinds::TT) where {T,N,S,TT} # Make sure to match the scalar reinterpret if that is applicable if sizeof(T) == sizeof(S) && (fieldcount(T) + fieldcount(S)) == 0 @@ -123,11 +125,9 @@ end # once it knows the data layout while nbytes_copied < sizeof(T) s[] = a.parent[ind_start + i, tailinds...] - while nbytes_copied < sizeof(T) && sidx < sizeof(S) - unsafe_store!(tptr, unsafe_load(sptr, sidx + 1), nbytes_copied + 1) - sidx += 1 - nbytes_copied += 1 - end + nb = min(sizeof(S) - sidx, sizeof(T)-nbytes_copied) + _memcpy!(tptr + nbytes_copied, sptr + sidx, nb) + nbytes_copied += nb sidx = 0 i += 1 end @@ -173,34 +173,26 @@ end # element from the original array and overwrite the relevant parts if sidx != 0 s[] = a.parent[ind_start + i, tailinds...] - while nbytes_copied < sizeof(T) && sidx < sizeof(S) - unsafe_store!(sptr, unsafe_load(tptr, nbytes_copied + 1), sidx + 1) - sidx += 1 - nbytes_copied += 1 - end + nb = min(sizeof(S) - sidx, sizeof(T)) + _memcpy!(sptr + sidx, tptr, nb) + nbytes_copied += nb a.parent[ind_start + i, tailinds...] = s[] i += 1 sidx = 0 end # Deal with the main body of elements while nbytes_copied < sizeof(T) && (sizeof(T) - nbytes_copied) > sizeof(S) - while nbytes_copied < sizeof(T) && sidx < sizeof(S) - unsafe_store!(sptr, unsafe_load(tptr, nbytes_copied + 1), sidx + 1) - sidx += 1 - nbytes_copied += 1 - end + nb = min(sizeof(S), sizeof(T) - nbytes_copied) + _memcpy!(sptr, tptr + nbytes_copied, nb) + nbytes_copied += nb a.parent[ind_start + i, tailinds...] = s[] i += 1 - sidx = 0 end # Deal with trailing partial elements if nbytes_copied < sizeof(T) s[] = a.parent[ind_start + i, tailinds...] - while nbytes_copied < sizeof(T) && sidx < sizeof(S) - unsafe_store!(sptr, unsafe_load(tptr, nbytes_copied + 1), sidx + 1) - sidx += 1 - nbytes_copied += 1 - end + nb = min(sizeof(S), sizeof(T) - nbytes_copied) + _memcpy!(sptr, tptr + nbytes_copied, nb) a.parent[ind_start + i, tailinds...] = s[] end end diff --git a/base/reshapedarray.jl b/base/reshapedarray.jl index ebd2efba68b36..18b2008f2c4d1 100644 --- a/base/reshapedarray.jl +++ b/base/reshapedarray.jl @@ -222,7 +222,7 @@ end I = ind2sub_rs(axes(A.parent), A.mi, i) _unsafe_getindex_rs(parent(A), I) end -_unsafe_getindex_rs(A, i::Integer) = (@inbounds ret = A[i]; ret) +@inline _unsafe_getindex_rs(A, i::Integer) = (@inbounds ret = A[i]; ret) @inline _unsafe_getindex_rs(A, I) = (@inbounds ret = A[I...]; ret) @inline function setindex!(A::ReshapedArrayLF, val, index::Int) diff --git a/src/ccall.cpp b/src/ccall.cpp index a8e41eac6861f..2c694f60d9c32 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -1766,6 +1766,20 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) JL_GC_POP(); return mark_or_box_ccall_result(ctx, strp, retboxed, rt, unionall, static_rt); } + else if (is_libjulia_func(memcpy)) { + const jl_cgval_t &dst = argv[0]; + const jl_cgval_t &src = argv[1]; + const jl_cgval_t &n = argv[2]; + ctx.builder.CreateMemCpy( + ctx.builder.CreateIntToPtr( + emit_unbox(ctx, T_size, dst, (jl_value_t*)jl_voidpointer_type), T_pint8), + ctx.builder.CreateIntToPtr( + emit_unbox(ctx, T_size, src, (jl_value_t*)jl_voidpointer_type), T_pint8), + emit_unbox(ctx, T_size, n, (jl_value_t*)jl_ulong_type), 1, + false); + JL_GC_POP(); + return ghostValue(jl_void_type); + } jl_cgval_t retval = sig.emit_a_ccall( ctx, From 80747267edea739b506f54cde45d4375fac50679 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Tue, 14 Aug 2018 13:35:16 -0400 Subject: [PATCH 037/110] Add doctest example for broadcast! --- base/broadcast.jl | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/base/broadcast.jl b/base/broadcast.jl index 88d83d2377e19..a95cc8bbfed29 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -713,6 +713,30 @@ Like [`broadcast`](@ref), but store the result of Note that `dest` is only used to store the result, and does not supply arguments to `f` unless it is also listed in the `As`, as in `broadcast!(f, A, A, B)` to perform `A[:] = broadcast(f, A, B)`. + +# Examples +```jldoctest +julia> A = [1.0; 0.0]; B = [0.0; 0.0]; + +julia> broadcast!(+, B, A, (0, -2.0)); + +julia> B +2-element Array{Float64,1}: + 1.0 + -2.0 + +julia> A +2-element Array{Float64,1}: + 1.0 + 0.0 + +julia> broadcast!(+, A, A, (0, -2.0)); + +julia> A +2-element Array{Float64,1}: + 1.0 + -2.0 +``` """ broadcast!(f::Tf, dest, As::Vararg{Any,N}) where {Tf,N} = (materialize!(dest, broadcasted(f, As...)); dest) From e21c1bbda787645bcbe9760f61ef7991943edaa9 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Fri, 17 Aug 2018 15:47:24 -0400 Subject: [PATCH 038/110] Doc sorting algos (#28514) --- base/sort.jl | 60 ++++++++++++++++++++++++++++++++++++++++++++ doc/src/base/sort.md | 12 ++++++--- 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/base/sort.jl b/base/sort.jl index c5cd7232e65c4..e04829a3191c4 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -370,6 +370,20 @@ struct InsertionSortAlg <: Algorithm end struct QuickSortAlg <: Algorithm end struct MergeSortAlg <: Algorithm end +""" + PartialQuickSort{T <: Union{Int,OrdinalRange}} + +Indicate that a sorting function should use the partial quick sort +algorithm. Partial quick sort returns the smallest `k` elements sorted from smallest +to largest, finding them and sorting them using [`QuickSort`](@ref). + +Characteristics: + * *not stable*: does not preserve the ordering of elements which + compare equal (e.g. "a" and "A" in a sort of letters which + ignores case). + * *in-place* in memory. + * *divide-and-conquer*: sort strategy similar to [`MergeSort`](@ref). +""" struct PartialQuickSort{T <: Union{Int,OrdinalRange}} <: Algorithm k::T end @@ -379,8 +393,54 @@ Base.last(a::PartialQuickSort{Int}) = a.k Base.first(a::PartialQuickSort) = first(a.k) Base.last(a::PartialQuickSort) = last(a.k) +""" + InsertionSort + +Indicate that a sorting function should use the insertion sort +algorithm. Insertion sort traverses the collection one element +at a time, inserting each element into its correct, sorted position in +the output list. + +Characteristics: + * *stable*: preserves the ordering of elements which + compare equal (e.g. "a" and "A" in a sort of letters + which ignores case). + * *in-place* in memory. + * *quadratic performance* in the number of elements to be sorted: + it is well-suited to small collections but should not be used for large ones. +""" const InsertionSort = InsertionSortAlg() +""" + QuickSort + +Indicate that a sorting function should use the quick sort +algorithm, which is *not* stable. + +Characteristics: + * *not stable*: does not preserve the ordering of elements which + compare equal (e.g. "a" and "A" in a sort of letters which + ignores case). + * *in-place* in memory. + * *divide-and-conquer*: sort strategy similar to [`MergeSort`](@ref). + * *good performance* for large collections. +""" const QuickSort = QuickSortAlg() +""" + MergeSort + +Indicate that a sorting function should use the merge sort +algorithm. Merge sort divides the collection into +subcollections and repeatedly merges them, sorting each +subcollection at each step, until the entire +collection has been recombined in sorted form. + +Characteristics: + * *stable*: preserves the ordering of elements which compare + equal (e.g. "a" and "A" in a sort of letters which ignores + case). + * *not in-place* in memory. + * *divide-and-conquer* sort strategy. +""" const MergeSort = MergeSortAlg() const DEFAULT_UNSTABLE = QuickSort diff --git a/doc/src/base/sort.md b/doc/src/base/sort.md index a3c3b7c3df338..17a9b8c5ed97d 100644 --- a/doc/src/base/sort.md +++ b/doc/src/base/sort.md @@ -110,6 +110,10 @@ can be specified via the `lt` keyword. Base.sort! Base.sort Base.sortperm +Base.InsertionSort +Base.MergeSort +Base.QuickSort +Base.PartialQuickSort Base.Sort.sortperm! Base.Sort.sortslices ``` @@ -131,10 +135,10 @@ Base.Sort.partialsortperm! There are currently four sorting algorithms available in base Julia: - * `InsertionSort` - * `QuickSort` - * `PartialQuickSort(k)` - * `MergeSort` + * [`InsertionSort`](@ref) + * [`QuickSort`](@ref) + * [`PartialQuickSort(k)`](@ref) + * [`MergeSort`](@ref) `InsertionSort` is an O(n^2) stable sorting algorithm. It is efficient for very small `n`, and is used internally by `QuickSort`. From 24df8fb5b49e12a36166af3dff86ad2e48d17b0a Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Fri, 17 Aug 2018 16:00:37 -0400 Subject: [PATCH 039/110] Example for parentindices --- base/subarray.jl | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/base/subarray.jl b/base/subarray.jl index b74290ba26e1e..ff640b3e73db4 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -66,7 +66,20 @@ parentindices(V::SubArray) = V.indices """ parentindices(A) -From an array view `A`, returns the corresponding indices in the parent. +Return the indices in the [`parent`](@ref) which correspond to the array view `A`. + +# Examples +```jldoctest +julia> A = [1 2; 3 4]; + +julia> V = view(A, 1, :) +2-element view(::Array{Int64,2}, 1, :) with eltype Int64: + 1 + 2 + +julia> parentindices(V) +(1, Base.Slice(Base.OneTo(2))) +``` """ parentindices(a::AbstractArray) = map(OneTo, size(a)) From e99204b52be23c49b5185d270b6697b097b16513 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 17 Aug 2018 15:57:17 -0400 Subject: [PATCH 040/110] Carry LLVM patch to fix incorrect codegen This is rL326967 to fix #28726. --- deps/llvm.mk | 1 + deps/patches/llvm-rL326967-aligned-load.patch | 301 ++++++++++++++++++ 2 files changed, 302 insertions(+) create mode 100644 deps/patches/llvm-rL326967-aligned-load.patch diff --git a/deps/llvm.mk b/deps/llvm.mk index c8d22926ae8ca..ec584b39e357c 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -417,6 +417,7 @@ $(eval $(call LLVM_PATCH,llvm-D49832-SCEVPred)) # Remove for 7.0 $(eval $(call LLVM_PATCH,llvm-rL323946-LSRTy)) # Remove for 7.0 $(eval $(call LLVM_PATCH,llvm-D50010-VNCoercion-ni)) $(eval $(call LLVM_PATCH,llvm-D50167-scev-umin)) +$(eval $(call LLVM_PATCH,llvm-rL326967-aligned-load)) # remove for 7.0 ifeq ($(LLVM_VER_PATCH), 0) $(eval $(call LLVM_PATCH,llvm-windows-race)) endif diff --git a/deps/patches/llvm-rL326967-aligned-load.patch b/deps/patches/llvm-rL326967-aligned-load.patch new file mode 100644 index 0000000000000..62c112306a292 --- /dev/null +++ b/deps/patches/llvm-rL326967-aligned-load.patch @@ -0,0 +1,301 @@ +commit b398d8e1fa5a5a914957fa22d0a64db97f6c265e +Author: Craig Topper +Date: Thu Mar 8 00:21:17 2018 +0000 + + [X86] Fix some isel patterns that used aligned vector load instructions with unaligned predicates. + + These patterns weren't checking the alignment of the load, but were using the aligned instructions. This will cause a GP fault if the data isn't aligned. + + I believe these were introduced in r312450. + + git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326967 91177308-0d34-0410-b5e6-96231b3b80d8 + +diff --git a/lib/Target/X86/X86InstrVecCompiler.td b/lib/Target/X86/X86InstrVecCompiler.td +index db3dfe56531..50c7763a2c3 100644 +--- a/lib/Target/X86/X86InstrVecCompiler.td ++++ b/lib/Target/X86/X86InstrVecCompiler.td +@@ -261,10 +261,10 @@ let Predicates = [HasVLX] in { + // will zero the upper bits. + // TODO: Is there a safe way to detect whether the producing instruction + // already zeroed the upper bits? +-multiclass subvector_zero_lowering { ++multiclass subvector_zero_lowering { + def : Pat<(DstTy (insert_subvector (bitconvert (ZeroTy immAllZerosV)), + (SrcTy RC:$src), (iPTR 0))), + (SUBREG_TO_REG (i64 0), +@@ -274,91 +274,91 @@ multiclass subvector_zero_lowering("VMOV"#MoveStr#"rm") addr:$src), SubIdx)>; ++ (!cast("VMOV"#LoadStr#"rm") addr:$src), SubIdx)>; + } + + let Predicates = [HasAVX, NoVLX] in { +- defm : subvector_zero_lowering<"APD", VR128, v4f64, v2f64, v8i32, loadv2f64, +- sub_xmm>; +- defm : subvector_zero_lowering<"APS", VR128, v8f32, v4f32, v8i32, loadv4f32, +- sub_xmm>; +- defm : subvector_zero_lowering<"DQA", VR128, v4i64, v2i64, v8i32, loadv2i64, +- sub_xmm>; +- defm : subvector_zero_lowering<"DQA", VR128, v8i32, v4i32, v8i32, loadv2i64, +- sub_xmm>; +- defm : subvector_zero_lowering<"DQA", VR128, v16i16, v8i16, v8i32, loadv2i64, +- sub_xmm>; +- defm : subvector_zero_lowering<"DQA", VR128, v32i8, v16i8, v8i32, loadv2i64, +- sub_xmm>; +-} +- +-let Predicates = [HasVLX] in { +- defm : subvector_zero_lowering<"APDZ128", VR128X, v4f64, v2f64, v8i32, ++ defm : subvector_zero_lowering<"APD", "UPD", VR128, v4f64, v2f64, v8i32, + loadv2f64, sub_xmm>; +- defm : subvector_zero_lowering<"APSZ128", VR128X, v8f32, v4f32, v8i32, ++ defm : subvector_zero_lowering<"APS", "UPS", VR128, v8f32, v4f32, v8i32, + loadv4f32, sub_xmm>; +- defm : subvector_zero_lowering<"DQA64Z128", VR128X, v4i64, v2i64, v8i32, ++ defm : subvector_zero_lowering<"DQA", "DQU", VR128, v4i64, v2i64, v8i32, + loadv2i64, sub_xmm>; +- defm : subvector_zero_lowering<"DQA64Z128", VR128X, v8i32, v4i32, v8i32, ++ defm : subvector_zero_lowering<"DQA", "DQU", VR128, v8i32, v4i32, v8i32, + loadv2i64, sub_xmm>; +- defm : subvector_zero_lowering<"DQA64Z128", VR128X, v16i16, v8i16, v8i32, ++ defm : subvector_zero_lowering<"DQA", "DQU", VR128, v16i16, v8i16, v8i32, + loadv2i64, sub_xmm>; +- defm : subvector_zero_lowering<"DQA64Z128", VR128X, v32i8, v16i8, v8i32, +- loadv2i64, sub_xmm>; +- +- defm : subvector_zero_lowering<"APDZ128", VR128X, v8f64, v2f64, v16i32, +- loadv2f64, sub_xmm>; +- defm : subvector_zero_lowering<"APSZ128", VR128X, v16f32, v4f32, v16i32, +- loadv4f32, sub_xmm>; +- defm : subvector_zero_lowering<"DQA64Z128", VR128X, v8i64, v2i64, v16i32, +- loadv2i64, sub_xmm>; +- defm : subvector_zero_lowering<"DQA64Z128", VR128X, v16i32, v4i32, v16i32, +- loadv2i64, sub_xmm>; +- defm : subvector_zero_lowering<"DQA64Z128", VR128X, v32i16, v8i16, v16i32, +- loadv2i64, sub_xmm>; +- defm : subvector_zero_lowering<"DQA64Z128", VR128X, v64i8, v16i8, v16i32, ++ defm : subvector_zero_lowering<"DQA", "DQU", VR128, v32i8, v16i8, v8i32, + loadv2i64, sub_xmm>; ++} + +- defm : subvector_zero_lowering<"APDZ256", VR256X, v8f64, v4f64, v16i32, +- loadv4f64, sub_ymm>; +- defm : subvector_zero_lowering<"APSZ256", VR256X, v16f32, v8f32, v16i32, +- loadv8f32, sub_ymm>; +- defm : subvector_zero_lowering<"DQA64Z256", VR256X, v8i64, v4i64, v16i32, +- loadv4i64, sub_ymm>; +- defm : subvector_zero_lowering<"DQA64Z256", VR256X, v16i32, v8i32, v16i32, +- loadv4i64, sub_ymm>; +- defm : subvector_zero_lowering<"DQA64Z256", VR256X, v32i16, v16i16, v16i32, +- loadv4i64, sub_ymm>; +- defm : subvector_zero_lowering<"DQA64Z256", VR256X, v64i8, v32i8, v16i32, +- loadv4i64, sub_ymm>; ++let Predicates = [HasVLX] in { ++ defm : subvector_zero_lowering<"APDZ128", "UPDZ128", VR128X, v4f64, ++ v2f64, v8i32, loadv2f64, sub_xmm>; ++ defm : subvector_zero_lowering<"APSZ128", "UPSZ128", VR128X, v8f32, ++ v4f32, v8i32, loadv4f32, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA64Z128", "DQU64Z128", VR128X, v4i64, ++ v2i64, v8i32, loadv2i64, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA64Z128", "DQU64Z128", VR128X, v8i32, ++ v4i32, v8i32, loadv2i64, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA64Z128", "DQU64Z128", VR128X, v16i16, ++ v8i16, v8i32, loadv2i64, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA64Z128", "DQU64Z128", VR128X, v32i8, ++ v16i8, v8i32, loadv2i64, sub_xmm>; ++ ++ defm : subvector_zero_lowering<"APDZ128", "UPDZ128", VR128X, v8f64, ++ v2f64, v16i32, loadv2f64, sub_xmm>; ++ defm : subvector_zero_lowering<"APSZ128", "UPSZ128", VR128X, v16f32, ++ v4f32, v16i32, loadv4f32, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA64Z128", "DQU64Z128", VR128X, v8i64, ++ v2i64, v16i32, loadv2i64, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA64Z128", "DQU64Z128", VR128X, v16i32, ++ v4i32, v16i32, loadv2i64, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA64Z128", "DQU64Z128", VR128X, v32i16, ++ v8i16, v16i32, loadv2i64, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA64Z128", "DQU64Z128", VR128X, v64i8, ++ v16i8, v16i32, loadv2i64, sub_xmm>; ++ ++ defm : subvector_zero_lowering<"APDZ256", "UPDZ256", VR256X, v8f64, ++ v4f64, v16i32, loadv4f64, sub_ymm>; ++ defm : subvector_zero_lowering<"APSZ256", "UPDZ256", VR256X, v16f32, ++ v8f32, v16i32, loadv8f32, sub_ymm>; ++ defm : subvector_zero_lowering<"DQA64Z256", "DQU64Z256", VR256X, v8i64, ++ v4i64, v16i32, loadv4i64, sub_ymm>; ++ defm : subvector_zero_lowering<"DQA64Z256", "DQU64Z256", VR256X, v16i32, ++ v8i32, v16i32, loadv4i64, sub_ymm>; ++ defm : subvector_zero_lowering<"DQA64Z256", "DQU64Z256", VR256X, v32i16, ++ v16i16, v16i32, loadv4i64, sub_ymm>; ++ defm : subvector_zero_lowering<"DQA64Z256", "DQU64Z256", VR256X, v64i8, ++ v32i8, v16i32, loadv4i64, sub_ymm>; + } + + let Predicates = [HasAVX512, NoVLX] in { +- defm : subvector_zero_lowering<"APD", VR128, v8f64, v2f64, v16i32, loadv2f64, +- sub_xmm>; +- defm : subvector_zero_lowering<"APS", VR128, v16f32, v4f32, v16i32, loadv4f32, +- sub_xmm>; +- defm : subvector_zero_lowering<"DQA", VR128, v8i64, v2i64, v16i32, loadv2i64, +- sub_xmm>; +- defm : subvector_zero_lowering<"DQA", VR128, v16i32, v4i32, v16i32, loadv2i64, +- sub_xmm>; +- defm : subvector_zero_lowering<"DQA", VR128, v32i16, v8i16, v16i32, loadv2i64, +- sub_xmm>; +- defm : subvector_zero_lowering<"DQA", VR128, v64i8, v16i8, v16i32, loadv2i64, +- sub_xmm>; +- +- defm : subvector_zero_lowering<"APDY", VR256, v8f64, v4f64, v16i32, +- loadv4f64, sub_ymm>; +- defm : subvector_zero_lowering<"APSY", VR256, v16f32, v8f32, v16i32, +- loadv8f32, sub_ymm>; +- defm : subvector_zero_lowering<"DQAY", VR256, v8i64, v4i64, v16i32, +- loadv4i64, sub_ymm>; +- defm : subvector_zero_lowering<"DQAY", VR256, v16i32, v8i32, v16i32, +- loadv4i64, sub_ymm>; +- defm : subvector_zero_lowering<"DQAY", VR256, v32i16, v16i16, v16i32, +- loadv4i64, sub_ymm>; +- defm : subvector_zero_lowering<"DQAY", VR256, v64i8, v32i8, v16i32, +- loadv4i64, sub_ymm>; ++ defm : subvector_zero_lowering<"APD", "UPD", VR128, v8f64, v2f64, ++ v16i32,loadv2f64, sub_xmm>; ++ defm : subvector_zero_lowering<"APS", "UPS", VR128, v16f32, v4f32, ++ v16i32, loadv4f32, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA", "DQU", VR128, v8i64, v2i64, ++ v16i32, loadv2i64, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA", "DQU", VR128, v16i32, v4i32, ++ v16i32, loadv2i64, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA", "DQU", VR128, v32i16, v8i16, ++ v16i32, loadv2i64, sub_xmm>; ++ defm : subvector_zero_lowering<"DQA", "DQU", VR128, v64i8, v16i8, ++ v16i32, loadv2i64, sub_xmm>; ++ ++ defm : subvector_zero_lowering<"APDY", "UPDY", VR256, v8f64, v4f64, ++ v16i32, loadv4f64, sub_ymm>; ++ defm : subvector_zero_lowering<"APSY", "UPSY", VR256, v16f32, v8f32, ++ v16i32, loadv8f32, sub_ymm>; ++ defm : subvector_zero_lowering<"DQAY", "DQUY", VR256, v8i64, v4i64, ++ v16i32, loadv4i64, sub_ymm>; ++ defm : subvector_zero_lowering<"DQAY", "DQUY", VR256, v16i32, v8i32, ++ v16i32, loadv4i64, sub_ymm>; ++ defm : subvector_zero_lowering<"DQAY", "DQUY", VR256, v32i16, v16i16, ++ v16i32, loadv4i64, sub_ymm>; ++ defm : subvector_zero_lowering<"DQAY", "DQUY", VR256, v64i8, v32i8, ++ v16i32, loadv4i64, sub_ymm>; + } + + // List of opcodes that guaranteed to zero the upper elements of vector regs. +diff --git a/test/CodeGen/X86/merge-consecutive-loads-256.ll b/test/CodeGen/X86/merge-consecutive-loads-256.ll +index 6ecd8116443..0f2cf594b1c 100644 +--- a/test/CodeGen/X86/merge-consecutive-loads-256.ll ++++ b/test/CodeGen/X86/merge-consecutive-loads-256.ll +@@ -28,13 +28,13 @@ define <4 x double> @merge_4f64_2f64_23(<2 x double>* %ptr) nounwind uwtable noi + define <4 x double> @merge_4f64_2f64_2z(<2 x double>* %ptr) nounwind uwtable noinline ssp { + ; AVX-LABEL: merge_4f64_2f64_2z: + ; AVX: # %bb.0: +-; AVX-NEXT: vmovaps 32(%rdi), %xmm0 ++; AVX-NEXT: vmovups 32(%rdi), %xmm0 + ; AVX-NEXT: retq + ; + ; X32-AVX-LABEL: merge_4f64_2f64_2z: + ; X32-AVX: # %bb.0: + ; X32-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax +-; X32-AVX-NEXT: vmovaps 32(%eax), %xmm0 ++; X32-AVX-NEXT: vmovups 32(%eax), %xmm0 + ; X32-AVX-NEXT: retl + %ptr0 = getelementptr inbounds <2 x double>, <2 x double>* %ptr, i64 2 + %val0 = load <2 x double>, <2 x double>* %ptr0 +@@ -109,13 +109,13 @@ define <4 x double> @merge_4f64_f64_34uu(double* %ptr) nounwind uwtable noinline + define <4 x double> @merge_4f64_f64_45zz(double* %ptr) nounwind uwtable noinline ssp { + ; AVX-LABEL: merge_4f64_f64_45zz: + ; AVX: # %bb.0: +-; AVX-NEXT: vmovaps 32(%rdi), %xmm0 ++; AVX-NEXT: vmovups 32(%rdi), %xmm0 + ; AVX-NEXT: retq + ; + ; X32-AVX-LABEL: merge_4f64_f64_45zz: + ; X32-AVX: # %bb.0: + ; X32-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax +-; X32-AVX-NEXT: vmovaps 32(%eax), %xmm0 ++; X32-AVX-NEXT: vmovups 32(%eax), %xmm0 + ; X32-AVX-NEXT: retl + %ptr0 = getelementptr inbounds double, double* %ptr, i64 4 + %ptr1 = getelementptr inbounds double, double* %ptr, i64 5 +@@ -155,13 +155,13 @@ define <4 x double> @merge_4f64_f64_34z6(double* %ptr) nounwind uwtable noinline + define <4 x i64> @merge_4i64_2i64_3z(<2 x i64>* %ptr) nounwind uwtable noinline ssp { + ; AVX-LABEL: merge_4i64_2i64_3z: + ; AVX: # %bb.0: +-; AVX-NEXT: vmovaps 48(%rdi), %xmm0 ++; AVX-NEXT: vmovups 48(%rdi), %xmm0 + ; AVX-NEXT: retq + ; + ; X32-AVX-LABEL: merge_4i64_2i64_3z: + ; X32-AVX: # %bb.0: + ; X32-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax +-; X32-AVX-NEXT: vmovaps 48(%eax), %xmm0 ++; X32-AVX-NEXT: vmovups 48(%eax), %xmm0 + ; X32-AVX-NEXT: retl + %ptr0 = getelementptr inbounds <2 x i64>, <2 x i64>* %ptr, i64 3 + %val0 = load <2 x i64>, <2 x i64>* %ptr0 +@@ -217,13 +217,13 @@ define <4 x i64> @merge_4i64_i64_1zzu(i64* %ptr) nounwind uwtable noinline ssp { + define <4 x i64> @merge_4i64_i64_23zz(i64* %ptr) nounwind uwtable noinline ssp { + ; AVX-LABEL: merge_4i64_i64_23zz: + ; AVX: # %bb.0: +-; AVX-NEXT: vmovaps 16(%rdi), %xmm0 ++; AVX-NEXT: vmovups 16(%rdi), %xmm0 + ; AVX-NEXT: retq + ; + ; X32-AVX-LABEL: merge_4i64_i64_23zz: + ; X32-AVX: # %bb.0: + ; X32-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax +-; X32-AVX-NEXT: vmovaps 16(%eax), %xmm0 ++; X32-AVX-NEXT: vmovups 16(%eax), %xmm0 + ; X32-AVX-NEXT: retl + %ptr0 = getelementptr inbounds i64, i64* %ptr, i64 2 + %ptr1 = getelementptr inbounds i64, i64* %ptr, i64 3 +diff --git a/test/CodeGen/X86/merge-consecutive-loads-512.ll b/test/CodeGen/X86/merge-consecutive-loads-512.ll +index 62102eb382c..3c6eaf65292 100644 +--- a/test/CodeGen/X86/merge-consecutive-loads-512.ll ++++ b/test/CodeGen/X86/merge-consecutive-loads-512.ll +@@ -106,13 +106,13 @@ define <8 x double> @merge_8f64_f64_23uuuuu9(double* %ptr) nounwind uwtable noin + define <8 x double> @merge_8f64_f64_12zzuuzz(double* %ptr) nounwind uwtable noinline ssp { + ; ALL-LABEL: merge_8f64_f64_12zzuuzz: + ; ALL: # %bb.0: +-; ALL-NEXT: vmovaps 8(%rdi), %xmm0 ++; ALL-NEXT: vmovups 8(%rdi), %xmm0 + ; ALL-NEXT: retq + ; + ; X32-AVX512F-LABEL: merge_8f64_f64_12zzuuzz: + ; X32-AVX512F: # %bb.0: + ; X32-AVX512F-NEXT: movl {{[0-9]+}}(%esp), %eax +-; X32-AVX512F-NEXT: vmovaps 8(%eax), %xmm0 ++; X32-AVX512F-NEXT: vmovups 8(%eax), %xmm0 + ; X32-AVX512F-NEXT: retl + %ptr0 = getelementptr inbounds double, double* %ptr, i64 1 + %ptr1 = getelementptr inbounds double, double* %ptr, i64 2 +@@ -190,7 +190,7 @@ define <8 x i64> @merge_8i64_4i64_z3(<4 x i64>* %ptr) nounwind uwtable noinline + define <8 x i64> @merge_8i64_i64_56zz9uzz(i64* %ptr) nounwind uwtable noinline ssp { + ; ALL-LABEL: merge_8i64_i64_56zz9uzz: + ; ALL: # %bb.0: +-; ALL-NEXT: vmovaps 40(%rdi), %xmm0 ++; ALL-NEXT: vmovups 40(%rdi), %xmm0 + ; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero + ; ALL-NEXT: vinsertf64x4 $1, %ymm1, %zmm0, %zmm0 + ; ALL-NEXT: retq +@@ -198,7 +198,7 @@ define <8 x i64> @merge_8i64_i64_56zz9uzz(i64* %ptr) nounwind uwtable noinline s + ; X32-AVX512F-LABEL: merge_8i64_i64_56zz9uzz: + ; X32-AVX512F: # %bb.0: + ; X32-AVX512F-NEXT: movl {{[0-9]+}}(%esp), %eax +-; X32-AVX512F-NEXT: vmovaps 40(%eax), %xmm0 ++; X32-AVX512F-NEXT: vmovups 40(%eax), %xmm0 + ; X32-AVX512F-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero + ; X32-AVX512F-NEXT: vinsertf64x4 $1, %ymm1, %zmm0, %zmm0 + ; X32-AVX512F-NEXT: retl From 71360499ae301b5472e987a108d6c407b13c8c1d Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 17 Aug 2018 18:14:41 -0400 Subject: [PATCH 041/110] Add GC static analysis annotations for builtins.c --- doc/src/devdocs/gc-sa.md | 4 +++- src/builtins.c | 30 +++++++++++++++--------------- src/julia.h | 15 +++++++++++---- src/julia_internal.h | 2 +- src/support/analyzer_annotations.h | 2 +- src/support/hashing.h | 21 +++++++++++---------- 6 files changed, 42 insertions(+), 32 deletions(-) diff --git a/doc/src/devdocs/gc-sa.md b/doc/src/devdocs/gc-sa.md index 6c5f5a8c06c5c..0483d19c044ce 100644 --- a/doc/src/devdocs/gc-sa.md +++ b/doc/src/devdocs/gc-sa.md @@ -251,7 +251,9 @@ jl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED; This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that is should only be used if those values are globally rooted by virtue of being -a leaftype. The rooting of leaftypes is a bit complicated, and we can generally +a leaftype. The rooting of leaftypes is a bit complicated. They are generally +rooted through `cache` field of the corresponding `TypeName`, which itself is +rooted by the containing module (so they're rooted as long as the containing module is ok) and we can generally assume that leaftypes are rooted where they are used, but we may refine this property in the future, so the separate annotation helps split out the reason for being globally rooted. diff --git a/src/builtins.c b/src/builtins.c index 2fa6c47afc2f7..e98ac120b4ce5 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -32,7 +32,7 @@ extern "C" { // egal and object_id --------------------------------------------------------- -static int bits_equal(void *a, void *b, int sz) +static int bits_equal(void *a, void *b, int sz) JL_NOTSAFEPOINT { switch (sz) { case 1: return *(int8_t*)a == *(int8_t*)b; @@ -63,7 +63,7 @@ static int bits_equal(void *a, void *b, int sz) // The solution is to keep the code in jl_egal simple and split out the // (more) complex cases into their own functions which are marked with // NOINLINE. -static int NOINLINE compare_svec(jl_svec_t *a, jl_svec_t *b) +static int NOINLINE compare_svec(jl_svec_t *a, jl_svec_t *b) JL_NOTSAFEPOINT { size_t l = jl_svec_len(a); if (l != jl_svec_len(b)) @@ -76,7 +76,7 @@ static int NOINLINE compare_svec(jl_svec_t *a, jl_svec_t *b) } // See comment above for an explanation of NOINLINE. -static int NOINLINE compare_fields(jl_value_t *a, jl_value_t *b, jl_datatype_t *dt) +static int NOINLINE compare_fields(jl_value_t *a, jl_value_t *b, jl_datatype_t *dt) JL_NOTSAFEPOINT { size_t f, nf = jl_datatype_nfields(dt); for (f = 0; f < nf; f++) { @@ -116,7 +116,7 @@ static int NOINLINE compare_fields(jl_value_t *a, jl_value_t *b, jl_datatype_t * return 1; } -static int egal_types(jl_value_t *a, jl_value_t *b, jl_typeenv_t *env) +static int egal_types(jl_value_t *a, jl_value_t *b, jl_typeenv_t *env) JL_NOTSAFEPOINT { if (a == b) return 1; @@ -163,7 +163,7 @@ static int egal_types(jl_value_t *a, jl_value_t *b, jl_typeenv_t *env) return jl_egal(a, b); } -JL_DLLEXPORT int jl_egal(jl_value_t *a, jl_value_t *b) +JL_DLLEXPORT int jl_egal(jl_value_t *a JL_MAYBE_UNROOTED, jl_value_t *b JL_MAYBE_UNROOTED) JL_NOTSAFEPOINT { // warning: a,b may NOT have been gc-rooted by the caller if (a == b) @@ -199,7 +199,7 @@ JL_DLLEXPORT int jl_egal(jl_value_t *a, jl_value_t *b) // object_id ------------------------------------------------------------------ -static uintptr_t bits_hash(const void *b, size_t sz) +static uintptr_t bits_hash(const void *b, size_t sz) JL_NOTSAFEPOINT { switch (sz) { case 1: return int32hash(*(const int8_t*)b); @@ -219,7 +219,7 @@ static uintptr_t bits_hash(const void *b, size_t sz) } } -static uintptr_t NOINLINE hash_svec(jl_svec_t *v) +static uintptr_t NOINLINE hash_svec(jl_svec_t *v) JL_NOTSAFEPOINT { uintptr_t h = 0; size_t i, l = jl_svec_len(v); @@ -236,9 +236,9 @@ typedef struct _varidx { struct _varidx *prev; } jl_varidx_t; -static uintptr_t jl_object_id_(jl_value_t *tv, jl_value_t *v); +static uintptr_t jl_object_id_(jl_value_t *tv, jl_value_t *v) JL_NOTSAFEPOINT; -static uintptr_t type_object_id_(jl_value_t *v, jl_varidx_t *env) +static uintptr_t type_object_id_(jl_value_t *v, jl_varidx_t *env) JL_NOTSAFEPOINT { if (v == NULL) return 0; jl_datatype_t *tv = (jl_datatype_t*)jl_typeof(v); @@ -277,7 +277,7 @@ static uintptr_t type_object_id_(jl_value_t *v, jl_varidx_t *env) return jl_object_id_((jl_value_t*)tv, v); } -static uintptr_t jl_object_id_(jl_value_t *tv, jl_value_t *v) +static uintptr_t jl_object_id_(jl_value_t *tv, jl_value_t *v) JL_NOTSAFEPOINT { if (tv == (jl_value_t*)jl_sym_type) return ((jl_sym_t*)v)->hash; @@ -337,7 +337,7 @@ static uintptr_t jl_object_id_(jl_value_t *tv, jl_value_t *v) return h; } -JL_DLLEXPORT uintptr_t jl_object_id(jl_value_t *v) +JL_DLLEXPORT uintptr_t jl_object_id(jl_value_t *v) JL_NOTSAFEPOINT { return jl_object_id_(jl_typeof(v), v); } @@ -1132,7 +1132,7 @@ static void add_intrinsic_properties(enum intrinsic f, unsigned nargs, void (*pf runtime_fp[f] = pfunc; } -static void add_intrinsic(jl_module_t *inm, const char *name, enum intrinsic f) +static void add_intrinsic(jl_module_t *inm, const char *name, enum intrinsic f) JL_GC_DISABLED { jl_value_t *i = jl_permbox32(jl_intrinsic_type, (int32_t)f); jl_sym_t *sym = jl_symbol(name); @@ -1140,7 +1140,7 @@ static void add_intrinsic(jl_module_t *inm, const char *name, enum intrinsic f) jl_module_export(inm, sym); } -void jl_init_intrinsic_properties(void) +void jl_init_intrinsic_properties(void) JL_GC_DISABLED { #define ADD_I(name, nargs) add_intrinsic_properties(name, nargs, (void(*)(void))&jl_##name); #define ADD_HIDDEN ADD_I @@ -1151,7 +1151,7 @@ void jl_init_intrinsic_properties(void) #undef ALIAS } -void jl_init_intrinsic_functions(void) +void jl_init_intrinsic_functions(void) JL_GC_DISABLED { jl_module_t *inm = jl_new_module(jl_symbol("Intrinsics")); inm->parent = jl_core_module; @@ -1183,7 +1183,7 @@ static void add_builtin_func(const char *name, jl_fptr_args_t fptr) jl_mk_builtin_func(NULL, name, fptr); } -void jl_init_primitives(void) +void jl_init_primitives(void) JL_GC_DISABLED { add_builtin_func("===", jl_f_is); add_builtin_func("typeof", jl_f_typeof); diff --git a/src/julia.h b/src/julia.h index 4c8b4396b7732..509d2a37e19f2 100644 --- a/src/julia.h +++ b/src/julia.h @@ -780,7 +780,13 @@ JL_DLLEXPORT size_t jl_array_len_(jl_array_t *a); JL_DLLEXPORT char *jl_array_typetagdata(jl_array_t *a); -STATIC_INLINE jl_value_t *jl_array_ptr_ref(void *a, size_t i) JL_NOTSAFEPOINT +#ifdef __clang_analyzer__ +STATIC_INLINE jl_value_t *jl_array_ptr_ref(void *a JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; +STATIC_INLINE jl_value_t *jl_array_ptr_set( + void *a JL_ROOTING_ARGUMENT, size_t i, + void *x JL_ROOTED_ARGUMENT) JL_NOTSAFEPOINT; +#else +STATIC_INLINE jl_value_t *jl_array_ptr_ref(void *a JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; { assert(i < jl_array_len(a)); return ((jl_value_t**)(jl_array_data(a)))[i]; @@ -799,6 +805,7 @@ STATIC_INLINE jl_value_t *jl_array_ptr_set( } return (jl_value_t*)x; } +#endif STATIC_INLINE uint8_t jl_array_uint8_ref(void *a, size_t i) JL_NOTSAFEPOINT { @@ -813,7 +820,7 @@ STATIC_INLINE void jl_array_uint8_set(void *a, size_t i, uint8_t x) JL_NOTSAFEPO ((uint8_t*)(jl_array_data(a)))[i] = x; } -#define jl_exprarg(e,n) (((jl_value_t**)jl_array_data(((jl_expr_t*)(e))->args))[n]) +#define jl_exprarg(e,n) jl_array_ptr_ref(((jl_expr_t*)(e))->args, n) #define jl_exprargset(e, n, v) jl_array_ptr_set(((jl_expr_t*)(e))->args, n, v) #define jl_expr_nargs(e) jl_array_len(((jl_expr_t*)(e))->args) @@ -1332,10 +1339,10 @@ JL_DLLEXPORT int jl_is_const(jl_module_t *m, jl_sym_t *var); JL_DLLEXPORT jl_value_t *jl_get_global(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var); JL_DLLEXPORT void jl_set_global(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, - jl_value_t *val JL_ROOTED_ARGUMENT); + jl_value_t *val JL_ROOTED_ARGUMENT JL_MAYBE_UNROOTED); JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, - jl_value_t *val JL_ROOTED_ARGUMENT); + jl_value_t *val JL_ROOTED_ARGUMENT JL_MAYBE_UNROOTED); JL_DLLEXPORT void jl_checked_assignment(jl_binding_t *b, jl_value_t *rhs); JL_DLLEXPORT void jl_declare_constant(jl_binding_t *b); JL_DLLEXPORT void jl_module_using(jl_module_t *to, jl_module_t *from); diff --git a/src/julia_internal.h b/src/julia_internal.h index d0b0039faff52..e8c3df13aa598 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -482,7 +482,7 @@ extern size_t jl_arr_xtralloc_limit; void jl_init_types(void); void jl_init_box_caches(void); void jl_init_frontend(void); -void jl_init_primitives(void); +void jl_init_primitives(void) JL_GC_DISABLED; void *jl_init_llvm(void); void jl_init_codegen(void); void jl_init_intrinsic_functions(void); diff --git a/src/support/analyzer_annotations.h b/src/support/analyzer_annotations.h index 75236435dfb69..cb21993d007fe 100644 --- a/src/support/analyzer_annotations.h +++ b/src/support/analyzer_annotations.h @@ -9,7 +9,7 @@ #define JL_ROOTING_ARGUMENT __attribute__((annotate("julia_rooting_argument"))) #define JL_ROOTED_ARGUMENT __attribute__((annotate("julia_rooted_argument"))) #define JL_GC_DISABLED __attribute__((annotate("julia_gc_disabled"))) -#define JL_ALWAYS_LEAFTYPE __attribute__((annotate("julia_always_leaftype"))) +#define JL_ALWAYS_LEAFTYPE JL_GLOBALLY_ROOTED #define JL_ROOTS_TEMPORARILY __attribute__((annotate("julia_temporarily_roots"))) #define JL_REQUIRE_ROOTED_SLOT __attribute__((annotate("julia_require_rooted_slot"))) #ifdef __cplusplus diff --git a/src/support/hashing.h b/src/support/hashing.h index 7fcbf4a323e84..8686c746f4898 100644 --- a/src/support/hashing.h +++ b/src/support/hashing.h @@ -5,32 +5,33 @@ #include "utils.h" #include "dtypes.h" +#include "analyzer_annotations.h" #ifdef __cplusplus extern "C" { #endif -uint_t nextipow2(uint_t i); -JL_DLLEXPORT uint32_t int32hash(uint32_t a); -JL_DLLEXPORT uint64_t int64hash(uint64_t key); -JL_DLLEXPORT uint32_t int64to32hash(uint64_t key); +uint_t nextipow2(uint_t i) JL_NOTSAFEPOINT; +JL_DLLEXPORT uint32_t int32hash(uint32_t a) JL_NOTSAFEPOINT; +JL_DLLEXPORT uint64_t int64hash(uint64_t key) JL_NOTSAFEPOINT; +JL_DLLEXPORT uint32_t int64to32hash(uint64_t key) JL_NOTSAFEPOINT; #ifdef _P64 #define inthash int64hash #else #define inthash int32hash #endif -JL_DLLEXPORT uint64_t memhash(const char *buf, size_t n); -JL_DLLEXPORT uint64_t memhash_seed(const char *buf, size_t n, uint32_t seed); -JL_DLLEXPORT uint32_t memhash32(const char *buf, size_t n); -JL_DLLEXPORT uint32_t memhash32_seed(const char *buf, size_t n, uint32_t seed); +JL_DLLEXPORT uint64_t memhash(const char *buf, size_t n) JL_NOTSAFEPOINT; +JL_DLLEXPORT uint64_t memhash_seed(const char *buf, size_t n, uint32_t seed) JL_NOTSAFEPOINT; +JL_DLLEXPORT uint32_t memhash32(const char *buf, size_t n) JL_NOTSAFEPOINT; +JL_DLLEXPORT uint32_t memhash32_seed(const char *buf, size_t n, uint32_t seed) JL_NOTSAFEPOINT; #ifdef _P64 -STATIC_INLINE uint64_t bitmix(uint64_t a, uint64_t b) +STATIC_INLINE uint64_t bitmix(uint64_t a, uint64_t b) JL_NOTSAFEPOINT { return int64hash(a^bswap_64(b)); } #else -STATIC_INLINE uint32_t bitmix(uint32_t a, uint32_t b) +STATIC_INLINE uint32_t bitmix(uint32_t a, uint32_t b) JL_NOTSAFEPOINT { return int64to32hash((((uint64_t)a) << 32) | (uint64_t)b); } From 239a40dd16cdac112e9455f9fdd5697b97413456 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 17 Aug 2018 18:49:07 -0400 Subject: [PATCH 042/110] Add gc static analysis annotations for datatype.c --- src/datatype.c | 21 +++++++++++---------- src/julia.h | 2 +- src/support/dtypes.h | 3 ++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/datatype.c b/src/datatype.c index 63069f3675854..c4d3fcc2a2da3 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -18,7 +18,7 @@ extern "C" { // allocating TypeNames ----------------------------------------------------------- -jl_sym_t *jl_demangle_typename(jl_sym_t *s) +jl_sym_t *jl_demangle_typename(jl_sym_t *s) JL_NOTSAFEPOINT { char *n = jl_symbol_name(s); if (n[0] != '#') @@ -90,7 +90,7 @@ jl_datatype_t *jl_new_uninitialized_datatype(void) static jl_datatype_layout_t *jl_get_layout(uint32_t nfields, uint32_t alignment, int haspadding, - jl_fielddesc32_t desc[]) + jl_fielddesc32_t desc[]) JL_NOTSAFEPOINT { // compute the smallest fielddesc type that can hold the layout description int fielddesc_type = 0; @@ -262,7 +262,7 @@ JL_DLLEXPORT int jl_islayout_inline(jl_value_t *eltype, size_t *fsz, size_t *al) return (countbits > 0 && countbits < 127) ? countbits : 0; } -static int references_name(jl_value_t *p, jl_typename_t *name) +static int references_name(jl_value_t *p, jl_typename_t *name) JL_NOTSAFEPOINT { if (jl_is_uniontype(p)) return references_name(((jl_uniontype_t*)p)->a, name) || @@ -362,10 +362,11 @@ void jl_compute_field_offsets(jl_datatype_t *st) size_t descsz = nfields * sizeof(jl_fielddesc32_t); jl_fielddesc32_t *desc; - if (descsz < jl_page_size) - desc = (jl_fielddesc32_t*)alloca(descsz); - else + int should_malloc = descsz >= jl_page_size; + if (should_malloc) desc = (jl_fielddesc32_t*)malloc(descsz); + else + desc = (jl_fielddesc32_t*)alloca(descsz); int haspadding = 0; assert(st->name == jl_tuple_typename || st == jl_sym_type || @@ -374,7 +375,7 @@ void jl_compute_field_offsets(jl_datatype_t *st) for (size_t i = 0; i < nfields; i++) { jl_value_t *ty = jl_field_type(st, i); - size_t fsz = 0, al = 0; + size_t fsz = 0, al = 1; if (jl_islayout_inline(ty, &fsz, &al)) { if (__unlikely(fsz > max_size)) // Should never happen @@ -427,11 +428,11 @@ void jl_compute_field_offsets(jl_datatype_t *st) if (st->size > sz) haspadding = 1; st->layout = jl_get_layout(nfields, alignm, haspadding, desc); - if (descsz >= jl_page_size) free(desc); + if (should_malloc) free(desc); jl_allocate_singleton_instance(st); return; throw_ovf: - if (descsz >= jl_page_size) free(desc); + if (should_malloc) free(desc); jl_errorf("type %s has field offset %d that exceeds the page size", jl_symbol_name(st->name->name), descsz); } @@ -873,7 +874,7 @@ JL_DLLEXPORT jl_value_t *jl_get_nth_field_checked(jl_value_t *v, size_t i) return jl_new_bits(ty, (char*)v + offs); } -JL_DLLEXPORT void jl_set_nth_field(jl_value_t *v, size_t i, jl_value_t *rhs) +JL_DLLEXPORT void jl_set_nth_field(jl_value_t *v, size_t i, jl_value_t *rhs) JL_NOTSAFEPOINT { jl_datatype_t *st = (jl_datatype_t*)jl_typeof(v); size_t offs = jl_field_offset(st, i); diff --git a/src/julia.h b/src/julia.h index 509d2a37e19f2..ed0460fefb64c 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1268,7 +1268,7 @@ JL_DLLEXPORT jl_value_t *jl_get_nth_field(jl_value_t *v, size_t i); JL_DLLEXPORT jl_value_t *jl_get_nth_field_noalloc(jl_value_t *v JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_value_t *jl_get_nth_field_checked(jl_value_t *v, size_t i); JL_DLLEXPORT void jl_set_nth_field(jl_value_t *v, size_t i, - jl_value_t *rhs); + jl_value_t *rhs) JL_NOTSAFEPOINT; JL_DLLEXPORT int jl_field_isdefined(jl_value_t *v, size_t i); JL_DLLEXPORT jl_value_t *jl_get_field(jl_value_t *o, const char *fld); JL_DLLEXPORT jl_value_t *jl_value_ptr(jl_value_t *a); diff --git a/src/support/dtypes.h b/src/support/dtypes.h index 4dfc945dbf7dd..bd75ea3a9913c 100644 --- a/src/support/dtypes.h +++ b/src/support/dtypes.h @@ -13,6 +13,7 @@ #endif #include "platform.h" +#include "analyzer_annotations.h" #if !defined(_OS_WINDOWS_) #include @@ -144,7 +145,7 @@ typedef uint32_t uint_t; typedef int32_t int_t; #endif -STATIC_INLINE unsigned int next_power_of_two(unsigned int val) +STATIC_INLINE unsigned int next_power_of_two(unsigned int val) JL_NOTSAFEPOINT { /* this function taken from libuv src/unix/core.c */ val -= 1; From b2babff79182d2ce93f1eb6d0826ec1257480d71 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 17 Aug 2018 19:21:38 -0400 Subject: [PATCH 043/110] Add analyzer annotations for dump.c --- src/dump.c | 92 ++++++++++++++++++++++++----------------------- src/julia.h | 4 +-- src/module.c | 2 +- src/support/ios.h | 3 +- 4 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/dump.c b/src/dump.c index c18865125e6c8..17d72a5ab86be 100644 --- a/src/dump.c +++ b/src/dump.c @@ -60,7 +60,9 @@ static arraylist_t reinit_list; // list of stuff that is being serialized // (only used by the incremental serializer in MODE_MODULE) -static jl_array_t *serializer_worklist; +// This is not quite globally rooted, but we take care to only +// ever assigned rooted values here. +static jl_array_t *serializer_worklist JL_GLOBALLY_ROOTED; // inverse of backedges tree // (only used by the incremental serializer in MODE_MODULE) @@ -160,48 +162,48 @@ static arraylist_t builtin_typenames; /* read and write in host byte order */ -static void write_int32(ios_t *s, int32_t i) +static void write_int32(ios_t *s, int32_t i) JL_NOTSAFEPOINT { ios_write(s, (char*)&i, 4); } -static int32_t read_int32(ios_t *s) +static int32_t read_int32(ios_t *s) JL_NOTSAFEPOINT { int32_t x = 0; ios_read(s, (char*)&x, 4); return x; } -static void write_uint64(ios_t *s, uint64_t i) +static void write_uint64(ios_t *s, uint64_t i) JL_NOTSAFEPOINT { ios_write(s, (char*)&i, 8); } -static uint64_t read_uint64(ios_t *s) +static uint64_t read_uint64(ios_t *s) JL_NOTSAFEPOINT { uint64_t x = 0; ios_read(s, (char*)&x, 8); return x; } -static void write_int64(ios_t *s, int64_t i) +static void write_int64(ios_t *s, int64_t i) JL_NOTSAFEPOINT { ios_write(s, (char*)&i, 8); } -static void write_uint16(ios_t *s, uint16_t i) +static void write_uint16(ios_t *s, uint16_t i) JL_NOTSAFEPOINT { ios_write(s, (char*)&i, 2); } -static uint16_t read_uint16(ios_t *s) +static uint16_t read_uint16(ios_t *s) JL_NOTSAFEPOINT { int16_t x = 0; ios_read(s, (char*)&x, 2); return x; } -static void write_float64(ios_t *s, double x) +static void write_float64(ios_t *s, double x) JL_NOTSAFEPOINT { write_uint64(s, *((uint64_t*)&x)); } @@ -209,10 +211,10 @@ static void write_float64(ios_t *s, double x) // --- serialize --- #define jl_serialize_value(s, v) jl_serialize_value_((s), (jl_value_t*)(v), 0) -static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_literal); -static jl_value_t *jl_deserialize_value(jl_serializer_state *s, jl_value_t **loc); +static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_literal) JL_GC_DISABLED; +static jl_value_t *jl_deserialize_value(jl_serializer_state *s, jl_value_t **loc) JL_GC_DISABLED; -static int module_in_worklist(jl_module_t *mod) +static int module_in_worklist(jl_module_t *mod) JL_NOTSAFEPOINT { int i, l = jl_array_len(serializer_worklist); for (i = 0; i < l; i++) { @@ -226,7 +228,7 @@ static int module_in_worklist(jl_module_t *mod) // compute whether a type references something internal to worklist // and thus could not have existed before deserialize // and thus does not need delayed unique-ing -static int type_in_worklist(jl_datatype_t *dt) +static int type_in_worklist(jl_datatype_t *dt) JL_NOTSAFEPOINT { if (module_in_worklist(dt->name->module)) return 1; @@ -241,7 +243,7 @@ static int type_in_worklist(jl_datatype_t *dt) static int type_recursively_external(jl_datatype_t *dt); -static int type_parameter_recursively_external(jl_value_t *p0) +static int type_parameter_recursively_external(jl_value_t *p0) JL_NOTSAFEPOINT { jl_datatype_t *p = (jl_datatype_t*)p0; while (jl_is_unionall(p)) { @@ -263,7 +265,7 @@ static int type_parameter_recursively_external(jl_value_t *p0) } // returns true if all of the parameters are tag 6 or 7 -static int type_recursively_external(jl_datatype_t *dt) +static int type_recursively_external(jl_datatype_t *dt) JL_NOTSAFEPOINT { if (dt->uid == 0) return 0; @@ -279,7 +281,7 @@ static int type_recursively_external(jl_datatype_t *dt) } -static void jl_serialize_datatype(jl_serializer_state *s, jl_datatype_t *dt) +static void jl_serialize_datatype(jl_serializer_state *s, jl_datatype_t *dt) JL_GC_DISABLED { int tag = 0; int internal = module_in_worklist(dt->name->module); @@ -460,7 +462,7 @@ static int is_ast_node(jl_value_t *v) jl_typeis(v, jl_lineinfonode_type); } -static int literal_val_id(jl_serializer_state *s, jl_value_t *v) +static int literal_val_id(jl_serializer_state *s, jl_value_t *v) JL_GC_DISABLED { jl_array_t *rs = s->method->roots; int i, l = jl_array_len(rs); @@ -480,7 +482,7 @@ static int literal_val_id(jl_serializer_state *s, jl_value_t *v) return jl_array_len(rs) - 1; } -static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_literal) +static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_literal) JL_GC_DISABLED { if (v == NULL) { write_uint8(s->s, TAG_NULL); @@ -1056,7 +1058,7 @@ static void jl_collect_missing_backedges_to_mod(jl_methtable_t *mt) // the intent of this function is to invert the backedges tree // for anything that points to a method not part of the worklist -static void collect_backedges(jl_method_instance_t *callee) +static void collect_backedges(jl_method_instance_t *callee) JL_GC_DISABLED { jl_array_t *backedges = callee->backedges; if (backedges) { @@ -1075,7 +1077,7 @@ static void collect_backedges(jl_method_instance_t *callee) } -static int jl_collect_backedges_to_mod(jl_typemap_entry_t *ml, void *closure) +static int jl_collect_backedges_to_mod(jl_typemap_entry_t *ml, void *closure) JL_GC_DISABLED { (void)(jl_array_t*)closure; jl_method_instance_t *callee = ml->func.linfo; @@ -1083,7 +1085,7 @@ static int jl_collect_backedges_to_mod(jl_typemap_entry_t *ml, void *closure) return 1; } -static int jl_collect_methcache_from_mod(jl_typemap_entry_t *ml, void *closure) +static int jl_collect_methcache_from_mod(jl_typemap_entry_t *ml, void *closure) JL_GC_DISABLED { jl_array_t *s = (jl_array_t*)closure; jl_method_t *m = ml->func.method; @@ -1097,12 +1099,12 @@ static int jl_collect_methcache_from_mod(jl_typemap_entry_t *ml, void *closure) return 1; } -static void jl_collect_methtable_from_mod(jl_array_t *s, jl_typename_t *tn) +static void jl_collect_methtable_from_mod(jl_array_t *s, jl_typename_t *tn) JL_GC_DISABLED { jl_typemap_visitor(tn->mt->defs, jl_collect_methcache_from_mod, (void*)s); } -static void jl_collect_lambdas_from_mod(jl_array_t *s, jl_module_t *m) +static void jl_collect_lambdas_from_mod(jl_array_t *s, jl_module_t *m) JL_GC_DISABLED { if (module_in_worklist(m)) return; @@ -1138,7 +1140,7 @@ static void jl_collect_lambdas_from_mod(jl_array_t *s, jl_module_t *m) } // flatten the backedge map reachable from caller into callees -static void jl_collect_backedges_to(jl_method_instance_t *caller, htable_t *all_callees) +static void jl_collect_backedges_to(jl_method_instance_t *caller, htable_t *all_callees) JL_GC_DISABLED { jl_array_t **pcallees = (jl_array_t**)ptrhash_bp(&edges_map, (void*)caller), *callees = *pcallees; @@ -1245,7 +1247,7 @@ static void write_work_list(ios_t *s) write_int32(s, 0); } -static void write_module_path(ios_t *s, jl_module_t *depmod) +static void write_module_path(ios_t *s, jl_module_t *depmod) JL_NOTSAFEPOINT { if (depmod->parent == jl_main_module || depmod->parent == depmod) return; @@ -1322,7 +1324,7 @@ static int64_t write_dependency_list(ios_t *s, jl_array_t **udepsp, jl_array_t * // --- deserialize --- -static jl_value_t *jl_deserialize_datatype(jl_serializer_state *s, int pos, jl_value_t **loc) +static jl_value_t *jl_deserialize_datatype(jl_serializer_state *s, int pos, jl_value_t **loc) JL_GC_DISABLED { int tag = read_uint8(s->s); if (tag == 6 || tag == 7) { @@ -1454,7 +1456,7 @@ static jl_value_t *jl_deserialize_datatype(jl_serializer_state *s, int pos, jl_v return (jl_value_t*)dt; } -static jl_value_t *jl_deserialize_value_svec(jl_serializer_state *s, uint8_t tag) +static jl_value_t *jl_deserialize_value_svec(jl_serializer_state *s, uint8_t tag) JL_GC_DISABLED { int usetable = (s->mode != MODE_IR); size_t i, len; @@ -1472,7 +1474,7 @@ static jl_value_t *jl_deserialize_value_svec(jl_serializer_state *s, uint8_t tag return (jl_value_t*)sv; } -static jl_value_t *jl_deserialize_value_symbol(jl_serializer_state *s, uint8_t tag) +static jl_value_t *jl_deserialize_value_symbol(jl_serializer_state *s, uint8_t tag) JL_GC_DISABLED { int usetable = (s->mode != MODE_IR); size_t len; @@ -1491,7 +1493,7 @@ static jl_value_t *jl_deserialize_value_symbol(jl_serializer_state *s, uint8_t t return sym; } -static jl_value_t *jl_deserialize_value_array(jl_serializer_state *s, uint8_t tag) +static jl_value_t *jl_deserialize_value_array(jl_serializer_state *s, uint8_t tag) JL_GC_DISABLED { int usetable = (s->mode != MODE_IR); int16_t i, ndims; @@ -1537,7 +1539,7 @@ static jl_value_t *jl_deserialize_value_array(jl_serializer_state *s, uint8_t ta return (jl_value_t*)a; } -static jl_value_t *jl_deserialize_value_expr(jl_serializer_state *s, uint8_t tag) +static jl_value_t *jl_deserialize_value_expr(jl_serializer_state *s, uint8_t tag) JL_GC_DISABLED { int usetable = (s->mode != MODE_IR); size_t i, len; @@ -1571,7 +1573,7 @@ static jl_value_t *jl_deserialize_value_expr(jl_serializer_state *s, uint8_t tag return (jl_value_t*)e; } -static jl_value_t *jl_deserialize_value_phi(jl_serializer_state *s, uint8_t tag) +static jl_value_t *jl_deserialize_value_phi(jl_serializer_state *s, uint8_t tag) JL_GC_DISABLED { int usetable = (s->mode != MODE_IR); size_t i, len_e, len_v; @@ -1598,7 +1600,7 @@ static jl_value_t *jl_deserialize_value_phi(jl_serializer_state *s, uint8_t tag) return phi; } -static jl_value_t *jl_deserialize_value_phic(jl_serializer_state *s, uint8_t tag) +static jl_value_t *jl_deserialize_value_phic(jl_serializer_state *s, uint8_t tag) JL_GC_DISABLED { int usetable = (s->mode != MODE_IR); size_t i, len; @@ -1617,7 +1619,7 @@ static jl_value_t *jl_deserialize_value_phic(jl_serializer_state *s, uint8_t tag return phic; } -static jl_value_t *jl_deserialize_value_method(jl_serializer_state *s, jl_value_t **loc) +static jl_value_t *jl_deserialize_value_method(jl_serializer_state *s, jl_value_t **loc) JL_GC_DISABLED { int usetable = (s->mode != MODE_IR); jl_method_t *m = @@ -1673,7 +1675,7 @@ static jl_value_t *jl_deserialize_value_method(jl_serializer_state *s, jl_value_ return (jl_value_t*)m; } -static jl_value_t *jl_deserialize_value_method_instance(jl_serializer_state *s, jl_value_t **loc) +static jl_value_t *jl_deserialize_value_method_instance(jl_serializer_state *s, jl_value_t **loc) JL_GC_DISABLED { int usetable = (s->mode != MODE_IR); jl_method_instance_t *li = @@ -1741,7 +1743,7 @@ static jl_value_t *jl_deserialize_value_method_instance(jl_serializer_state *s, return (jl_value_t*)li; } -static jl_value_t *jl_deserialize_value_module(jl_serializer_state *s) +static jl_value_t *jl_deserialize_value_module(jl_serializer_state *s) JL_GC_DISABLED { int usetable = (s->mode != MODE_IR); uintptr_t pos = backref_list.len; @@ -1801,7 +1803,7 @@ static jl_value_t *jl_deserialize_value_module(jl_serializer_state *s) return (jl_value_t*)m; } -static jl_value_t *jl_deserialize_value_globalref(jl_serializer_state *s) +static jl_value_t *jl_deserialize_value_globalref(jl_serializer_state *s) JL_GC_DISABLED { int usetable = (s->mode != MODE_IR); if (usetable) { @@ -1819,7 +1821,7 @@ static jl_value_t *jl_deserialize_value_globalref(jl_serializer_state *s) } } -static jl_value_t *jl_deserialize_value_singleton(jl_serializer_state *s, jl_value_t **loc) +static jl_value_t *jl_deserialize_value_singleton(jl_serializer_state *s, jl_value_t **loc) JL_GC_DISABLED { if (s->mode == MODE_IR) { jl_datatype_t *dt = (jl_datatype_t*)jl_deserialize_value(s, NULL); @@ -1845,7 +1847,7 @@ static jl_value_t *jl_deserialize_value_singleton(jl_serializer_state *s, jl_val return v; } -static void jl_deserialize_struct(jl_serializer_state *s, jl_value_t *v, size_t startfield) +static void jl_deserialize_struct(jl_serializer_state *s, jl_value_t *v, size_t startfield) JL_GC_DISABLED { jl_datatype_t *dt = (jl_datatype_t*)jl_typeof(v); size_t i, nf = jl_datatype_nfields(dt); @@ -1887,7 +1889,7 @@ static void jl_deserialize_struct(jl_serializer_state *s, jl_value_t *v, size_t } } -static jl_value_t *jl_deserialize_typemap_entry(jl_serializer_state *s) +static jl_value_t *jl_deserialize_typemap_entry(jl_serializer_state *s) JL_GC_DISABLED { int N = read_int32(s->s); int n = N; jl_value_t *te = jl_nothing; @@ -1914,7 +1916,7 @@ static jl_value_t *jl_deserialize_typemap_entry(jl_serializer_state *s) return te; } -static jl_value_t *jl_deserialize_value_any(jl_serializer_state *s, uint8_t tag, jl_value_t **loc) +static jl_value_t *jl_deserialize_value_any(jl_serializer_state *s, uint8_t tag, jl_value_t **loc) JL_GC_DISABLED { int usetable = (s->mode != MODE_IR); int32_t sz = (tag == TAG_SHORT_GENERAL ? read_uint8(s->s) : read_int32(s->s)); @@ -1960,7 +1962,7 @@ static jl_value_t *jl_deserialize_value_any(jl_serializer_state *s, uint8_t tag, return v; } -static jl_value_t *jl_deserialize_value(jl_serializer_state *s, jl_value_t **loc) +static jl_value_t *jl_deserialize_value(jl_serializer_state *s, jl_value_t **loc) JL_GC_DISABLED { assert(!ios_eof(s->s)); jl_value_t *v; @@ -2169,7 +2171,7 @@ static void jl_insert_methods(jl_array_t *list) } } -static size_t lowerbound_dependent_world_set(size_t world, arraylist_t *dependent_worlds) +static size_t lowerbound_dependent_world_set(size_t world, arraylist_t *dependent_worlds) JL_NOTSAFEPOINT { size_t i, l = dependent_worlds->len; if (world <= (size_t)dependent_worlds->items[l - 1]) @@ -2765,7 +2767,7 @@ static int jl_invalid_types_equal(jl_datatype_t *a, jl_datatype_t *b) } #endif -static jl_datatype_t *jl_recache_type(jl_datatype_t *dt, size_t start, jl_value_t *v) +static jl_datatype_t *jl_recache_type(jl_datatype_t *dt, size_t start, jl_value_t *v) JL_GC_DISABLED { if (v == NULL) v = dt->instance; // the instance before unique'ing @@ -2834,6 +2836,7 @@ static jl_datatype_t *jl_recache_type(jl_datatype_t *dt, size_t start, jl_value_ } else if (v == o) { if (t->instance != v) { + assert(loc); *loc = t->instance; if (offs > 0) backref_list.items[offs] = t->instance; @@ -2853,7 +2856,7 @@ static jl_datatype_t *jl_recache_type(jl_datatype_t *dt, size_t start, jl_value_ return t; } -static void jl_recache_types(void) +static void jl_recache_types(void) JL_GC_DISABLED { size_t i = 0; while (i < flagref_list.len) { @@ -2891,6 +2894,7 @@ static void jl_recache_types(void) if (t->instance != v) { jl_set_typeof(v, (void*)(intptr_t)0x20); // invalidate the old value to help catch errors if (v == o) { + assert(loc); *loc = t->instance; if (offs > 0) backref_list.items[offs] = t->instance; diff --git a/src/julia.h b/src/julia.h index ed0460fefb64c..c7f73e2426df5 100644 --- a/src/julia.h +++ b/src/julia.h @@ -786,7 +786,7 @@ STATIC_INLINE jl_value_t *jl_array_ptr_set( void *a JL_ROOTING_ARGUMENT, size_t i, void *x JL_ROOTED_ARGUMENT) JL_NOTSAFEPOINT; #else -STATIC_INLINE jl_value_t *jl_array_ptr_ref(void *a JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; +STATIC_INLINE jl_value_t *jl_array_ptr_ref(void *a JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT { assert(i < jl_array_len(a)); return ((jl_value_t**)(jl_array_data(a)))[i]; @@ -1358,7 +1358,7 @@ STATIC_INLINE jl_function_t *jl_get_function(jl_module_t *m, const char *name) { return (jl_function_t*)jl_get_global(m, jl_symbol(name)); } -int jl_is_submodule(jl_module_t *child, jl_module_t *parent); +int jl_is_submodule(jl_module_t *child, jl_module_t *parent) JL_NOTSAFEPOINT; // eq hash tables JL_DLLEXPORT jl_array_t *jl_eqtable_put(jl_array_t *h, void *key, void *val, int *inserted); diff --git a/src/module.c b/src/module.c index b037b19c7a6cc..b676360f928f9 100644 --- a/src/module.c +++ b/src/module.c @@ -671,7 +671,7 @@ JL_DLLEXPORT jl_uuid_t jl_module_uuid(jl_module_t* m) { return m->uuid; } // TODO: make this part of the module constructor and read-only? JL_DLLEXPORT void jl_set_module_uuid(jl_module_t *m, jl_uuid_t uuid) { m->uuid = uuid; } -int jl_is_submodule(jl_module_t *child, jl_module_t *parent) +int jl_is_submodule(jl_module_t *child, jl_module_t *parent) JL_NOTSAFEPOINT { while (1) { if (parent == child) diff --git a/src/support/ios.h b/src/support/ios.h index 9d74d3033269e..0f47b61e387fc 100644 --- a/src/support/ios.h +++ b/src/support/ios.h @@ -5,6 +5,7 @@ #include #include "uv.h" +#include "analyzer_annotations.h" #ifdef __cplusplus extern "C" { @@ -74,7 +75,7 @@ extern void (*ios_set_io_wait_func)(int); /* low-level interface functions */ JL_DLLEXPORT size_t ios_read(ios_t *s, char *dest, size_t n); JL_DLLEXPORT size_t ios_readall(ios_t *s, char *dest, size_t n); -JL_DLLEXPORT size_t ios_write(ios_t *s, const char *data, size_t n); +JL_DLLEXPORT size_t ios_write(ios_t *s, const char *data, size_t n) JL_NOTSAFEPOINT; JL_DLLEXPORT int64_t ios_seek(ios_t *s, int64_t pos); // absolute seek JL_DLLEXPORT int64_t ios_seek_end(ios_t *s); JL_DLLEXPORT int64_t ios_skip(ios_t *s, int64_t offs); // relative seek From dbcc152fcdf03be537032a045117e8c8caf08b51 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Sat, 18 Aug 2018 21:30:41 +0200 Subject: [PATCH 044/110] Misc doc improvements (#28719) * doc: remove unused file. * doc: improve docstring of at-big_str * doc: fix some broken links --- base/int.jl | 15 ++++++++++++--- doc/src/base/numbers.md | 16 +++++++++------- doc/src/manual/index.md | 39 --------------------------------------- 3 files changed, 21 insertions(+), 49 deletions(-) delete mode 100644 doc/src/manual/index.md diff --git a/base/int.jl b/base/int.jl index e6610e9af4774..718542e0e13ea 100644 --- a/base/int.jl +++ b/base/int.jl @@ -579,9 +579,18 @@ end @big_str str @big_str(str) -`@big_str` parses a string into a BigInt -Throws an `ArgumentError` if the string is not a valid integer -Removes all underscores `_` from the string +Parse a string into a [`BigInt`](@ref) or [`BigFloat`](@ref), +and throw an `ArgumentError` if the string is not a valid number. +For integers `_` is allowed in the string as a separator. + +# Examples +```jldoctest +julia> big"123_456" +123456 + +julia> big"7891.5" +7.8915e+03 +``` """ macro big_str(s) if '_' in s diff --git a/doc/src/base/numbers.md b/doc/src/base/numbers.md index 190584bb0f8f4..50e6d2b7134da 100644 --- a/doc/src/base/numbers.md +++ b/doc/src/base/numbers.md @@ -89,8 +89,6 @@ Base.isinteger Base.isreal Core.Float32(::Any) Core.Float64(::Any) -Base.GMP.BigInt(::Any) -Base.MPFR.BigFloat(::Any) Base.Rounding.rounding Base.Rounding.setrounding(::Type, ::Any) Base.Rounding.setrounding(::Function, ::Type, ::RoundingMode) @@ -113,18 +111,22 @@ Base.@int128_str Base.@uint128_str ``` -## BigFloats +## BigFloats and BigInts -The [`BigFloat`](@ref) type implements arbitrary-precision floating-point arithmetic using -the [GNU MPFR library](http://www.mpfr.org/). +The [`BigFloat`](@ref) and [`BigInt`](@ref) types implements +arbitrary-precision floating point and integer arithmetic, respectively. For +[`BigFloat`](@ref) the [GNU MPFR library](http://www.mpfr.org/) is used, +and for [`BigInt`](@ref) the [GNU Multiple Precision Arithmetic Library (GMP)] +(https://gmplib.org) is used. ```@docs +Base.MPFR.BigFloat(::Any) Base.precision Base.MPFR.precision(::Type{BigFloat}) Base.MPFR.setprecision Base.MPFR.BigFloat(x, prec::Int) -BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) +Base.MPFR.BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) Base.MPFR.BigFloat(x, prec::Int, rounding::RoundingMode) -Base.MPFR.BigFloat(x::String) +Base.GMP.BigInt(::Any) Base.@big_str ``` diff --git a/doc/src/manual/index.md b/doc/src/manual/index.md deleted file mode 100644 index 3ae00cff847e6..0000000000000 --- a/doc/src/manual/index.md +++ /dev/null @@ -1,39 +0,0 @@ -# The Julia Manual - - * [Introduction](@ref man-introduction) - * [Getting Started](@ref man-getting-started) - * [Variables](@ref) - * [Integers and Floating-Point Numbers](@ref) - * [Mathematical Operations and Elementary Functions](@ref) - * [Complex and Rational Numbers](@ref) - * [Strings](@ref) - * [Functions](@ref) - * [Control Flow](@ref) - * [Scope of Variables](@ref scope-of-variables) - * [Types](@ref man-types) - * [Methods](@ref) - * [Constructors](@ref man-constructors) - * [Conversion and Promotion](@ref conversion-and-promotion) - * [Interfaces](@ref) - * [Modules](@ref) - * [Documentation](@ref) - * [Metaprogramming](@ref) - * [Multi-dimensional Arrays](@ref man-multi-dim-arrays) - * [Missing Values](@ref missing) - * [Networking and Streams](@ref) - * [Parallel Computing](@ref) - * [Dates](@ref) - * [Running External Programs](@ref) - * [Calling C and Fortran Code](@ref) - * [Handling Operating System Variation](@ref) - * [Environment Variables](@ref) - * [Embedding Julia](@ref) - * [Profiling](@ref) - * [Memory allocation analysis](@ref) - * [Stack Traces](@ref) - * [Performance Tips](@ref man-performance-tips) - * [Workflow Tips](@ref man-workflow-tips) - * [Style Guide](@ref) - * [Frequently Asked Questions](@ref) - * [Noteworthy Differences from other Languages](@ref) - * [Unicode Input](@ref) From 3ae8df155a0212ed3a3fb67195bf39c37d5d4a6a Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 15:06:12 -0400 Subject: [PATCH 045/110] Fix missing GC root in interpreter.c Static analysis complains in relevant part: ``` /home/keno/julia-1.0/src/interpreter.c:154:9: warning: Argument value may have been GCed jl_set_datatype_super(dt, super); ^ /home/keno/julia-1.0/src/interpreter.c:144:10: note: Started tracking value here dt = jl_new_abstracttype(name, modu, NULL, (jl_svec_t*)para); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/keno/julia-1.0/src/interpreter.c:146:23: note: Value may have been GCed here jl_binding_t *b = jl_get_binding_wr(modu, (jl_sym_t*)name, 1); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/keno/julia-1.0/src/interpreter.c:154:9: note: Argument value may have been GCed jl_set_datatype_super(dt, super); ^ ~~ ``` Seems true to me. Add `dt` to the roots in this function. --- src/interpreter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interpreter.c b/src/interpreter.c index 030fb4a709912..5e72aafc8f9f2 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -134,7 +134,7 @@ static void eval_abstracttype(jl_expr_t *ex, interpreter_state *s) jl_datatype_t *dt = NULL; jl_value_t *w = NULL; jl_module_t *modu = s->module; - JL_GC_PUSH4(¶, &super, &temp, &w); + JL_GC_PUSH5(¶, &super, &temp, &w, &dt); assert(jl_is_svec(para)); if (jl_is_globalref(name)) { modu = jl_globalref_mod(name); From 54bc9ee6687a8f38c52154baf32ecb9bd6e43b31 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 15:23:14 -0400 Subject: [PATCH 046/110] Fix another missing GC root --- src/interpreter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/interpreter.c b/src/interpreter.c index 5e72aafc8f9f2..70beff9ba0b18 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -397,7 +397,9 @@ SECT_INTERP static jl_value_t *eval_value(jl_value_t *e, interpreter_state *s) if (jl_is_pinode(e)) { jl_value_t *val = eval_value(jl_fieldref_noalloc(e, 0), s); #ifndef JL_NDEBUG + JL_GC_PUSH1(&val); jl_typeassert(val, jl_fieldref_noalloc(e, 1)); + JL_GC_POP(); #endif return val; } From af3331b7782c08e63a076b9f143b1f6dad512ba8 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 18:15:26 -0400 Subject: [PATCH 047/110] Fix missing gc root in jl_cglobal Static analysis complains that the jl_fieldref could allocate, which then gets passed to jl_bitcast unrooted. I believe it's right about that. While we're here, also fix what I believe is a typo (`ty` vs `v`). --- src/runtime_intrinsics.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index 5caa7bf6f137f..92c19c8fe5898 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -78,8 +78,9 @@ JL_DLLEXPORT jl_value_t *jl_pointerset(jl_value_t *p, jl_value_t *x, jl_value_t JL_DLLEXPORT jl_value_t *jl_cglobal(jl_value_t *v, jl_value_t *ty) { JL_TYPECHK(cglobal, type, ty); + JL_GC_PUSH1(&v); jl_value_t *rt = - v == (jl_value_t*)jl_void_type ? (jl_value_t*)jl_voidpointer_type : // a common case + ty == (jl_value_t*)jl_void_type ? (jl_value_t*)jl_voidpointer_type : // a common case (jl_value_t*)jl_apply_type1((jl_value_t*)jl_pointer_type, ty); if (!jl_is_concrete_type(rt)) @@ -88,8 +89,11 @@ JL_DLLEXPORT jl_value_t *jl_cglobal(jl_value_t *v, jl_value_t *ty) if (jl_is_tuple(v) && jl_nfields(v) == 1) v = jl_fieldref(v, 0); - if (jl_is_pointer(v)) - return jl_bitcast(rt, v); + if (jl_is_pointer(v)) { + v = jl_bitcast(rt, v); + JL_GC_POP(); + return v; + } char *f_lib = NULL; if (jl_is_tuple(v) && jl_nfields(v) > 1) { @@ -120,6 +124,7 @@ JL_DLLEXPORT jl_value_t *jl_cglobal(jl_value_t *v, jl_value_t *ty) jl_value_t *jv = jl_gc_alloc_1w(); jl_set_typeof(jv, rt); *(void**)jl_data_ptr(jv) = ptr; + JL_GC_POP(); return jv; } From 46e7a566f1897468d86133db8d3d021e0c9a3f5e Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sat, 18 Aug 2018 23:01:50 -0400 Subject: [PATCH 048/110] update AArch64 code model patch for 6.0.1 --- deps/llvm.mk | 4 ++ ...lvm-D27629-AArch64-large_model_6.0.1.patch | 53 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 deps/patches/llvm-D27629-AArch64-large_model_6.0.1.patch diff --git a/deps/llvm.mk b/deps/llvm.mk index ec584b39e357c..e3c9f6c5823a1 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -385,7 +385,11 @@ LLVM_PATCH_PREV := $$(LLVM_SRC_DIR)/$1.patch-applied endef ifeq ($(LLVM_VER_SHORT),6.0) +ifeq ($(LLVM_VER_PATCH), 0) $(eval $(call LLVM_PATCH,llvm-D27629-AArch64-large_model_4.0)) +else +$(eval $(call LLVM_PATCH,llvm-D27629-AArch64-large_model_6.0.1)) +endif $(eval $(call LLVM_PATCH,llvm-D34078-vectorize-fdiv)) $(eval $(call LLVM_PATCH,llvm-6.0-NVPTX-addrspaces)) # NVPTX $(eval $(call LLVM_PATCH,llvm-D42262-jumpthreading-not-i1)) # remove for 7.0 diff --git a/deps/patches/llvm-D27629-AArch64-large_model_6.0.1.patch b/deps/patches/llvm-D27629-AArch64-large_model_6.0.1.patch new file mode 100644 index 0000000000000..89beefdd157e5 --- /dev/null +++ b/deps/patches/llvm-D27629-AArch64-large_model_6.0.1.patch @@ -0,0 +1,53 @@ +From f76abe65e6d07fea5e838c4f8c9a9421c16debb0 Mon Sep 17 00:00:00 2001 +From: Valentin Churavy +Date: Thu, 5 Jul 2018 12:37:50 -0400 +Subject: [PATCH] Fix unwind info relocation with large code model on AArch64 + +--- + lib/MC/MCObjectFileInfo.cpp | 2 ++ + .../AArch64/ELF_ARM64_large-relocations.s | 20 +++++++++++++++++++ + 2 files changed, 22 insertions(+) + create mode 100644 test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_large-relocations.s + +diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp +index 328f000f37c..938b35f20d1 100644 +--- a/lib/MC/MCObjectFileInfo.cpp ++++ b/lib/MC/MCObjectFileInfo.cpp +@@ -291,6 +291,8 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) { + break; + case Triple::ppc64: + case Triple::ppc64le: ++ case Triple::aarch64: ++ case Triple::aarch64_be: + case Triple::x86_64: + FDECFIEncoding = dwarf::DW_EH_PE_pcrel | + (Large ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); +diff --git a/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_large-relocations.s b/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_large-relocations.s +new file mode 100644 +index 00000000000..66f28dabd79 +--- /dev/null ++++ b/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_large-relocations.s +@@ -0,0 +1,20 @@ ++# RUN: llvm-mc -triple=arm64-none-linux-gnu -large-code-model -filetype=obj -o %T/large-reloc.o %s ++# RUN: llvm-rtdyld -triple=arm64-none-linux-gnu -verify -map-section large-reloc.o,.eh_frame=0x10000 -map-section large-reloc.o,.text=0xffff000000000000 -check=%s %T/large-reloc.o ++# RUN-BE: llvm-mc -triple=aarch64_be-none-linux-gnu -large-code-model -filetype=obj -o %T/be-large-reloc.o %s ++# RUN-BE: llvm-rtdyld -triple=aarch64_be-none-linux-gnu -verify -map-section be-large-reloc.o,.eh_frame=0x10000 -map-section be-large-reloc.o,.text=0xffff000000000000 -check=%s %T/be-large-reloc.o ++ ++ .text ++ .globl g ++ .p2align 2 ++ .type g,@function ++g: ++ .cfi_startproc ++ mov x0, xzr ++ ret ++ .Lfunc_end0: ++ .size g, .Lfunc_end0-g ++ .cfi_endproc ++ ++# Skip the CIE and load the 8 bytes PC begin pointer. ++# Assuming the CIE and the FDE length are both 4 bytes. ++# rtdyld-check: *{8}(section_addr(large-reloc.o, .eh_frame) + (*{4}(section_addr(large-reloc.o, .eh_frame))) + 0xc) = g - (section_addr(large-reloc.o, .eh_frame) + (*{4}(section_addr(large-reloc.o, .eh_frame))) + 0xc) +-- +2.18.0 + From 8ba726e44e1739f3cd16677f685ef4d298d4dc28 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sat, 18 Aug 2018 17:53:07 -0400 Subject: [PATCH 049/110] upgrade to LLVM 6.0.1 --- deps/Versions.make | 4 ++-- deps/checksums/llvm-6.0.0.src.tar.xz/md5 | 1 - deps/checksums/llvm-6.0.0.src.tar.xz/sha512 | 1 - deps/checksums/llvm-6.0.1.src.tar.xz/md5 | 1 + deps/checksums/llvm-6.0.1.src.tar.xz/sha512 | 1 + 5 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 deps/checksums/llvm-6.0.0.src.tar.xz/md5 delete mode 100644 deps/checksums/llvm-6.0.0.src.tar.xz/sha512 create mode 100644 deps/checksums/llvm-6.0.1.src.tar.xz/md5 create mode 100644 deps/checksums/llvm-6.0.1.src.tar.xz/sha512 diff --git a/deps/Versions.make b/deps/Versions.make index fa58087b065f7..f40fd4d84c8f8 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -1,5 +1,5 @@ -LLVM_VER = 6.0.0 -LLVM_BB_REL = 6 +LLVM_VER = 6.0.1 +LLVM_BB_REL = 1 PCRE_VER = 10.30 DSFMT_VER = 2.2.3 LAPACK_VER = 3.5.0 diff --git a/deps/checksums/llvm-6.0.0.src.tar.xz/md5 b/deps/checksums/llvm-6.0.0.src.tar.xz/md5 deleted file mode 100644 index f2f552adb296b..0000000000000 --- a/deps/checksums/llvm-6.0.0.src.tar.xz/md5 +++ /dev/null @@ -1 +0,0 @@ -788a11a35fa62eb008019b37187d09d2 diff --git a/deps/checksums/llvm-6.0.0.src.tar.xz/sha512 b/deps/checksums/llvm-6.0.0.src.tar.xz/sha512 deleted file mode 100644 index 5d40c04e3e347..0000000000000 --- a/deps/checksums/llvm-6.0.0.src.tar.xz/sha512 +++ /dev/null @@ -1 +0,0 @@ -a71fdd5ddc46f01327ad891cfcc198febdbe10769c57f14d8a4fb7d514621ee4080e1a641200d3353c16a16731d390270499ec6cd3dc98fadc570f3eb6b52b8c diff --git a/deps/checksums/llvm-6.0.1.src.tar.xz/md5 b/deps/checksums/llvm-6.0.1.src.tar.xz/md5 new file mode 100644 index 0000000000000..0c7151e84b867 --- /dev/null +++ b/deps/checksums/llvm-6.0.1.src.tar.xz/md5 @@ -0,0 +1 @@ +c88c98709300ce2c285391f387fecce0 diff --git a/deps/checksums/llvm-6.0.1.src.tar.xz/sha512 b/deps/checksums/llvm-6.0.1.src.tar.xz/sha512 new file mode 100644 index 0000000000000..2e0ff6e648c08 --- /dev/null +++ b/deps/checksums/llvm-6.0.1.src.tar.xz/sha512 @@ -0,0 +1 @@ +cbbb00eb99cfeb4aff623ee1a5ba075e7b5a76fc00c5f9f539ff28c108598f5708a0369d5bd92683def5a20c2fe60cab7827b42d628dbfcc79b57e0e91b84dd9 From 2805ebeb5b1da1d3933aa08514d50af034d031dd Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Sun, 19 Aug 2018 16:39:35 +0900 Subject: [PATCH 050/110] add document on JULIA_PROJECT environment variable (#28556) * add document on JULIA_PROJECT environment variable * wrap file names with backticks [ci skip] --- doc/src/manual/environment-variables.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/src/manual/environment-variables.md b/doc/src/manual/environment-variables.md index b27ff27729afc..d38aa0f21a067 100644 --- a/doc/src/manual/environment-variables.md +++ b/doc/src/manual/environment-variables.md @@ -65,6 +65,15 @@ and a global configuration search path of /etc/julia/startup.jl ``` +### `JULIA_PROJECT` + +A directory path that points to the current Julia project. Setting this +environment variable has the same effect as specifying the `--project` start-up +option, but `--project` has higher precedence. If the variable is set to `@.`, +Julia tries to find a project directory that contains `Project.toml` or +`JuliaProject.toml` file from the current directory and its parents. See also +the chapter on [Code Loading](@ref). + ### `JULIA_LOAD_PATH` A separated list of absolute paths that are to be appended to the variable From a288a2dae4193c245205b05055869d115b08bdba Mon Sep 17 00:00:00 2001 From: annainfo Date: Sun, 19 Aug 2018 10:02:35 +0200 Subject: [PATCH 051/110] Update style-guide.md (#28754) s/Julia's Base/Julia Base - as elsewhere, e.g. Julia Base (notably in intro of https://github.com/JuliaLang/julia/commits/master/doc/src/base/base.md), Julia functions, Julia variables, Julia Function Pointers, Julia startup, Julia runtime --- doc/src/manual/style-guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/manual/style-guide.md b/doc/src/manual/style-guide.md index 624297d8a10fa..a39697d124456 100644 --- a/doc/src/manual/style-guide.md +++ b/doc/src/manual/style-guide.md @@ -130,7 +130,7 @@ a = Vector{Union{Int,AbstractString,Tuple,Array}}(undef, n) In this case `Vector{Any}(undef, n)` is better. It is also more helpful to the compiler to annotate specific uses (e.g. `a[i]::Int`) than to try to pack many alternatives into one type. -## Use naming conventions consistent with Julia's `base/` +## Use naming conventions consistent with Julia `base/` * modules and type names use capitalization and camel case: `module SparseArrays`, `struct UnitRange`. * functions are lowercase ([`maximum`](@ref), [`convert`](@ref)) and, when readable, with multiple @@ -143,7 +143,7 @@ uses (e.g. `a[i]::Int`) than to try to pack many alternatives into one type. If a function name requires multiple words, consider whether it might represent more than one concept and might be better split into pieces. -## Write functions with argument ordering similar to Julia's Base +## Write functions with argument ordering similar to Julia Base As a general rule, the Base library uses the following order of arguments to functions, as applicable: From 90c73b2d0ae4911b511e7b944b0b11b1c4e7da9e Mon Sep 17 00:00:00 2001 From: auxetic <16112973+auxetic@users.noreply.github.com> Date: Sun, 19 Aug 2018 21:59:44 +0800 Subject: [PATCH 052/110] fix typo and format (#28755) --- doc/src/manual/parallel-computing.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/src/manual/parallel-computing.md b/doc/src/manual/parallel-computing.md index 5f18d97e75aa4..a07312182904b 100644 --- a/doc/src/manual/parallel-computing.md +++ b/doc/src/manual/parallel-computing.md @@ -158,7 +158,7 @@ julia> data = [i for i in c] Consider a simple example using channels for inter-task communication. We start 4 tasks to process data from a single `jobs` channel. Jobs, identified by an id (`job_id`), are written to the channel. -Each task in this simulation reads a `job_id`, waits for a random amout of time and writes back +Each task in this simulation reads a `job_id`, waits for a random amount of time and writes back a tuple of `job_id` and the simulated time to the results channel. Finally all the `results` are printed out. @@ -1792,10 +1792,10 @@ mpirun -np 4 ./julia example.jl ``` [^1]: - in this context, mpi refers to the mpi-1 standard. beginning with mpi-2, the mpi standards committee - introduced a new set of communication mechanisms, collectively referred to as remote memory access - (rma). the motivation for adding rma to the mpi standard was to facilitate one-sided communication - patterns. for additional information on the latest mpi standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). + In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee + introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access + (RMA). The motivation for adding rma to the MPI standard was to facilitate one-sided communication + patterns. For additional information on the latest MPI standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). [^2]: [Julia GPU man pages](http://juliagpu.github.io/CUDAnative.jl/stable/man/usage.html#Julia-support-1) From 640fc09189ed513c9f168bee56c43b9245f2f615 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 21:05:40 -0400 Subject: [PATCH 053/110] Fix three missing gc roots in subtyping All found by static analysis. I'm hoping one of them might have been the cause of CI failures like this one: https://circleci.com/gh/JuliaLang/julia/33846?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link --- src/subtype.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index 6b566415ee273..6ecea1840559f 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -598,8 +598,9 @@ static jl_value_t *fix_inferred_var_bound(jl_tvar_t *var, jl_value_t *ty) { if (!jl_is_typevar(ty) && jl_has_free_typevars(ty)) { jl_value_t *ans = ty; - jl_array_t *vs = jl_find_free_typevars(ty); + jl_array_t *vs = NULL; JL_GC_PUSH2(&ans, &vs); + vs = jl_find_free_typevars(ty); int i; for (i = 0; i < jl_array_len(vs); i++) { ans = jl_type_unionall((jl_tvar_t*)jl_array_ptr_ref(vs, i), ans); @@ -630,7 +631,7 @@ static int subtype_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_t *e, int8 btemp = btemp->prev; } jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, NULL, 0, 0, 0, 0, e->invdepth, 0, NULL, e->vars }; - JL_GC_PUSH3(&u, &vb.lb, &vb.ub); + JL_GC_PUSH4(&u, &vb.lb, &vb.ub, &vb.innervars); e->vars = &vb; int ans; if (R) { @@ -1731,7 +1732,9 @@ static int intersect_vararg_length(jl_value_t *v, ssize_t n, jl_stenv_t *e, int8 // only do the check if N is free in the tuple type's last parameter if (jl_is_typevar(N) && N != (jl_value_t*)va_p1 && N != (jl_value_t*)va_p2) { jl_value_t *len = jl_box_long(n); + JL_GC_PUSH1(&len); jl_value_t *il = R ? intersect(len, N, e, 2) : intersect(N, len, e, 2); + JL_GC_POP(); if (il == jl_bottom_type) return 0; } From 64580598afc67308c3f1cd638901274344759aac Mon Sep 17 00:00:00 2001 From: Michael Krabbe Borregaard Date: Sun, 19 Aug 2018 21:14:54 +0200 Subject: [PATCH 054/110] Remove mention of `reload` from the docs; fix #28572 (#28644) * Remove mention of `reload` from the docs --- doc/src/manual/modules.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/doc/src/manual/modules.md b/doc/src/manual/modules.md index 74065606cc4e4..ef073cbe6db23 100644 --- a/doc/src/manual/modules.md +++ b/doc/src/manual/modules.md @@ -232,13 +232,10 @@ For file dependencies, a change is determined by examining whether the modificat of each file loaded by `include` or added explicitly by `include_dependency` is unchanged, or equal to the modification time truncated to the nearest second (to accommodate systems that can't copy mtime with sub-second accuracy). It also takes into account whether the path to the file chosen -by the search logic in `require` matches the path that had created the precompile file. - -It also takes into account the set of dependencies already loaded into the current process and -won't recompile those modules, even if their files change or disappear, in order to avoid creating -incompatibilities between the running system and the precompile cache. If you want to have changes -to the source reflected in the running system, you should call `reload("Module")` on the module -you changed, and any module that depended on it in which you want to see the change reflected. +by the search logic in `require` matches the path that had created the precompile file. It also takes +into account the set of dependencies already loaded into the current process and won't recompile those +modules, even if their files change or disappear, in order to avoid creating incompatibilities between +the running system and the precompile cache. If you know that a module is *not* safe to precompile your module (for example, for one of the reasons described below), you should From 728d31d6c5e6a88f5f27ef929fe44c13caa72dfd Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Sun, 19 Aug 2018 21:17:56 +0200 Subject: [PATCH 055/110] fix shuffle! on empty arrays (#28727) shuffle([]) doesn't work anymore since nextpow2(n) has been replaced by nextpow(2, n), where n == 0. --- stdlib/Random/src/misc.jl | 1 + stdlib/Random/test/runtests.jl | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/stdlib/Random/src/misc.jl b/stdlib/Random/src/misc.jl index 0e7bb9782e500..7b94abb062314 100644 --- a/stdlib/Random/src/misc.jl +++ b/stdlib/Random/src/misc.jl @@ -182,6 +182,7 @@ julia> shuffle!(rng, Vector(1:16)) function shuffle!(r::AbstractRNG, a::AbstractArray) @assert !has_offset_axes(a) n = length(a) + n <= 1 && return a # nextpow below won't work with n == 0 @assert n <= Int64(2)^52 mask = nextpow(2, n) - 1 for i = n:-1:2 diff --git a/stdlib/Random/test/runtests.jl b/stdlib/Random/test/runtests.jl index 91d3db9eb994a..83e4b44e83697 100644 --- a/stdlib/Random/test/runtests.jl +++ b/stdlib/Random/test/runtests.jl @@ -686,3 +686,11 @@ end @test Random.gentype(Random.UInt52(UInt128)) == UInt128 @test Random.gentype(Random.UInt104()) == UInt128 end + +@testset "shuffle[!]" begin + a = [] + @test shuffle(a) == a # issue #28727 + @test shuffle!(a) === a + a = rand(Int, 1) + @test shuffle(a) == a +end From b6b471c8c10558a71eefab58a9fa47326d7b024a Mon Sep 17 00:00:00 2001 From: scls19fr Date: Mon, 20 Aug 2018 00:15:35 +0200 Subject: [PATCH 056/110] Update Enums.jl (#28769) Helps #28768 --- base/Enums.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base/Enums.jl b/base/Enums.jl index 021c8c4bea561..4c457443f678d 100644 --- a/base/Enums.jl +++ b/base/Enums.jl @@ -44,6 +44,9 @@ f (generic function with 1 method) julia> f(apple) "I'm a Fruit with value: 1" + +julia> Fruit(1) +apple::Fruit = 1 ``` Values can also be specified inside a `begin` block, e.g. From 57b3497f1b854967224b5cd344258d1e311e063f Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 19 Aug 2018 15:59:57 -0400 Subject: [PATCH 057/110] Fix gc rooting in exception throwing Most paths to `throw_internal` assume that `e` may be unrooted. However, the static analyzer complains that a transition from gc-safe to gc-unsafe (`jl_gc_unsafe_enter`) is a safepoint, so `e` may have been collected there before it gets assigned to `exception_in_transit` (which is a root). Switch the order of operations to fix that. --- src/task.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/task.c b/src/task.c index 6cd7d8c6727d8..7ec5f7e4be09c 100644 --- a/src/task.c +++ b/src/task.c @@ -548,9 +548,9 @@ void JL_NORETURN throw_internal(jl_value_t *e) ptls->io_wait = 0; if (ptls->safe_restore) jl_longjmp(*ptls->safe_restore, 1); - jl_gc_unsafe_enter(ptls); assert(e != NULL); ptls->exception_in_transit = e; + jl_gc_unsafe_enter(ptls); jl_handler_t *eh = ptls->current_task->eh; if (eh != NULL) { #ifdef ENABLE_TIMINGS From 3a54c14e24aa19741f3dd7d00991def9de7c7c85 Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Mon, 20 Aug 2018 18:09:45 +0900 Subject: [PATCH 058/110] fix description of kwargs... (#28757) * fix description of kwargs... * clarify the key type of dicts passed as kwargs --- doc/src/manual/functions.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/src/manual/functions.md b/doc/src/manual/functions.md index 45c170bf9b1a6..5b57f6a2a435d 100644 --- a/doc/src/manual/functions.md +++ b/doc/src/manual/functions.md @@ -541,6 +541,10 @@ function f(x; y=0, kwargs...) end ``` +Inside `f`, `kwargs` will be a key-value iterator over a named tuple. Named +tuples (as well as dictionaries with keys of `Symbol`) can be passed as keyword +arguments using a semicolon in a call, e.g. `f(x, z=1; kwargs...)`. + If a keyword argument is not assigned a default value in the method definition, then it is *required*: an [`UndefKeywordError`](@ref) exception will be thrown if the caller does not assign it a value: @@ -552,9 +556,6 @@ f(3, y=5) # ok, y is assigned f(3) # throws UndefKeywordError(:y) ``` -Inside `f`, `kwargs` will be a named tuple. Named tuples (as well as dictionaries) can be passed as -keyword arguments using a semicolon in a call, e.g. `f(x, z=1; kwargs...)`. - One can also pass `key => value` expressions after a semicolon. For example, `plot(x, y; :width => 2)` is equivalent to `plot(x, y, width=2)`. This is useful in situations where the keyword name is computed at runtime. From f6c48ebf83983016c158f790a466b354ece7addc Mon Sep 17 00:00:00 2001 From: ExpandingMan Date: Mon, 20 Aug 2018 05:16:47 -0400 Subject: [PATCH 059/110] added documentation for read command methods (#28748) * added documentation for read command methods * fixed docs --- base/process.jl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/base/process.jl b/base/process.jl index d9b15b2e5bfe3..ef690c454d263 100644 --- a/base/process.jl +++ b/base/process.jl @@ -625,6 +625,11 @@ function open(f::Function, cmds::AbstractCmd, args...) return ret end +""" + read(command::Cmd) + +Run `command` and return the resulting output as an array of bytes. +""" function read(cmd::AbstractCmd) procs = open(cmd, "r", devnull) bytes = read(procs.out) @@ -632,6 +637,11 @@ function read(cmd::AbstractCmd) return bytes end +""" + read(command::Cmd, String) + +Run `command` and return the resulting output as a `String`. +""" read(cmd::AbstractCmd, ::Type{String}) = String(read(cmd)) """ From 302a507c470ab2b69193b6a071daa477f12d87c2 Mon Sep 17 00:00:00 2001 From: James Shaw Date: Mon, 20 Aug 2018 16:46:04 +0100 Subject: [PATCH 060/110] fix two typos (#28731) --- doc/src/manual/variables-and-scoping.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/manual/variables-and-scoping.md b/doc/src/manual/variables-and-scoping.md index 496730a4376fa..ab6f1962be0c6 100644 --- a/doc/src/manual/variables-and-scoping.md +++ b/doc/src/manual/variables-and-scoping.md @@ -495,7 +495,7 @@ are constant by default. Note that `const` only affects the variable binding; the variable may be bound to a mutable object (such as an array), and that object may still be modified. Additionally when one tries -to assign a value a variable that is declared constant the following scenarios are possible: +to assign a value to a variable that is declared constant the following scenarios are possible: * if a new value has a different type than the type of the constant then an error is thrown: ```jldoctest @@ -522,7 +522,7 @@ julia> const z = 100 julia> z = 100 100 ``` -The last rule applies for immutable objects even if the vairable binding would change, e.g.: +The last rule applies for immutable objects even if the variable binding would change, e.g.: ```julia-repl julia> const s1 = "1" "1" From ae0738ebc78a4bb79c709e37371e9d6834a014fa Mon Sep 17 00:00:00 2001 From: annainfo Date: Mon, 20 Aug 2018 19:15:38 +0200 Subject: [PATCH 061/110] Update integers-and-floating-point-numbers.md (#28744) --- doc/src/manual/integers-and-floating-point-numbers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/manual/integers-and-floating-point-numbers.md b/doc/src/manual/integers-and-floating-point-numbers.md index b218ab8d582e4..8478d497d91ad 100644 --- a/doc/src/manual/integers-and-floating-point-numbers.md +++ b/doc/src/manual/integers-and-floating-point-numbers.md @@ -215,7 +215,7 @@ UInt128: [0,340282366920938463463374607431768211455] ``` The values returned by [`typemin`](@ref) and [`typemax`](@ref) are always of the given argument -type. (The above expression uses several features we have yet to introduce, including [for loops](@ref man-loops), +type. (The above expression uses several features that have yet to be introduced, including [for loops](@ref man-loops), [Strings](@ref man-strings), and [Interpolation](@ref), but should be easy enough to understand for users with some existing programming experience.) @@ -678,7 +678,7 @@ where syntactic conflicts arise: * The 32-bit floating-point literal expression `1.5f22` could be interpreted as the numeric literal `1.5` multiplied by the variable `f22`. -In all cases, we resolve the ambiguity in favor of interpretation as numeric literals: +In all cases the ambiguity is resolved in favor of interpretation as numeric literals: * Expressions starting with `0x` are always hexadecimal literals. * Expressions starting with a numeric literal followed by `e` or `E` are always floating-point literals. From 4498d27c3c3e11effdfdfdce822d025079f01a0a Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Tue, 21 Aug 2018 06:12:58 -0700 Subject: [PATCH 062/110] Resolve all method ambiguities in LinearAlgebra (#28749) * Add a test to check method ambiguities * Use StridedMatrix to avoid method ambiguity; fixes #27405 * Avoid method ambiguity in promote_leaf_eltypes This change is only for making Test.detect_ambiguities and shouldn't introduce any change in working code (unless it depends on MethodError). Before this change, we have: julia> LinearAlgebra.promote_leaf_eltypes(()) ERROR: MethodError: LinearAlgebra.promote_leaf_eltypes(::Tuple{}) is ambiguous. Candidates: With this change, we have: julia> LinearAlgebra.promote_leaf_eltypes(()) Bool --- stdlib/LinearAlgebra/src/diagonal.jl | 6 +++--- stdlib/LinearAlgebra/src/generic.jl | 4 ++-- stdlib/LinearAlgebra/test/matmul.jl | 4 ++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index 2d2557510cca0..1a5eca3c0ce05 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -277,9 +277,9 @@ mul!(out::AbstractVector, A::Diagonal, in::AbstractVector) = out .= A.diag .* in mul!(out::AbstractVector, A::Adjoint{<:Any,<:Diagonal}, in::AbstractVector) = out .= adjoint.(A.parent.diag) .* in mul!(out::AbstractVector, A::Transpose{<:Any,<:Diagonal}, in::AbstractVector) = out .= transpose.(A.parent.diag) .* in -mul!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) = out .= A.diag .* in -mul!(out::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, in::AbstractMatrix) = out .= adjoint.(A.parent.diag) .* in -mul!(out::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, in::AbstractMatrix) = out .= transpose.(A.parent.diag) .* in +mul!(out::AbstractMatrix, A::Diagonal, in::StridedMatrix) = out .= A.diag .* in +mul!(out::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, in::StridedMatrix) = out .= adjoint.(A.parent.diag) .* in +mul!(out::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, in::StridedMatrix) = out .= transpose.(A.parent.diag) .* in # ambiguities with Symmetric/Hermitian # RealHermSymComplex[Sym]/[Herm] only include Number; invariant to [c]transpose diff --git a/stdlib/LinearAlgebra/src/generic.jl b/stdlib/LinearAlgebra/src/generic.jl index ea23e8d51cee7..ca747db604fc8 100644 --- a/stdlib/LinearAlgebra/src/generic.jl +++ b/stdlib/LinearAlgebra/src/generic.jl @@ -1324,8 +1324,8 @@ julia> promote_leaf_eltypes(a) Complex{Float64} ``` """ -promote_leaf_eltypes(x::Union{AbstractArray{T},Tuple{Vararg{T}}}) where {T<:Number} = T -promote_leaf_eltypes(x::Union{AbstractArray{T},Tuple{Vararg{T}}}) where {T<:NumberArray} = eltype(T) +promote_leaf_eltypes(x::Union{AbstractArray{T},Tuple{T,Vararg{T}}}) where {T<:Number} = T +promote_leaf_eltypes(x::Union{AbstractArray{T},Tuple{T,Vararg{T}}}) where {T<:NumberArray} = eltype(T) promote_leaf_eltypes(x::T) where {T} = T promote_leaf_eltypes(x::Union{AbstractArray,Tuple}) = mapreduce(promote_leaf_eltypes, promote_type, x; init=Bool) diff --git a/stdlib/LinearAlgebra/test/matmul.jl b/stdlib/LinearAlgebra/test/matmul.jl index 7ac8924e63447..a61445128e263 100644 --- a/stdlib/LinearAlgebra/test/matmul.jl +++ b/stdlib/LinearAlgebra/test/matmul.jl @@ -445,4 +445,8 @@ end @test Xv1'*Xv3' ≈ XcXc end +@testset "method ambiguity" begin + @test detect_ambiguities(LinearAlgebra, Base; imported=true, recursive=true) == [] +end + end # module TestMatmul From 9a380fa9f268c7ec1360bb562dad9abd5428159d Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 17 Aug 2018 22:04:52 -0400 Subject: [PATCH 063/110] Add static analysis annotations for gc.c --- doc/src/devdocs/gc-sa.md | 8 ++--- src/gc.c | 78 +++++++++++++++++++++------------------- src/gc.h | 32 +++++++++-------- src/support/arraylist.h | 4 ++- 4 files changed, 66 insertions(+), 56 deletions(-) diff --git a/doc/src/devdocs/gc-sa.md b/doc/src/devdocs/gc-sa.md index 0483d19c044ce..4cf336bec4e31 100644 --- a/doc/src/devdocs/gc-sa.md +++ b/doc/src/devdocs/gc-sa.md @@ -253,10 +253,10 @@ This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that is should only be used if those values are globally rooted by virtue of being a leaftype. The rooting of leaftypes is a bit complicated. They are generally rooted through `cache` field of the corresponding `TypeName`, which itself is -rooted by the containing module (so they're rooted as long as the containing module is ok) and we can generally -assume that leaftypes are rooted where they are used, but we may refine this -property in the future, so the separate annotation helps split out the reason -for being globally rooted. +rooted by the containing module (so they're rooted as long as the containing +module is ok) and we can generally assume that leaftypes are rooted where they +are used, but we may refine this property in the future, so the separate +annotation helps split out the reason for being globally rooted. The analyzer also automatically detects checks for leaftype-ness and will not complain about missing GC roots on these paths. diff --git a/src/gc.c b/src/gc.c index 878fb4f479952..363e9af41b509 100644 --- a/src/gc.c +++ b/src/gc.c @@ -96,7 +96,7 @@ static inline void jl_gc_wait_for_the_world(void) #define malloc_cache_align(sz) jl_malloc_aligned(sz, JL_CACHE_BYTE_ALIGNMENT) #define realloc_cache_align(p, sz, oldsz) jl_realloc_aligned(p, sz, oldsz, JL_CACHE_BYTE_ALIGNMENT) -static void schedule_finalization(void *o, void *f) +static void schedule_finalization(void *o, void *f) JL_NOTSAFEPOINT { arraylist_push(&to_finalize, o); arraylist_push(&to_finalize, f); @@ -125,7 +125,7 @@ static void run_finalizer(jl_ptls_t ptls, jl_value_t *o, jl_value_t *ff) // if `need_sync` is true, the `list` is the `finalizers` list of another // thread and we need additional synchronizations static void finalize_object(arraylist_t *list, jl_value_t *o, - arraylist_t *copied_list, int need_sync) + arraylist_t *copied_list, int need_sync) JL_NOTSAFEPOINT { // The acquire load makes sure that the first `len` objects are valid. // If `need_sync` is true, all mutations of the content should be limited @@ -258,7 +258,7 @@ JL_DLLEXPORT void jl_gc_enable_finalizers(jl_ptls_t ptls, int on) } } -static void schedule_all_finalizers(arraylist_t *flist) +static void schedule_all_finalizers(arraylist_t *flist) JL_NOTSAFEPOINT { void **items = flist->items; size_t len = flist->len; @@ -458,7 +458,7 @@ STATIC_INLINE void gc_update_heap_size(int64_t sz_ub, int64_t sz_est) last_full_live_est = sz_est; } -static void gc_sync_cache_nolock(jl_ptls_t ptls, jl_gc_mark_cache_t *gc_cache) +static void gc_sync_cache_nolock(jl_ptls_t ptls, jl_gc_mark_cache_t *gc_cache) JL_NOTSAFEPOINT { const int nbig = gc_cache->nbig_obj; for (int i = 0; i < nbig; i++) { @@ -480,7 +480,7 @@ static void gc_sync_cache_nolock(jl_ptls_t ptls, jl_gc_mark_cache_t *gc_cache) gc_cache->scanned_bytes = 0; } -static void gc_sync_cache(jl_ptls_t ptls) +static void gc_sync_cache(jl_ptls_t ptls) JL_NOTSAFEPOINT { JL_LOCK_NOGC(&gc_cache_lock); gc_sync_cache_nolock(ptls, &ptls->gc_cache); @@ -497,7 +497,7 @@ static void gc_sync_all_caches_nolock(jl_ptls_t ptls) } STATIC_INLINE void gc_queue_big_marked(jl_ptls_t ptls, bigval_t *hdr, - int toyoung) + int toyoung) JL_NOTSAFEPOINT { const int nentry = sizeof(ptls->gc_cache.big_obj) / sizeof(void*); size_t nobj = ptls->gc_cache.nbig_obj; @@ -521,7 +521,7 @@ STATIC_INLINE void gc_queue_big_marked(jl_ptls_t ptls, bigval_t *hdr, // The return value is `1` if the object was not marked before. // Returning `0` can happen if another thread marked it in parallel. STATIC_INLINE int gc_setmark_tag(jl_taggedvalue_t *o, uint8_t mark_mode, - uintptr_t tag, uint8_t *bits) + uintptr_t tag, uint8_t *bits) JL_NOTSAFEPOINT { assert(!gc_marked(tag)); assert(gc_marked(mark_mode)); @@ -545,7 +545,7 @@ STATIC_INLINE int gc_setmark_tag(jl_taggedvalue_t *o, uint8_t mark_mode, // This function should be called exactly once during marking for each big // object being marked to update the big objects metadata. STATIC_INLINE void gc_setmark_big(jl_ptls_t ptls, jl_taggedvalue_t *o, - uint8_t mark_mode) + uint8_t mark_mode) JL_NOTSAFEPOINT { assert(!page_metadata(o)); bigval_t *hdr = bigval_header(o); @@ -572,7 +572,7 @@ STATIC_INLINE void gc_setmark_big(jl_ptls_t ptls, jl_taggedvalue_t *o, // object being marked to update the page metadata. STATIC_INLINE void gc_setmark_pool_(jl_ptls_t ptls, jl_taggedvalue_t *o, uint8_t mark_mode, - jl_gc_pagemeta_t *page) + jl_gc_pagemeta_t *page) JL_NOTSAFEPOINT { #ifdef MEMDEBUG gc_setmark_big(ptls, o, mark_mode); @@ -598,13 +598,13 @@ STATIC_INLINE void gc_setmark_pool_(jl_ptls_t ptls, jl_taggedvalue_t *o, } STATIC_INLINE void gc_setmark_pool(jl_ptls_t ptls, jl_taggedvalue_t *o, - uint8_t mark_mode) + uint8_t mark_mode) JL_NOTSAFEPOINT { gc_setmark_pool_(ptls, o, mark_mode, jl_assume(page_metadata(o))); } STATIC_INLINE void gc_setmark(jl_ptls_t ptls, jl_taggedvalue_t *o, - uint8_t mark_mode, size_t sz) + uint8_t mark_mode, size_t sz) JL_NOTSAFEPOINT { if (sz <= GC_MAX_SZCLASS) { gc_setmark_pool(ptls, o, mark_mode); @@ -614,7 +614,7 @@ STATIC_INLINE void gc_setmark(jl_ptls_t ptls, jl_taggedvalue_t *o, } } -STATIC_INLINE void gc_setmark_buf_(jl_ptls_t ptls, void *o, uint8_t mark_mode, size_t minsz) +STATIC_INLINE void gc_setmark_buf_(jl_ptls_t ptls, void *o, uint8_t mark_mode, size_t minsz) JL_NOTSAFEPOINT { jl_taggedvalue_t *buf = jl_astaggedvalue(o); uintptr_t tag = buf->header; @@ -637,12 +637,12 @@ STATIC_INLINE void gc_setmark_buf_(jl_ptls_t ptls, void *o, uint8_t mark_mode, s } } -void gc_setmark_buf(jl_ptls_t ptls, void *o, uint8_t mark_mode, size_t minsz) +void gc_setmark_buf(jl_ptls_t ptls, void *o, uint8_t mark_mode, size_t minsz) JL_NOTSAFEPOINT { gc_setmark_buf_(ptls, o, mark_mode, minsz); } -void jl_gc_force_mark_old(jl_ptls_t ptls, jl_value_t *v) +void jl_gc_force_mark_old(jl_ptls_t ptls, jl_value_t *v) JL_NOTSAFEPOINT { jl_taggedvalue_t *o = jl_astaggedvalue(v); jl_datatype_t *dt = (jl_datatype_t*)jl_typeof(v); @@ -759,7 +759,7 @@ JL_DLLEXPORT jl_value_t *jl_gc_big_alloc(jl_ptls_t ptls, size_t sz) // Sweep list rooted at *pv, removing and freeing any unmarked objects. // Return pointer to last `next` field in the culled list. -static bigval_t **sweep_big_list(int sweep_full, bigval_t **pv) +static bigval_t **sweep_big_list(int sweep_full, bigval_t **pv) JL_NOTSAFEPOINT { bigval_t *v = *pv; while (v != NULL) { @@ -819,7 +819,7 @@ static void sweep_big(jl_ptls_t ptls, int sweep_full) // tracking Arrays with malloc'd storage -void jl_gc_track_malloced_array(jl_ptls_t ptls, jl_array_t *a) +void jl_gc_track_malloced_array(jl_ptls_t ptls, jl_array_t *a) JL_NOTSAFEPOINT { // This is **NOT** a GC safe point. mallocarray_t *ma; @@ -835,20 +835,19 @@ void jl_gc_track_malloced_array(jl_ptls_t ptls, jl_array_t *a) ptls->heap.mallocarrays = ma; } -void jl_gc_count_allocd(size_t sz) +void jl_gc_count_allocd(size_t sz) JL_NOTSAFEPOINT { - // This is **NOT** a GC safe point. gc_num.allocd += sz; } -void jl_gc_reset_alloc_count(void) +void jl_gc_reset_alloc_count(void) JL_NOTSAFEPOINT { live_bytes += (gc_num.deferred_alloc + (gc_num.allocd + gc_num.interval)); gc_num.allocd = -(int64_t)gc_num.interval; gc_num.deferred_alloc = 0; } -static size_t array_nbytes(jl_array_t *a) +static size_t array_nbytes(jl_array_t *a) JL_NOTSAFEPOINT { size_t sz = 0; int isbitsunion = jl_array_isbitsunion(a); @@ -862,7 +861,7 @@ static size_t array_nbytes(jl_array_t *a) return sz; } -static void jl_gc_free_array(jl_array_t *a) +static void jl_gc_free_array(jl_array_t *a) JL_NOTSAFEPOINT { if (a->flags.how == 2) { char *d = (char*)a->data - a->offset*a->elsize; @@ -874,7 +873,7 @@ static void jl_gc_free_array(jl_array_t *a) } } -static void sweep_malloced_arrays(void) +static void sweep_malloced_arrays(void) JL_NOTSAFEPOINT { gc_time_mallocd_array_start(); for (int t_i = 0;t_i < jl_n_threads;t_i++) { @@ -1013,7 +1012,7 @@ int jl_gc_classify_pools(size_t sz, int *osize) int64_t lazy_freed_pages = 0; // Returns pointer to terminal pointer of list rooted at *pfl. -static jl_taggedvalue_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, jl_taggedvalue_t **pfl, int sweep_full, int osize) +static jl_taggedvalue_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, jl_taggedvalue_t **pfl, int sweep_full, int osize) JL_NOTSAFEPOINT { char *data = pg->data; uint8_t *ages = pg->ages; @@ -1129,7 +1128,7 @@ static jl_taggedvalue_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, jl_t } // the actual sweeping over all allocated pages in a memory pool -static inline void sweep_pool_page(jl_taggedvalue_t ***pfl, jl_gc_pagemeta_t *pg, int sweep_full) +static inline void sweep_pool_page(jl_taggedvalue_t ***pfl, jl_gc_pagemeta_t *pg, int sweep_full) JL_NOTSAFEPOINT { int p_n = pg->pool_n; int t_n = pg->thread_n; @@ -1140,7 +1139,7 @@ static inline void sweep_pool_page(jl_taggedvalue_t ***pfl, jl_gc_pagemeta_t *pg } // sweep over a pagetable0 for all allocated pages -static inline int sweep_pool_pagetable0(jl_taggedvalue_t ***pfl, pagetable0_t *pagetable0, int sweep_full) +static inline int sweep_pool_pagetable0(jl_taggedvalue_t ***pfl, pagetable0_t *pagetable0, int sweep_full) JL_NOTSAFEPOINT { unsigned ub = 0; unsigned alloc = 0; @@ -1164,7 +1163,7 @@ static inline int sweep_pool_pagetable0(jl_taggedvalue_t ***pfl, pagetable0_t *p } // sweep over pagetable1 for all pagetable0 that may contain allocated pages -static inline int sweep_pool_pagetable1(jl_taggedvalue_t ***pfl, pagetable1_t *pagetable1, int sweep_full) +static inline int sweep_pool_pagetable1(jl_taggedvalue_t ***pfl, pagetable1_t *pagetable1, int sweep_full) JL_NOTSAFEPOINT { unsigned ub = 0; unsigned alloc = 0; @@ -1189,7 +1188,7 @@ static inline int sweep_pool_pagetable1(jl_taggedvalue_t ***pfl, pagetable1_t *p } // sweep over all memory for all pagetable1 that may contain allocated pages -static void sweep_pool_pagetable(jl_taggedvalue_t ***pfl, int sweep_full) +static void sweep_pool_pagetable(jl_taggedvalue_t ***pfl, int sweep_full) JL_NOTSAFEPOINT { if (REGION2_PG_COUNT == 1) { // compile-time optimization pagetable1_t *pagetable1 = memory_map.meta1[0]; @@ -1216,13 +1215,13 @@ static void sweep_pool_pagetable(jl_taggedvalue_t ***pfl, int sweep_full) } // sweep over all memory that is being used and not in a pool -static void gc_sweep_other(jl_ptls_t ptls, int sweep_full) +static void gc_sweep_other(jl_ptls_t ptls, int sweep_full) JL_NOTSAFEPOINT { sweep_malloced_arrays(); sweep_big(ptls, sweep_full); } -static void gc_pool_sync_nfree(jl_gc_pagemeta_t *pg, jl_taggedvalue_t *last) +static void gc_pool_sync_nfree(jl_gc_pagemeta_t *pg, jl_taggedvalue_t *last) JL_NOTSAFEPOINT { assert(pg->fl_begin_offset != (uint16_t)-1); char *cur_pg = gc_page_data(last); @@ -1244,13 +1243,17 @@ static void gc_sweep_pool(int sweep_full) gc_time_pool_start(); lazy_freed_pages = 0; + // For the benfit of the analyzer, which doesn't know that jl_n_threads + // doesn't change over the course of this function + size_t n_threads = jl_n_threads; + // allocate enough space to hold the end of the free list chain // for every thread and pool size - jl_taggedvalue_t ***pfl = (jl_taggedvalue_t ***) alloca(jl_n_threads * JL_GC_N_POOLS * sizeof(jl_taggedvalue_t**)); + jl_taggedvalue_t ***pfl = (jl_taggedvalue_t ***) alloca(n_threads * JL_GC_N_POOLS * sizeof(jl_taggedvalue_t**)); // update metadata of pages that were pointed to by freelist or newpages from a pool // i.e. pages being the current allocation target - for (int t_i = 0; t_i < jl_n_threads; t_i++) { + for (int t_i = 0; t_i < n_threads; t_i++) { jl_ptls_t ptls2 = jl_all_tls_states[t_i]; for (int i = 0; i < JL_GC_N_POOLS; i++) { jl_gc_pool_t *p = &ptls2->heap.norm_pools[i]; @@ -1279,7 +1282,7 @@ static void gc_sweep_pool(int sweep_full) sweep_pool_pagetable(pfl, sweep_full); // null out terminal pointers of free lists - for (int t_i = 0; t_i < jl_n_threads; t_i++) { + for (int t_i = 0; t_i < n_threads; t_i++) { for (int i = 0; i < JL_GC_N_POOLS; i++) { *pfl[t_i * JL_GC_N_POOLS + i] = NULL; } @@ -1399,7 +1402,7 @@ static void NOINLINE gc_mark_stack_resize(jl_gc_mark_cache_t *gc_cache, gc_mark_ // in `gc_cache` or `sp` // The `sp` will be updated on return if `inc` is true. STATIC_INLINE void gc_mark_stack_push(jl_gc_mark_cache_t *gc_cache, gc_mark_sp_t *sp, - void *pc, void *data, size_t data_size, int inc) + void *pc, void *data, size_t data_size, int inc) JL_NOTSAFEPOINT { assert(data_size <= sizeof(jl_gc_mark_data_t)); if (__unlikely(sp->pc == sp->pc_end)) @@ -1417,7 +1420,7 @@ STATIC_INLINE void gc_mark_stack_push(jl_gc_mark_cache_t *gc_cache, gc_mark_sp_t // Return the tag (with GC bits cleared) and the GC bits in `*ptag` and `*pbits`. // Return whether the object needs to be scanned / have metadata updated. STATIC_INLINE int gc_try_setmark(jl_value_t *obj, uintptr_t *nptr, - uintptr_t *ptag, uint8_t *pbits) + uintptr_t *ptag, uint8_t *pbits) JL_NOTSAFEPOINT { if (!obj) return 0; @@ -1469,7 +1472,7 @@ STATIC_INLINE void gc_mark_queue_scan_obj(jl_gc_mark_cache_t *gc_cache, gc_mark_ // The object will be marked atomically which can also happen concurrently. // It will be queued if the object wasn't marked already (or concurrently by another thread) // Returns whether the object is young. -STATIC_INLINE int gc_mark_queue_obj(jl_gc_mark_cache_t *gc_cache, gc_mark_sp_t *sp, void *_obj) +STATIC_INLINE int gc_mark_queue_obj(jl_gc_mark_cache_t *gc_cache, gc_mark_sp_t *sp, void *_obj) JL_NOTSAFEPOINT { jl_value_t *obj = (jl_value_t*)jl_assume(_obj); uintptr_t nptr = 0; @@ -1485,7 +1488,7 @@ STATIC_INLINE int gc_mark_queue_obj(jl_gc_mark_cache_t *gc_cache, gc_mark_sp_t * // Check if `nptr` is tagged for `old + refyoung`, // Push the object to the remset and update the `nptr` counter if necessary. -STATIC_INLINE void gc_mark_push_remset(jl_ptls_t ptls, jl_value_t *obj, uintptr_t nptr) +STATIC_INLINE void gc_mark_push_remset(jl_ptls_t ptls, jl_value_t *obj, uintptr_t nptr) JL_NOTSAFEPOINT { if (__unlikely((nptr & 0x3) == 0x3)) { ptls->heap.remset_nptr += nptr >> 2; @@ -1571,7 +1574,7 @@ STATIC_INLINE int gc_mark_scan_obj8(jl_ptls_t ptls, gc_mark_sp_t *sp, gc_mark_ob // Scan an object with 16bits field descriptors. see `gc_mark_obj16_t` STATIC_INLINE int gc_mark_scan_obj16(jl_ptls_t ptls, gc_mark_sp_t *sp, gc_mark_obj16_t *obj16, char *parent, jl_fielddesc16_t *begin, jl_fielddesc16_t *end, - jl_value_t **pnew_obj, uintptr_t *ptag, uint8_t *pbits) + jl_value_t **pnew_obj, uintptr_t *ptag, uint8_t *pbits) JL_NOTSAFEPOINT { (void)jl_assume(obj16 == (gc_mark_obj16_t*)sp->data); (void)jl_assume(begin < end); @@ -2933,6 +2936,7 @@ static void *gc_perm_alloc_large(size_t sz, int zero, unsigned align, unsigned o if (align > 1 && (offset != 0 || align > malloc_align)) sz += align - 1; uintptr_t base = (uintptr_t)(zero ? calloc(1, sz) : malloc(sz)); + jl_may_leak(base); unsigned diff = (offset - base) % align; return (void*)(base + diff); } diff --git a/src/gc.h b/src/gc.h index 4cf2cd0f7fa40..c6a284d7d32ab 100644 --- a/src/gc.h +++ b/src/gc.h @@ -348,6 +348,9 @@ typedef struct { int ub; } pagetable_t; +#ifdef __clang_analyzer__ +unsigned ffs_u32(uint32_t bitvec) JL_NOTSAFEPOINT; +#else STATIC_INLINE unsigned ffs_u32(uint32_t bitvec) { #if defined(_COMPILER_MINGW_) @@ -360,6 +363,7 @@ STATIC_INLINE unsigned ffs_u32(uint32_t bitvec) return ffs(bitvec) - 1; #endif } +#endif extern jl_gc_num_t gc_num; extern pagetable_t memory_map; @@ -368,7 +372,7 @@ extern arraylist_t finalizer_list_marked; extern arraylist_t to_finalize; extern int64_t lazy_freed_pages; -STATIC_INLINE bigval_t *bigval_header(jl_taggedvalue_t *o) +STATIC_INLINE bigval_t *bigval_header(jl_taggedvalue_t *o) JL_NOTSAFEPOINT { return container_of(o, bigval_t, header); } @@ -389,34 +393,34 @@ STATIC_INLINE jl_taggedvalue_t *page_pfl_end(jl_gc_pagemeta_t *p) return (jl_taggedvalue_t*)(p->data + p->fl_end_offset); } -STATIC_INLINE int gc_marked(uintptr_t bits) +STATIC_INLINE int gc_marked(uintptr_t bits) JL_NOTSAFEPOINT { return (bits & GC_MARKED) != 0; } -STATIC_INLINE int gc_old(uintptr_t bits) +STATIC_INLINE int gc_old(uintptr_t bits) JL_NOTSAFEPOINT { return (bits & GC_OLD) != 0; } -STATIC_INLINE uintptr_t gc_set_bits(uintptr_t tag, int bits) +STATIC_INLINE uintptr_t gc_set_bits(uintptr_t tag, int bits) JL_NOTSAFEPOINT { return (tag & ~(uintptr_t)3) | bits; } -STATIC_INLINE uintptr_t gc_ptr_tag(void *v, uintptr_t mask) +STATIC_INLINE uintptr_t gc_ptr_tag(void *v, uintptr_t mask) JL_NOTSAFEPOINT { return ((uintptr_t)v) & mask; } -STATIC_INLINE void *gc_ptr_clear_tag(void *v, uintptr_t mask) +STATIC_INLINE void *gc_ptr_clear_tag(void *v, uintptr_t mask) JL_NOTSAFEPOINT { return (void*)(((uintptr_t)v) & ~mask); } NOINLINE uintptr_t gc_get_stack_ptr(void); -STATIC_INLINE jl_gc_pagemeta_t *page_metadata(void *_data) +STATIC_INLINE jl_gc_pagemeta_t *page_metadata(void *_data) JL_NOTSAFEPOINT { uintptr_t data = ((uintptr_t)_data); unsigned i; @@ -441,7 +445,7 @@ struct jl_gc_metadata_ext { unsigned pagetable0_i32, pagetable0_i; }; -STATIC_INLINE struct jl_gc_metadata_ext page_metadata_ext(void *_data) +STATIC_INLINE struct jl_gc_metadata_ext page_metadata_ext(void *_data) JL_NOTSAFEPOINT { uintptr_t data = (uintptr_t)_data; struct jl_gc_metadata_ext info; @@ -462,7 +466,7 @@ STATIC_INLINE struct jl_gc_metadata_ext page_metadata_ext(void *_data) return info; } -STATIC_INLINE void gc_big_object_unlink(const bigval_t *hdr) +STATIC_INLINE void gc_big_object_unlink(const bigval_t *hdr) JL_NOTSAFEPOINT { *hdr->prev = hdr->next; if (hdr->next) { @@ -470,7 +474,7 @@ STATIC_INLINE void gc_big_object_unlink(const bigval_t *hdr) } } -STATIC_INLINE void gc_big_object_link(bigval_t *hdr, bigval_t **list) +STATIC_INLINE void gc_big_object_link(bigval_t *hdr, bigval_t **list) JL_NOTSAFEPOINT { hdr->next = *list; hdr->prev = list; @@ -623,7 +627,7 @@ JL_DLLEXPORT extern jl_gc_debug_env_t jl_gc_debug_env; int gc_debug_check_other(void); int gc_debug_check_pool(void); void gc_debug_print(void); -void gc_scrub_record_task(jl_task_t *ta); +void gc_scrub_record_task(jl_task_t *ta) JL_NOTSAFEPOINT; void gc_scrub(void); #else #define gc_sweep_always_full 0 @@ -638,7 +642,7 @@ static inline int gc_debug_check_pool(void) static inline void gc_debug_print(void) { } -static inline void gc_scrub_record_task(jl_task_t *ta) +static inline void gc_scrub_record_task(jl_task_t *ta) JL_NOTSAFEPOINT { (void)ta; } @@ -648,11 +652,11 @@ static inline void gc_scrub(void) #endif #ifdef OBJPROFILE -void objprofile_count(void *ty, int old, int sz); +void objprofile_count(void *ty, int old, int sz) JL_NOTSAFEPOINT; void objprofile_printall(void); void objprofile_reset(void); #else -static inline void objprofile_count(void *ty, int old, int sz) +static inline void objprofile_count(void *ty, int old, int sz) JL_NOTSAFEPOINT { } diff --git a/src/support/arraylist.h b/src/support/arraylist.h index 3c4ed8a2ef21c..6616cdbc40446 100644 --- a/src/support/arraylist.h +++ b/src/support/arraylist.h @@ -9,6 +9,8 @@ extern "C" { #endif +#include "analyzer_annotations.h" + typedef struct { size_t len; size_t max; @@ -19,7 +21,7 @@ typedef struct { arraylist_t *arraylist_new(arraylist_t *a, size_t size); void arraylist_free(arraylist_t *a); -void arraylist_push(arraylist_t *a, void *elt); +void arraylist_push(arraylist_t *a, void *elt) JL_NOTSAFEPOINT; void *arraylist_pop(arraylist_t *a); void arraylist_grow(arraylist_t *a, size_t n); From dce8cc250410b154a30f9dc13fb71cd7d2ebff1e Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 14:48:57 -0400 Subject: [PATCH 064/110] Partial GC annotations for gf.c This file is hard. Let's come back to it later. --- src/gf.c | 12 ++++++------ src/julia.h | 4 ++-- src/julia_internal.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gf.c b/src/gf.c index c179563422013..a7b442732c486 100644 --- a/src/gf.c +++ b/src/gf.c @@ -204,7 +204,7 @@ JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_methtable_t *mt, jl_value_t *typ JL_DLLEXPORT jl_method_t *jl_new_method_uninit(jl_module_t*); -void jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_args_t fptr) +void jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_args_t fptr) JL_GC_DISABLED { jl_sym_t *sname = jl_symbol(name); if (dt == NULL) { @@ -289,7 +289,7 @@ jl_code_info_t *jl_type_infer(jl_method_instance_t **pli, size_t world, int forc return src; } -int jl_is_rettype_inferred(jl_method_instance_t *li) +int jl_is_rettype_inferred(jl_method_instance_t *li) JL_NOTSAFEPOINT { if (!li->inferred) return 0; @@ -587,7 +587,7 @@ static void jl_compilation_sig( jl_method_t *definition, intptr_t nspec, // output: - jl_svec_t **const newparams) + jl_svec_t **const newparams JL_REQUIRE_ROOTED_SLOT) { if (definition->generator) { // staged functions aren't optimized @@ -921,7 +921,7 @@ JL_DLLEXPORT int jl_isa_compileable_sig( } static jl_method_instance_t *cache_method( - jl_methtable_t *mt, union jl_typemap_t *cache, jl_value_t *parent, + jl_methtable_t *mt, union jl_typemap_t *cache, jl_value_t *parent JL_PROPAGATES_ROOT, jl_tupletype_t *tt, // the original tupletype of the signature jl_method_t *definition, size_t world, @@ -2061,7 +2061,7 @@ STATIC_INLINE int sig_match_fast(jl_value_t **args, jl_value_t **sig, size_t i, return 1; } -jl_typemap_entry_t *call_cache[N_CALL_CACHE]; +jl_typemap_entry_t *call_cache[N_CALL_CACHE] JL_GLOBALLY_ROOTED; static uint8_t pick_which[N_CALL_CACHE]; #ifdef JL_GF_PROFILE size_t ncalls; @@ -2183,7 +2183,7 @@ JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t **args, uint32_t nargs) return verify_type(res); } -JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_value_t *types, size_t world) +JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROOT, size_t world) { jl_methtable_t *mt = jl_first_argument_datatype(types)->name->mt; jl_svec_t *env = jl_emptysvec; diff --git a/src/julia.h b/src/julia.h index c7f73e2426df5..c8370e7fa59ce 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1086,7 +1086,7 @@ JL_DLLEXPORT jl_value_t *jl_type_unionall(jl_tvar_t *v, jl_value_t *body); JL_DLLEXPORT const char *jl_typename_str(jl_value_t *v) JL_NOTSAFEPOINT; JL_DLLEXPORT const char *jl_typeof_str(jl_value_t *v) JL_NOTSAFEPOINT; JL_DLLEXPORT int jl_type_morespecific(jl_value_t *a, jl_value_t *b); -jl_value_t *jl_unwrap_unionall(jl_value_t *v) JL_NOTSAFEPOINT; +jl_value_t *jl_unwrap_unionall(jl_value_t *v JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; jl_value_t *jl_rewrap_unionall(jl_value_t *t, jl_value_t *u); STATIC_INLINE int jl_is_dispatch_tupletype(jl_value_t *v) JL_NOTSAFEPOINT @@ -1833,7 +1833,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp); // argc/argv JL_DLLEXPORT void jl_set_ARGS(int argc, char **argv); -JL_DLLEXPORT int jl_generating_output(void); +JL_DLLEXPORT int jl_generating_output(void) JL_NOTSAFEPOINT; // Settings for code_coverage and malloc_log // NOTE: if these numbers change, test/cmdlineargs.jl will have to be updated diff --git a/src/julia_internal.h b/src/julia_internal.h index e8c3df13aa598..aabdc112d247e 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -137,7 +137,7 @@ STATIC_INLINE uint32_t jl_int32hash_fast(uint32_t a) #define GC_OLD_MARKED (GC_OLD | GC_MARKED) // reachable and old // useful constants -extern jl_methtable_t *jl_type_type_mt; +extern jl_methtable_t *jl_type_type_mt JL_GLOBALLY_ROOTED; JL_DLLEXPORT extern size_t jl_world_counter; typedef void (*tracer_cb)(jl_value_t *tracee); From b108d51b8a3c1361c59229c4dab699114aba0802 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 14:51:07 -0400 Subject: [PATCH 065/110] static analysis annotations for init.c --- src/init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/init.c b/src/init.c index b293ab1a44b88..98e8bfe7cf4e5 100644 --- a/src/init.c +++ b/src/init.c @@ -278,6 +278,7 @@ JL_DLLEXPORT void jl_atexit_hook(int exitcode) } JL_CATCH { //error handling -- continue cleanup, as much as possible + assert(item); uv_unref(item->h); jl_printf(JL_STDERR, "error during exit cleanup: close: "); jl_static_show(JL_STDERR, ptls->exception_in_transit); From 3708c647c54097bcaf4b202be53fdc652178ad8b Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 15:21:00 -0400 Subject: [PATCH 066/110] Add GC static analysis annotations in interpreter.c --- src/interpreter.c | 19 +++++++++++-------- src/julia.h | 3 ++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/interpreter.c b/src/interpreter.c index 70beff9ba0b18..deb0d8986b770 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -124,7 +124,7 @@ SECT_INTERP void jl_set_datatype_super(jl_datatype_t *tt, jl_value_t *super) static void eval_abstracttype(jl_expr_t *ex, interpreter_state *s) { - jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); + jl_value_t **args = jl_array_ptr_data(ex->args); if (inside_typedef) jl_error("cannot eval a new abstract type definition while defining another type"); jl_value_t *name = args[0]; @@ -168,7 +168,7 @@ static void eval_abstracttype(jl_expr_t *ex, interpreter_state *s) static void eval_primitivetype(jl_expr_t *ex, interpreter_state *s) { - jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); + jl_value_t **args = (jl_value_t**)jl_array_ptr_data(ex->args); if (inside_typedef) jl_error("cannot eval a new primitive type definition while defining another type"); jl_value_t *name = args[0]; @@ -219,7 +219,7 @@ static void eval_primitivetype(jl_expr_t *ex, interpreter_state *s) static void eval_structtype(jl_expr_t *ex, interpreter_state *s) { - jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); + jl_value_t **args = jl_array_ptr_data(ex->args); if (inside_typedef) jl_error("cannot eval a new struct type definition while defining another type"); jl_value_t *name = args[0]; @@ -285,7 +285,7 @@ static void eval_structtype(jl_expr_t *ex, interpreter_state *s) static jl_value_t *eval_methoddef(jl_expr_t *ex, interpreter_state *s) { - jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); + jl_value_t **args = jl_array_ptr_data(ex->args); jl_sym_t *fname = (jl_sym_t*)args[0]; jl_module_t *modu = s->module; if (jl_is_globalref(fname)) { @@ -348,12 +348,12 @@ SECT_INTERP jl_value_t *jl_eval_global_var(jl_module_t *m, jl_sym_t *e) return v; } -SECT_INTERP static int jl_source_nslots(jl_code_info_t *src) +SECT_INTERP static int jl_source_nslots(jl_code_info_t *src) JL_NOTSAFEPOINT { return jl_array_len(src->slotflags); } -SECT_INTERP static int jl_source_nssavalues(jl_code_info_t *src) +SECT_INTERP static int jl_source_nssavalues(jl_code_info_t *src) JL_NOTSAFEPOINT { return jl_is_long(src->ssavaluetypes) ? jl_unbox_long(src->ssavaluetypes) : jl_array_len(src->ssavaluetypes); } @@ -417,13 +417,13 @@ SECT_INTERP static jl_value_t *eval_value(jl_value_t *e, interpreter_state *s) // edges list doesn't contain last branch. this value should be unused. return NULL; } - jl_value_t *val = jl_arrayref((jl_array_t*)jl_fieldref_noalloc(e, 1), edge); + jl_value_t *val = jl_array_ptr_ref((jl_array_t*)jl_fieldref_noalloc(e, 1), edge); return eval_value(val, s); } if (!jl_is_expr(e)) return e; jl_expr_t *ex = (jl_expr_t*)e; - jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); + jl_value_t **args = jl_array_ptr_data(ex->args); size_t nargs = jl_array_len(ex->args); jl_sym_t *head = ex->head; if (head == call_sym) { @@ -746,6 +746,7 @@ SECT_INTERP CALLBACK_ABI void *jl_interpret_call_callback(interpreter_state *s, { struct jl_interpret_call_args *args = (struct jl_interpret_call_args *)vargs; + JL_GC_PROMISE_ROOTED(args); jl_code_info_t *src = jl_code_for_interpreter(args->lam); args->lam->inferred = (jl_value_t*)src; jl_gc_wb(args->lam, src); @@ -787,6 +788,7 @@ struct jl_interpret_toplevel_thunk_args { SECT_INTERP CALLBACK_ABI void *jl_interpret_toplevel_thunk_callback(interpreter_state *s, void *vargs) { struct jl_interpret_toplevel_thunk_args *args = (struct jl_interpret_toplevel_thunk_args*)vargs; + JL_GC_PROMISE_ROOTED(args); jl_array_t *stmts = args->src->code; assert(jl_typeis(stmts, jl_array_any_type)); jl_value_t **locals; @@ -824,6 +826,7 @@ SECT_INTERP CALLBACK_ABI void *jl_interpret_toplevel_expr_in_callback(interprete { struct interpret_toplevel_expr_in_args *args = (struct interpret_toplevel_expr_in_args*)vargs; + JL_GC_PROMISE_ROOTED(args); jl_ptls_t ptls = jl_get_ptls_states(); jl_value_t *v=NULL; jl_module_t *last_m = ptls->current_module; diff --git a/src/julia.h b/src/julia.h index c8370e7fa59ce..9d8c697e16245 100644 --- a/src/julia.h +++ b/src/julia.h @@ -781,11 +781,13 @@ JL_DLLEXPORT size_t jl_array_len_(jl_array_t *a); JL_DLLEXPORT char *jl_array_typetagdata(jl_array_t *a); #ifdef __clang_analyzer__ +jl_value_t **jl_array_ptr_data(jl_array_t *a JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; STATIC_INLINE jl_value_t *jl_array_ptr_ref(void *a JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; STATIC_INLINE jl_value_t *jl_array_ptr_set( void *a JL_ROOTING_ARGUMENT, size_t i, void *x JL_ROOTED_ARGUMENT) JL_NOTSAFEPOINT; #else +#define jl_array_ptr_data(a) ((jl_value_t**)((jl_array_t*)(a))->data) STATIC_INLINE jl_value_t *jl_array_ptr_ref(void *a JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT { assert(i < jl_array_len(a)); @@ -846,7 +848,6 @@ STATIC_INLINE void jl_array_uint8_set(void *a, size_t i, uint8_t x) JL_NOTSAFEPO // get a pointer to the data in a datatype #define jl_data_ptr(v) ((jl_value_t**)v) -#define jl_array_ptr_data(a) ((jl_value_t**)((jl_array_t*)a)->data) #define jl_string_data(s) ((char*)s + sizeof(void*)) #define jl_string_len(s) (*(size_t*)s) From ee88b92f7681084b8ccde897fc40d280baf06812 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 15:28:35 -0400 Subject: [PATCH 067/110] Add static analysis annotations for jloptions.c --- src/julia.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/julia.h b/src/julia.h index 9d8c697e16245..7ec57376ba3bd 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1297,7 +1297,7 @@ JL_DLLEXPORT jl_value_t *jl_array_to_string(jl_array_t *a); JL_DLLEXPORT jl_array_t *jl_alloc_vec_any(size_t n); JL_DLLEXPORT jl_value_t *jl_arrayref(jl_array_t *a, size_t i); // 0-indexed JL_DLLEXPORT jl_value_t *jl_ptrarrayref(jl_array_t *a JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; // 0-indexed -JL_DLLEXPORT void jl_arrayset(jl_array_t *a, jl_value_t *v, size_t i); // 0-indexed +JL_DLLEXPORT void jl_arrayset(jl_array_t *a JL_ROOTING_ARGUMENT, jl_value_t *v JL_ROOTED_ARGUMENT, size_t i) JL_NOTSAFEPOINT; // 0-indexed JL_DLLEXPORT void jl_arrayunset(jl_array_t *a, size_t i); // 0-indexed JL_DLLEXPORT int jl_array_isassigned(jl_array_t *a, size_t i); // 0-indexed JL_DLLEXPORT void jl_array_grow_end(jl_array_t *a, size_t inc); From a759c11eb13dc5da267ad02a569d1558de0b9ec2 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 16:37:27 -0400 Subject: [PATCH 068/110] Add gc annotations to jltypes.c --- src/jltypes.c | 28 +++++++++++++++------------- src/julia_internal.h | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/jltypes.c b/src/jltypes.c index 9a1f6a42b6449..a9f8fff425b02 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -314,7 +314,7 @@ int jl_count_union_components(jl_value_t *v) // Return the `*pi`th element of a nested type union, according to a // standard traversal order. Anything that is not itself a `Union` is // considered an "element". `*pi` is destroyed in the process. -static jl_value_t *nth_union_component(jl_value_t *v, int *pi) +static jl_value_t *nth_union_component(jl_value_t *v, int *pi) JL_NOTSAFEPOINT { if (!jl_is_uniontype(v)) { if (*pi == 0) @@ -328,13 +328,13 @@ static jl_value_t *nth_union_component(jl_value_t *v, int *pi) return nth_union_component(u->b, pi); } -jl_value_t *jl_nth_union_component(jl_value_t *v, int i) +jl_value_t *jl_nth_union_component(jl_value_t *v, int i) JL_NOTSAFEPOINT { return nth_union_component(v, &i); } // inverse of jl_nth_union_component -int jl_find_union_component(jl_value_t *haystack, jl_value_t *needle, unsigned *nth) +int jl_find_union_component(jl_value_t *haystack, jl_value_t *needle, unsigned *nth) JL_NOTSAFEPOINT { if (jl_is_uniontype(haystack)) { if (jl_find_union_component(((jl_uniontype_t*)haystack)->a, needle, nth)) @@ -349,7 +349,7 @@ int jl_find_union_component(jl_value_t *haystack, jl_value_t *needle, unsigned * return 0; } -static void flatten_type_union(jl_value_t **types, size_t n, jl_value_t **out, size_t *idx) +static void flatten_type_union(jl_value_t **types, size_t n, jl_value_t **out, size_t *idx) JL_NOTSAFEPOINT { size_t i; for(i=0; i < n; i++) { @@ -366,25 +366,25 @@ static void flatten_type_union(jl_value_t **types, size_t n, jl_value_t **out, s } } -STATIC_INLINE const char *datatype_module_name(jl_value_t *t) +STATIC_INLINE const char *datatype_module_name(jl_value_t *t) JL_NOTSAFEPOINT { if (((jl_datatype_t*)t)->name->module == NULL) return NULL; return jl_symbol_name(((jl_datatype_t*)t)->name->module->name); } -STATIC_INLINE const char *str_(const char *s) +STATIC_INLINE const char *str_(const char *s) JL_NOTSAFEPOINT { return s == NULL ? "" : s; } -STATIC_INLINE int cmp_(int a, int b) +STATIC_INLINE int cmp_(int a, int b) JL_NOTSAFEPOINT { return a < b ? -1 : a > b; } // a/b are jl_datatype_t* & not NULL -int datatype_name_cmp(jl_value_t *a, jl_value_t *b) +int datatype_name_cmp(jl_value_t *a, jl_value_t *b) JL_NOTSAFEPOINT { if (!jl_is_datatype(a)) return jl_is_datatype(b) ? 1 : 0; @@ -426,7 +426,7 @@ int datatype_name_cmp(jl_value_t *a, jl_value_t *b) // sort singletons first, then DataTypes, then UnionAlls, // ties broken alphabetically including module name & type parameters -int union_sort_cmp(const void *ap, const void *bp) +int union_sort_cmp(const void *ap, const void *bp) JL_NOTSAFEPOINT { jl_value_t *a = *(jl_value_t**)ap; jl_value_t *b = *(jl_value_t**)bp; @@ -558,7 +558,7 @@ static int contains_unions(jl_value_t *type) return 0; } -static intptr_t wrapper_id(jl_value_t *t) +static intptr_t wrapper_id(jl_value_t *t) JL_NOTSAFEPOINT { // DataType wrappers occur often, e.g. when called as constructors. // make sure any type equal to a wrapper gets a consistent, ordered ID. @@ -587,7 +587,7 @@ static int is_typekey_ordered(jl_value_t **key, size_t n) } // ordered comparison of types -static int typekey_compare(jl_datatype_t *tt, jl_value_t **key, size_t n) +static int typekey_compare(jl_datatype_t *tt, jl_value_t **key, size_t n) JL_NOTSAFEPOINT { size_t j; if (tt == NULL) return -1; // place NULLs at end to allow padding for fast growing @@ -634,7 +634,7 @@ static int typekey_compare(jl_datatype_t *tt, jl_value_t **key, size_t n) return 0; } -static int dt_compare(const void *ap, const void *bp) +static int dt_compare(const void *ap, const void *bp) JL_NOTSAFEPOINT { jl_datatype_t *a = *(jl_datatype_t**)ap; jl_datatype_t *b = *(jl_datatype_t**)bp; @@ -971,6 +971,7 @@ static jl_value_t *lookup_type_stack(jl_typestack_t *stack, jl_datatype_t *tt, s // stack, return it. this computes a fixed point for recursive types. jl_typename_t *tn = tt->name; while (stack != NULL) { + JL_GC_PROMISE_ROOTED(stack->tt); if (stack->tt->name == tn && ntp == jl_svec_len(stack->tt->parameters) && typekey_eq(stack->tt, iparams, ntp)) { @@ -1322,6 +1323,7 @@ static jl_tupletype_t *jl_apply_tuple_type_v_(jl_value_t **p, size_t np, jl_svec { int cacheable = 1; for (size_t i = 0; i < np; i++) { + assert(p[i]); if (!jl_is_concrete_type(p[i])) cacheable = 0; } @@ -1638,7 +1640,7 @@ static jl_tvar_t *tvar(const char *name) extern void jl_init_int32_int64_cache(void); -void jl_init_types(void) +void jl_init_types(void) JL_GC_DISABLED { jl_module_t *core = NULL; // will need to be assigned later diff --git a/src/julia_internal.h b/src/julia_internal.h index aabdc112d247e..7626f76f293a1 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -479,7 +479,7 @@ extern char jl_using_perf_jitevents; #endif extern size_t jl_arr_xtralloc_limit; -void jl_init_types(void); +void jl_init_types(void) JL_GC_DISABLED; void jl_init_box_caches(void); void jl_init_frontend(void); void jl_init_primitives(void) JL_GC_DISABLED; From 9ca53d0e71608b7e2e5ecb063fe97cb47a3eea36 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 16:42:02 -0400 Subject: [PATCH 069/110] Add static analysis annotations for src/method.c --- src/method.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/method.c b/src/method.c index 981f917831fa3..4acae10b713f1 100644 --- a/src/method.c +++ b/src/method.c @@ -220,7 +220,7 @@ static void jl_code_info_set_ast(jl_code_info_t *li, jl_expr_t *ast) li->code = body; jl_gc_wb(li, li->code); size_t n = jl_array_len(body); - jl_value_t **bd = (jl_value_t**)jl_array_data((jl_array_t*)li->code); + jl_value_t **bd = (jl_value_t**)jl_array_ptr_data((jl_array_t*)li->code); for (j = 0; j < n; j++) { jl_value_t *st = bd[j]; if (jl_is_expr(st) && ((jl_expr_t*)st)->head == meta_sym) { @@ -599,7 +599,7 @@ JL_DLLEXPORT jl_method_t *jl_new_method_uninit(jl_module_t *module) return m; } -jl_array_t *jl_all_methods; +jl_array_t *jl_all_methods JL_GLOBALLY_ROOTED; static jl_method_t *jl_new_method( jl_code_info_t *definition, jl_sym_t *name, @@ -695,7 +695,7 @@ JL_DLLEXPORT jl_value_t *jl_generic_function_def(jl_sym_t *name, return gf; } -static jl_datatype_t *first_arg_datatype(jl_value_t *a, int got_tuple1) +static jl_datatype_t *first_arg_datatype(jl_value_t *a JL_PROPAGATES_ROOT, int got_tuple1) JL_NOTSAFEPOINT { if (jl_is_datatype(a)) { if (got_tuple1) @@ -726,13 +726,13 @@ static jl_datatype_t *first_arg_datatype(jl_value_t *a, int got_tuple1) } // get DataType of first tuple element, or NULL if cannot be determined -JL_DLLEXPORT jl_datatype_t *jl_first_argument_datatype(jl_value_t *argtypes) +JL_DLLEXPORT jl_datatype_t *jl_first_argument_datatype(jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT { return first_arg_datatype(argtypes, 0); } // get DataType implied by a single given type, or `nothing` -JL_DLLEXPORT jl_value_t *jl_argument_datatype(jl_value_t *argt) +JL_DLLEXPORT jl_value_t *jl_argument_datatype(jl_value_t *argt JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT { jl_datatype_t *dt = first_arg_datatype(argt, 1); if (dt == NULL) From 20792fe7f0b6c382f5858d3a129d9a966000e1fb Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 17:03:44 -0400 Subject: [PATCH 070/110] Add static analysis annotations for module.c --- src/julia.h | 4 ++-- src/module.c | 31 ++++++++++++++++++++++++------- src/support/htable.h | 16 +++++++++------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/julia.h b/src/julia.h index 7ec57376ba3bd..a6b58ced8633e 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1340,10 +1340,10 @@ JL_DLLEXPORT int jl_is_const(jl_module_t *m, jl_sym_t *var); JL_DLLEXPORT jl_value_t *jl_get_global(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var); JL_DLLEXPORT void jl_set_global(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, - jl_value_t *val JL_ROOTED_ARGUMENT JL_MAYBE_UNROOTED); + jl_value_t *val JL_ROOTED_ARGUMENT); JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, - jl_value_t *val JL_ROOTED_ARGUMENT JL_MAYBE_UNROOTED); + jl_value_t *val JL_ROOTED_ARGUMENT); JL_DLLEXPORT void jl_checked_assignment(jl_binding_t *b, jl_value_t *rhs); JL_DLLEXPORT void jl_declare_constant(jl_binding_t *b); JL_DLLEXPORT void jl_module_using(jl_module_t *to, jl_module_t *from); diff --git a/src/module.c b/src/module.c index b676360f928f9..efbd7da58cf39 100644 --- a/src/module.c +++ b/src/module.c @@ -125,6 +125,23 @@ JL_DLLEXPORT jl_binding_t *jl_get_binding_wr(jl_module_t *m, jl_sym_t *var, int return *bp; } +// Hash tables don't generically root their contents, but they do for bindings. +// Express this to the analyzer. +#ifdef __clang_analyzer__ +jl_binding_t *jl_get_module_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT; +jl_binding_t **jl_get_module_binding_bp(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT; +#else +static inline jl_binding_t *jl_get_module_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT +{ + return (jl_binding_t*)ptrhash_get(&m->bindings, var); +} +static inline jl_binding_t **jl_get_module_binding_bp(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT +{ + return (jl_binding_t**)ptrhash_bp(&m->bindings, var); +} +#endif + + // return module of binding JL_DLLEXPORT jl_module_t *jl_get_module_of_binding(jl_module_t *m, jl_sym_t *var) { @@ -138,7 +155,7 @@ JL_DLLEXPORT jl_module_t *jl_get_module_of_binding(jl_module_t *m, jl_sym_t *var // like jl_get_binding_wr, but has different error paths JL_DLLEXPORT jl_binding_t *jl_get_binding_for_method_def(jl_module_t *m, jl_sym_t *var) { - jl_binding_t **bp = (jl_binding_t**)ptrhash_bp(&m->bindings, var); + jl_binding_t **bp = jl_get_module_binding_bp(m, var); jl_binding_t *b = *bp; if (b != HT_NOTFOUND) { @@ -177,16 +194,16 @@ typedef struct _modstack_t { struct _modstack_t *prev; } modstack_t; -static jl_binding_t *jl_get_binding_(jl_module_t *m, jl_sym_t *var, modstack_t *st); +static jl_binding_t *jl_get_binding_(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var, modstack_t *st); // find a binding from a module's `usings` list -static jl_binding_t *using_resolve_binding(jl_module_t *m, jl_sym_t *var, modstack_t *st, int warn) +static jl_binding_t *using_resolve_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var, modstack_t *st, int warn) { jl_binding_t *b = NULL; jl_module_t *owner = NULL; for(int i=(int)m->usings.len-1; i >= 0; --i) { jl_module_t *imp = (jl_module_t*)m->usings.items[i]; - jl_binding_t *tempb = (jl_binding_t*)ptrhash_get(&imp->bindings, var); + jl_binding_t *tempb = jl_get_module_binding(imp, var); if (tempb != HT_NOTFOUND && tempb->exportp) { tempb = jl_get_binding_(imp, var, st); if (tempb == NULL || tempb->owner == NULL) @@ -227,7 +244,7 @@ static jl_binding_t *jl_get_binding_(jl_module_t *m, jl_sym_t *var, modstack_t * } tmp = tmp->prev; } - jl_binding_t *b = (jl_binding_t*)ptrhash_get(&m->bindings, var); + jl_binding_t *b = jl_get_module_binding(m, var); if (b == HT_NOTFOUND || b->owner == NULL) { b = using_resolve_binding(m, var, &top, 1); if (b != NULL) { @@ -473,7 +490,7 @@ JL_DLLEXPORT jl_value_t *jl_get_global(jl_module_t *m, jl_sym_t *var) return b->value; } -JL_DLLEXPORT void jl_set_global(jl_module_t *m, jl_sym_t *var, jl_value_t *val) +JL_DLLEXPORT void jl_set_global(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT) { jl_binding_t *bp = jl_get_binding_wr(m, var, 1); if (!bp->constp) { @@ -482,7 +499,7 @@ JL_DLLEXPORT void jl_set_global(jl_module_t *m, jl_sym_t *var, jl_value_t *val) } } -JL_DLLEXPORT void jl_set_const(jl_module_t *m, jl_sym_t *var, jl_value_t *val) +JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT) { jl_binding_t *bp = jl_get_binding_wr(m, var, 1); if (!bp->constp) { diff --git a/src/support/htable.h b/src/support/htable.h index 2b79eef12dc86..317a9dae95e1d 100644 --- a/src/support/htable.h +++ b/src/support/htable.h @@ -5,6 +5,8 @@ #define HT_N_INLINE 32 +#include "analyzer_annotations.h" + #ifdef __cplusplus extern "C" { #endif @@ -25,13 +27,13 @@ void htable_free(htable_t *h); // clear and (possibly) change size void htable_reset(htable_t *h, size_t sz); -#define HTPROT(HTNAME) \ -void *HTNAME##_get(htable_t *h, void *key); \ -void HTNAME##_put(htable_t *h, void *key, void *val); \ -void HTNAME##_adjoin(htable_t *h, void *key, void *val); \ -int HTNAME##_has(htable_t *h, void *key); \ -int HTNAME##_remove(htable_t *h, void *key); \ -void **HTNAME##_bp(htable_t *h, void *key); +#define HTPROT(HTNAME) \ +void *HTNAME##_get(htable_t *h, void *key) JL_NOTSAFEPOINT; \ +void HTNAME##_put(htable_t *h, void *key, void *val) JL_NOTSAFEPOINT; \ +void HTNAME##_adjoin(htable_t *h, void *key, void *val) JL_NOTSAFEPOINT;\ +int HTNAME##_has(htable_t *h, void *key) JL_NOTSAFEPOINT; \ +int HTNAME##_remove(htable_t *h, void *key) JL_NOTSAFEPOINT; \ +void **HTNAME##_bp(htable_t *h, void *key) JL_NOTSAFEPOINT; #define HTPROT_R(HTNAME) \ void *HTNAME##_get_r(htable_t *h, void *key, void *ctx); \ From 9ab3d8fe057d65662c554692a0a966092ae79fa8 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 17:10:02 -0400 Subject: [PATCH 071/110] Add static analysis annotations for precompile.c --- src/precompile.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/precompile.c b/src/precompile.c index c5392af41c649..188f58c1b2e2a 100644 --- a/src/precompile.c +++ b/src/precompile.c @@ -80,11 +80,13 @@ void jl_write_compiler_output(void) } } - if (jl_options.outputo || jl_options.outputbc || jl_options.outputunoptbc) + if (jl_options.outputo || jl_options.outputbc || jl_options.outputunoptbc) { + assert(s); jl_dump_native(jl_options.outputbc, jl_options.outputunoptbc, jl_options.outputo, (const char*)s->buf, (size_t)s->size); + } } JL_GC_POP(); } @@ -127,6 +129,7 @@ static void _compile_all_tvar_union(jl_value_t *methsig) if (!jl_has_concrete_subtype(sig)) goto getnext; // signature wouldn't be callable / is invalid -- skip it if (jl_is_concrete_type(sig)) { + JL_GC_PROMISE_ROOTED(sig); // `sig` is rooted because it's a leaftype (JL_ALWAYS_LEAFTYPE) if (jl_compile_hint((jl_tupletype_t*)sig)) goto getnext; // success } @@ -197,6 +200,7 @@ static void _compile_all_union(jl_value_t *sig) for (i = 0, idx_ctr = 0, incr = 1; i < l; i++) { jl_value_t *ty = jl_svecref(sigbody->parameters, i); if (jl_is_uniontype(ty)) { + assert(idx_ctr < count_unions); size_t l = jl_count_union_components(ty); size_t j = idx[idx_ctr]; jl_svecset(p, i, jl_nth_union_component(ty, j)); From 54dae01905047ab5873856b106aa3f8d69e2dfcb Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 17:28:26 -0400 Subject: [PATCH 072/110] Add annotations for rtutils --- src/julia.h | 16 ++++++++-------- src/julia_internal.h | 5 +++-- src/module.c | 28 +++++++++++++++++----------- src/rtutils.c | 26 +++++++++++++------------- src/support/utf8.h | 4 +++- 5 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/julia.h b/src/julia.h index a6b58ced8633e..28eacb6de0ff7 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1334,8 +1334,8 @@ JL_DLLEXPORT jl_binding_t *jl_get_binding_wr(jl_module_t *m JL_PROPAGATES_ROOT, JL_DLLEXPORT jl_binding_t *jl_get_binding_for_method_def(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var); JL_DLLEXPORT int jl_boundp(jl_module_t *m, jl_sym_t *var); -JL_DLLEXPORT int jl_defines_or_exports_p(jl_module_t *m, jl_sym_t *var); -JL_DLLEXPORT int jl_binding_resolved_p(jl_module_t *m, jl_sym_t *var); +JL_DLLEXPORT int jl_defines_or_exports_p(jl_module_t *m, jl_sym_t *var) JL_NOTSAFEPOINT; +JL_DLLEXPORT int jl_binding_resolved_p(jl_module_t *m, jl_sym_t *var) JL_NOTSAFEPOINT; JL_DLLEXPORT int jl_is_const(jl_module_t *m, jl_sym_t *var); JL_DLLEXPORT jl_value_t *jl_get_global(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var); JL_DLLEXPORT void jl_set_global(jl_module_t *m JL_ROOTING_ARGUMENT, @@ -1352,7 +1352,7 @@ JL_DLLEXPORT void jl_module_import(jl_module_t *to, jl_module_t *from, jl_sym_t *s); JL_DLLEXPORT void jl_module_export(jl_module_t *from, jl_sym_t *s); JL_DLLEXPORT int jl_is_imported(jl_module_t *m, jl_sym_t *s); -JL_DLLEXPORT int jl_module_exports_p(jl_module_t *m, jl_sym_t *var); +JL_DLLEXPORT int jl_module_exports_p(jl_module_t *m, jl_sym_t *var) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_module_t *jl_new_main_module(void); JL_DLLEXPORT void jl_add_standard_imports(jl_module_t *m); STATIC_INLINE jl_function_t *jl_get_function(jl_module_t *m, const char *name) @@ -1770,11 +1770,11 @@ JL_DLLEXPORT JL_STREAM *jl_stdin_stream(void); JL_DLLEXPORT JL_STREAM *jl_stderr_stream(void); // showing and std streams -JL_DLLEXPORT void jl_flush_cstdio(void); -JL_DLLEXPORT jl_value_t *jl_stdout_obj(void); -JL_DLLEXPORT jl_value_t *jl_stderr_obj(void); -JL_DLLEXPORT size_t jl_static_show(JL_STREAM *out, jl_value_t *v); -JL_DLLEXPORT size_t jl_static_show_func_sig(JL_STREAM *s, jl_value_t *type); +JL_DLLEXPORT void jl_flush_cstdio(void) JL_NOTSAFEPOINT; +JL_DLLEXPORT jl_value_t *jl_stdout_obj(void) JL_NOTSAFEPOINT; +JL_DLLEXPORT jl_value_t *jl_stderr_obj(void) JL_NOTSAFEPOINT; +JL_DLLEXPORT size_t jl_static_show(JL_STREAM *out, jl_value_t *v) JL_NOTSAFEPOINT; +JL_DLLEXPORT size_t jl_static_show_func_sig(JL_STREAM *s, jl_value_t *type) JL_NOTSAFEPOINT; JL_DLLEXPORT void jlbacktrace(void); // Mainly for debugging, use `void*` so that no type cast is needed in C++. JL_DLLEXPORT void jl_(void *jl_value); diff --git a/src/julia_internal.h b/src/julia_internal.h index 7626f76f293a1..6ff53f13d3db3 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -465,6 +465,7 @@ void jl_compute_field_offsets(jl_datatype_t *st); jl_array_t *jl_new_array_for_deserialization(jl_value_t *atype, uint32_t ndims, size_t *dims, int isunboxed, int elsz); void jl_module_run_initializer(jl_module_t *m); +jl_binding_t *jl_get_module_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT; extern jl_array_t *jl_module_init_order JL_GLOBALLY_ROOTED; extern jl_array_t *jl_cfunction_list JL_GLOBALLY_ROOTED; @@ -699,8 +700,8 @@ extern JL_DLLEXPORT jl_value_t *jl_segv_exception; #endif // -- Runtime intrinsics -- // -JL_DLLEXPORT const char *jl_intrinsic_name(int f); -unsigned jl_intrinsic_nargs(int f); +JL_DLLEXPORT const char *jl_intrinsic_name(int f) JL_NOTSAFEPOINT; +unsigned jl_intrinsic_nargs(int f) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_value_t *jl_bitcast(jl_value_t *ty, jl_value_t *v); JL_DLLEXPORT jl_value_t *jl_pointerref(jl_value_t *p, jl_value_t *i, jl_value_t *align); diff --git a/src/module.c b/src/module.c index efbd7da58cf39..a0f75bffc4345 100644 --- a/src/module.c +++ b/src/module.c @@ -128,14 +128,14 @@ JL_DLLEXPORT jl_binding_t *jl_get_binding_wr(jl_module_t *m, jl_sym_t *var, int // Hash tables don't generically root their contents, but they do for bindings. // Express this to the analyzer. #ifdef __clang_analyzer__ -jl_binding_t *jl_get_module_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT; -jl_binding_t **jl_get_module_binding_bp(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT; +jl_binding_t *_jl_get_module_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT; +jl_binding_t **_jl_get_module_binding_bp(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT; #else -static inline jl_binding_t *jl_get_module_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT +static inline jl_binding_t *_jl_get_module_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT { return (jl_binding_t*)ptrhash_get(&m->bindings, var); } -static inline jl_binding_t **jl_get_module_binding_bp(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT +static inline jl_binding_t **_jl_get_module_binding_bp(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT { return (jl_binding_t**)ptrhash_bp(&m->bindings, var); } @@ -155,7 +155,7 @@ JL_DLLEXPORT jl_module_t *jl_get_module_of_binding(jl_module_t *m, jl_sym_t *var // like jl_get_binding_wr, but has different error paths JL_DLLEXPORT jl_binding_t *jl_get_binding_for_method_def(jl_module_t *m, jl_sym_t *var) { - jl_binding_t **bp = jl_get_module_binding_bp(m, var); + jl_binding_t **bp = _jl_get_module_binding_bp(m, var); jl_binding_t *b = *bp; if (b != HT_NOTFOUND) { @@ -203,7 +203,7 @@ static jl_binding_t *using_resolve_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl jl_module_t *owner = NULL; for(int i=(int)m->usings.len-1; i >= 0; --i) { jl_module_t *imp = (jl_module_t*)m->usings.items[i]; - jl_binding_t *tempb = jl_get_module_binding(imp, var); + jl_binding_t *tempb = _jl_get_module_binding(imp, var); if (tempb != HT_NOTFOUND && tempb->exportp) { tempb = jl_get_binding_(imp, var, st); if (tempb == NULL || tempb->owner == NULL) @@ -244,7 +244,7 @@ static jl_binding_t *jl_get_binding_(jl_module_t *m, jl_sym_t *var, modstack_t * } tmp = tmp->prev; } - jl_binding_t *b = jl_get_module_binding(m, var); + jl_binding_t *b = _jl_get_module_binding(m, var); if (b == HT_NOTFOUND || b->owner == NULL) { b = using_resolve_binding(m, var, &top, 1); if (b != NULL) { @@ -470,18 +470,24 @@ JL_DLLEXPORT int jl_defines_or_exports_p(jl_module_t *m, jl_sym_t *var) return b != HT_NOTFOUND && (b->exportp || b->owner==m); } -JL_DLLEXPORT int jl_module_exports_p(jl_module_t *m, jl_sym_t *var) +JL_DLLEXPORT int jl_module_exports_p(jl_module_t *m, jl_sym_t *var) JL_NOTSAFEPOINT { - jl_binding_t *b = (jl_binding_t*)ptrhash_get(&m->bindings, var); + jl_binding_t *b = _jl_get_module_binding(m, var); return b != HT_NOTFOUND && b->exportp; } -JL_DLLEXPORT int jl_binding_resolved_p(jl_module_t *m, jl_sym_t *var) +JL_DLLEXPORT int jl_binding_resolved_p(jl_module_t *m, jl_sym_t *var) JL_NOTSAFEPOINT { - jl_binding_t *b = (jl_binding_t*)ptrhash_get(&m->bindings, var); + jl_binding_t *b = _jl_get_module_binding(m, var); return b != HT_NOTFOUND && b->owner != NULL; } +JL_DLLEXPORT jl_binding_t *jl_get_module_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var) JL_NOTSAFEPOINT +{ + jl_binding_t *b = _jl_get_module_binding(m, var); + return b == HT_NOTFOUND ? NULL : b; +} + JL_DLLEXPORT jl_value_t *jl_get_global(jl_module_t *m, jl_sym_t *var) { jl_binding_t *b = jl_get_binding(m, var); diff --git a/src/rtutils.c b/src/rtutils.c index 1e0295a0217a6..84a7d8082830c 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -462,20 +462,20 @@ JL_DLLEXPORT int jl_substrtof(char *str, int offset, size_t len, float *out) // showing -------------------------------------------------------------------- -JL_DLLEXPORT void jl_flush_cstdio(void) +JL_DLLEXPORT void jl_flush_cstdio(void) JL_NOTSAFEPOINT { fflush(stdout); fflush(stderr); } -JL_DLLEXPORT jl_value_t *jl_stdout_obj(void) +JL_DLLEXPORT jl_value_t *jl_stdout_obj(void) JL_NOTSAFEPOINT { if (jl_base_module == NULL) return NULL; jl_value_t *stdout_obj = jl_get_global(jl_base_module, jl_symbol("stdout")); return stdout_obj; } -JL_DLLEXPORT jl_value_t *jl_stderr_obj(void) +JL_DLLEXPORT jl_value_t *jl_stderr_obj(void) JL_NOTSAFEPOINT { if (jl_base_module == NULL) return NULL; jl_value_t *stderr_obj = jl_get_global(jl_base_module, jl_symbol("stderr")); @@ -484,7 +484,7 @@ JL_DLLEXPORT jl_value_t *jl_stderr_obj(void) // toys for debugging --------------------------------------------------------- -static size_t jl_show_svec(JL_STREAM *out, jl_svec_t *t, const char *head, const char *opn, const char *cls) +static size_t jl_show_svec(JL_STREAM *out, jl_svec_t *t, const char *head, const char *opn, const char *cls) JL_NOTSAFEPOINT { size_t i, n=0, len = jl_svec_len(t); n += jl_printf(out, "%s", head); @@ -504,12 +504,12 @@ struct recur_list { jl_value_t *v; }; -static size_t jl_static_show_x(JL_STREAM *out, jl_value_t *v, struct recur_list *depth); +static size_t jl_static_show_x(JL_STREAM *out, jl_value_t *v, struct recur_list *depth) JL_NOTSAFEPOINT; -JL_DLLEXPORT int jl_id_start_char(uint32_t wc); -JL_DLLEXPORT int jl_id_char(uint32_t wc); +JL_DLLEXPORT int jl_id_start_char(uint32_t wc) JL_NOTSAFEPOINT; +JL_DLLEXPORT int jl_id_char(uint32_t wc) JL_NOTSAFEPOINT; -JL_DLLEXPORT int jl_is_identifier(char *str) +JL_DLLEXPORT int jl_is_identifier(char *str) JL_NOTSAFEPOINT { size_t i = 0; uint32_t wc = u8_nextchar(str, &i); @@ -528,7 +528,7 @@ JL_DLLEXPORT int jl_is_identifier(char *str) // This is necessary to make sure that this function doesn't allocate any // memory through the Julia GC static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt, - struct recur_list *depth) + struct recur_list *depth) JL_NOTSAFEPOINT { size_t n = 0; if ((uintptr_t)vt < 4096U) { @@ -576,7 +576,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt if (globname && !strchr(jl_symbol_name(globname), '#') && !strchr(jl_symbol_name(globname), '@') && dv->name->module && jl_binding_resolved_p(dv->name->module, globname)) { - jl_binding_t *b = jl_get_binding(dv->name->module, globname); + jl_binding_t *b = jl_get_module_binding(dv->name->module, globname); if (b && jl_typeof(b->value) == v) globfunc = 1; } @@ -933,7 +933,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt return n; } -static size_t jl_static_show_x(JL_STREAM *out, jl_value_t *v, struct recur_list *depth) +static size_t jl_static_show_x(JL_STREAM *out, jl_value_t *v, struct recur_list *depth) JL_NOTSAFEPOINT { // show values without calling a julia method or allocating through the GC if (v == NULL) { @@ -953,12 +953,12 @@ static size_t jl_static_show_x(JL_STREAM *out, jl_value_t *v, struct recur_list return jl_static_show_x_(out, v, (jl_datatype_t*)jl_typeof(v), &this_item); } -JL_DLLEXPORT size_t jl_static_show(JL_STREAM *out, jl_value_t *v) +JL_DLLEXPORT size_t jl_static_show(JL_STREAM *out, jl_value_t *v) JL_NOTSAFEPOINT { return jl_static_show_x(out, v, 0); } -JL_DLLEXPORT size_t jl_static_show_func_sig(JL_STREAM *s, jl_value_t *type) +JL_DLLEXPORT size_t jl_static_show_func_sig(JL_STREAM *s, jl_value_t *type) JL_NOTSAFEPOINT { jl_value_t *ftype = (jl_value_t*)jl_first_argument_datatype(type); if (ftype == NULL) diff --git a/src/support/utf8.h b/src/support/utf8.h index ba5085a2b34f3..1d8e31c043838 100644 --- a/src/support/utf8.h +++ b/src/support/utf8.h @@ -7,6 +7,8 @@ extern "C" { #endif +#include "analyzer_annotations.h" + /* is c the start of a utf8 sequence? */ #define isutf(c) (((c)&0xC0)!=0x80) @@ -28,7 +30,7 @@ JL_DLLEXPORT size_t u8_offset(const char *str, size_t charnum); JL_DLLEXPORT size_t u8_charnum(const char *str, size_t offset); /* return next character, updating an index variable */ -uint32_t u8_nextchar(const char *s, size_t *i); +uint32_t u8_nextchar(const char *s, size_t *i) JL_NOTSAFEPOINT; /* next character without NUL character terminator */ uint32_t u8_nextmemchar(const char *s, size_t *i); From db21a81d79fe00c217365073eebfb265e71ca00a Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 18:13:07 -0400 Subject: [PATCH 073/110] Add annotations for runtime_intrinsics.c --- src/runtime_intrinsics.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index 92c19c8fe5898..eece1a1f9cc38 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -82,6 +82,7 @@ JL_DLLEXPORT jl_value_t *jl_cglobal(jl_value_t *v, jl_value_t *ty) jl_value_t *rt = ty == (jl_value_t*)jl_void_type ? (jl_value_t*)jl_voidpointer_type : // a common case (jl_value_t*)jl_apply_type1((jl_value_t*)jl_pointer_type, ty); + JL_GC_PROMISE_ROOTED(rt); // (JL_ALWAYS_LEAFTYPE) if (!jl_is_concrete_type(rt)) jl_error("cglobal: type argument not concrete"); @@ -97,7 +98,7 @@ JL_DLLEXPORT jl_value_t *jl_cglobal(jl_value_t *v, jl_value_t *ty) char *f_lib = NULL; if (jl_is_tuple(v) && jl_nfields(v) > 1) { - jl_value_t *t1 = jl_fieldref(v, 1); + jl_value_t *t1 = jl_fieldref_noalloc(v, 1); v = jl_fieldref(v, 0); if (jl_is_symbol(t1)) f_lib = jl_symbol_name((jl_sym_t*)t1); @@ -132,19 +133,19 @@ JL_DLLEXPORT jl_value_t *jl_cglobal_auto(jl_value_t *v) { return jl_cglobal(v, (jl_value_t*)jl_void_type); } -static inline char signbitbyte(void *a, unsigned bytes) +static inline char signbitbyte(void *a, unsigned bytes) JL_NOTSAFEPOINT { // sign bit of an signed number of n bytes, as a byte return (((signed char*)a)[bytes - 1] < 0) ? ~0 : 0; } -static inline char usignbitbyte(void *a, unsigned bytes) +static inline char usignbitbyte(void *a, unsigned bytes) JL_NOTSAFEPOINT { // sign bit of an unsigned number return 0; } -static inline unsigned select_by_size(unsigned sz) +static inline unsigned select_by_size(unsigned sz) JL_NOTSAFEPOINT { /* choose the right sized function specialization */ switch (sz) { @@ -159,7 +160,7 @@ static inline unsigned select_by_size(unsigned sz) #define SELECTOR_FUNC(intrinsic) \ typedef intrinsic##_t select_##intrinsic##_t[6]; \ - static inline intrinsic##_t select_##intrinsic(unsigned sz, const select_##intrinsic##_t list) \ + static inline intrinsic##_t select_##intrinsic(unsigned sz, const select_##intrinsic##_t list) JL_NOTSAFEPOINT \ { \ intrinsic##_t thunk = list[select_by_size(sz)]; \ if (!thunk) thunk = list[0]; \ @@ -179,7 +180,7 @@ static inline unsigned select_by_size(unsigned sz) // nbits::number of bits // c_type::c_type corresponding to nbits #define un_iintrinsic_ctype(OP, name, nbits, c_type) \ -static inline void jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pr) \ +static inline void jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pr) JL_NOTSAFEPOINT \ { \ c_type a = *(c_type*)pa; \ *(c_type*)pr = OP(a); \ @@ -191,7 +192,7 @@ static inline void jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pr) // nbits::number of bits // c_type::c_type corresponding to nbits #define uu_iintrinsic_ctype(OP, name, nbits, c_type) \ -static inline unsigned jl_##name##nbits(unsigned runtime_nbits, void *pa) \ +static inline unsigned jl_##name##nbits(unsigned runtime_nbits, void *pa) JL_NOTSAFEPOINT \ { \ c_type a = *(c_type*)pa; \ return OP(a); \ @@ -203,7 +204,7 @@ static inline unsigned jl_##name##nbits(unsigned runtime_nbits, void *pa) \ // nbits::number of bits in the *input* // c_type::c_type corresponding to nbits #define un_fintrinsic_ctype(OP, name, c_type) \ -static inline void name(unsigned osize, void *pa, void *pr) \ +static inline void name(unsigned osize, void *pa, void *pr) JL_NOTSAFEPOINT \ { \ c_type a = *(c_type*)pa; \ OP((c_type*)pr, a); \ @@ -215,7 +216,7 @@ static inline void name(unsigned osize, void *pa, void *pr) \ // nbits::number of bits // c_type::c_type corresponding to nbits #define bi_intrinsic_ctype(OP, name, nbits, c_type) \ -static void jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb, void *pr) \ +static void jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb, void *pr) JL_NOTSAFEPOINT \ { \ c_type a = *(c_type*)pa; \ c_type b = *(c_type*)pb; \ @@ -228,7 +229,7 @@ static void jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb, void *p // nbits::number of bits // c_type::c_type corresponding to nbits #define bool_intrinsic_ctype(OP, name, nbits, c_type) \ -static int jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb) \ +static int jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb) JL_NOTSAFEPOINT \ { \ c_type a = *(c_type*)pa; \ c_type b = *(c_type*)pb; \ @@ -241,7 +242,7 @@ static int jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb) \ // nbits::number of bits // c_type::c_type corresponding to nbits #define checked_intrinsic_ctype(CHECK_OP, OP, name, nbits, c_type) \ -static int jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb, void *pr) \ +static int jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb, void *pr) JL_NOTSAFEPOINT \ { \ c_type a = *(c_type*)pa; \ c_type b = *(c_type*)pb; \ @@ -257,7 +258,7 @@ static int jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb, void *pr // nbits::number of bits // c_type::c_type corresponding to nbits #define ter_intrinsic_ctype(OP, name, nbits, c_type) \ -static void jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb, void *pc, void *pr) \ +static void jl_##name##nbits(unsigned runtime_nbits, void *pa, void *pb, void *pc, void *pr) JL_NOTSAFEPOINT \ { \ c_type a = *(c_type*)pa; \ c_type b = *(c_type*)pb; \ @@ -498,7 +499,7 @@ static const select_intrinsic_cmp_t name##_list = { \ }; \ cmp_iintrinsic(name, u) -typedef int (*intrinsic_checked_t)(unsigned, void*, void*, void*); +typedef int (*intrinsic_checked_t)(unsigned, void*, void*, void*) JL_NOTSAFEPOINT; SELECTOR_FUNC(intrinsic_checked) #define checked_iintrinsic(name, u, lambda_checked) \ JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a, jl_value_t *b) \ @@ -590,6 +591,7 @@ static inline jl_value_t *jl_intrinsiclambda_checked(jl_value_t *ty, void *pa, v params[0] = ty; params[1] = (jl_value_t*)jl_bool_type; jl_datatype_t *tuptyp = jl_apply_tuple_type_v(params, 2); + JL_GC_PROMISE_ROOTED(tuptyp); // (JL_ALAWYS_LEAFTYPE) jl_ptls_t ptls = jl_get_ptls_states(); jl_value_t *newv = jl_gc_alloc(ptls, ((jl_datatype_t*)tuptyp)->size, tuptyp); From 06968c157bc7e52bf83c7d8e17d4273cbc574f42 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 18:20:46 -0400 Subject: [PATCH 074/110] Silence analyzer complaints about signal-handling.c --- src/signals-unix.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/signals-unix.c b/src/signals-unix.c index 230c0cb2dada5..298270b52aca0 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -577,7 +577,6 @@ static void *signal_listener(void *arg) } #endif while (1) { - profile = 0; sig = 0; errno = 0; #ifdef HAVE_KEVENT From 13820d0fd295549dda4984c9ab9d204bd30d05eb Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 18 Aug 2018 18:21:59 -0400 Subject: [PATCH 075/110] Add static analysis annotations for stackwalk.c --- src/stackwalk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stackwalk.c b/src/stackwalk.c index 735dcf0e71411..dce26784dfb1f 100644 --- a/src/stackwalk.c +++ b/src/stackwalk.c @@ -95,7 +95,7 @@ size_t rec_backtrace(uintptr_t *data, size_t maxsize) return rec_backtrace_ctx(data, maxsize, &context); } -static jl_value_t *array_ptr_void_type = NULL; +static jl_value_t *array_ptr_void_type JL_ALWAYS_LEAFTYPE = NULL; JL_DLLEXPORT jl_value_t *jl_backtrace_from_here(int returnsp) { jl_array_t *ip = NULL; From 4d6d216c5e728cf27fbc6d18d77c758d7fe83d7a Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 19 Aug 2018 15:46:28 -0400 Subject: [PATCH 076/110] Add static analysis annotations for subtype.c --- src/julia.h | 2 +- src/julia_internal.h | 4 +-- src/subtype.c | 63 +++++++++++++++++++++++++++----------------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/julia.h b/src/julia.h index 28eacb6de0ff7..cef517bc8b9b5 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1073,7 +1073,7 @@ JL_DLLEXPORT uintptr_t jl_object_id(jl_value_t *v) JL_NOTSAFEPOINT; // type predicates and basic operations JL_DLLEXPORT int jl_has_free_typevars(jl_value_t *v) JL_NOTSAFEPOINT; -JL_DLLEXPORT int jl_has_typevar(jl_value_t *t, jl_tvar_t *v); +JL_DLLEXPORT int jl_has_typevar(jl_value_t *t, jl_tvar_t *v) JL_NOTSAFEPOINT; JL_DLLEXPORT int jl_has_typevar_from_unionall(jl_value_t *t, jl_unionall_t *ua); JL_DLLEXPORT int jl_subtype_env_size(jl_value_t *t); JL_DLLEXPORT int jl_subtype_env(jl_value_t *x, jl_value_t *y, jl_value_t **env, int envsz); diff --git a/src/julia_internal.h b/src/julia_internal.h index 6ff53f13d3db3..81e3f7924ab45 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -397,10 +397,10 @@ jl_fptr_args_t jl_get_builtin_fptr(jl_value_t *b); extern uv_loop_t *jl_io_loop; void jl_uv_flush(uv_stream_t *stream); -typedef struct _typeenv { +typedef struct jl_typeenv_t { jl_tvar_t *var; jl_value_t *val; - struct _typeenv *prev; + struct jl_typeenv_t *prev; } jl_typeenv_t; int jl_tuple_isa(jl_value_t **child, size_t cl, jl_datatype_t *pdt); diff --git a/src/subtype.c b/src/subtype.c index 6ecea1840559f..1fc6bf33fde5a 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -52,7 +52,7 @@ typedef struct { // during the computation. // Most of the complexity is due to the "diagonal rule", requiring us to // identify which type vars range over only concrete types. -typedef struct _varbinding { +typedef struct jl_varbinding_t { jl_tvar_t *var; jl_value_t *lb; jl_value_t *ub; @@ -79,14 +79,16 @@ typedef struct _varbinding { // array of typevars that our bounds depend on, whose UnionAlls need to be // moved outside ours. jl_array_t *innervars; - struct _varbinding *prev; + struct jl_varbinding_t *prev; } jl_varbinding_t; // subtype algorithm state -typedef struct { +typedef struct jl_stenv_t { + // N.B.: varbindings are created on the stack and rooted there jl_varbinding_t *vars; // type variable environment jl_unionstate_t Lunions; // union state for unions on the left of A <: B jl_unionstate_t Runions; // union state for unions on the right + // N.B.: envout is gc-rooted jl_value_t **envout; // for passing caller the computed bounds of right-side variables int envsz; // length of envout int envidx; // current index in envout @@ -99,7 +101,10 @@ typedef struct { // state manipulation utilities // look up a type variable in an environment -static jl_varbinding_t *lookup(jl_stenv_t *e, jl_tvar_t *v) +#ifdef __clang_analyzer__ +static jl_varbinding_t *lookup(jl_stenv_t *e, jl_tvar_t *v) JL_GLOBALLY_ROOTED JL_NOTSAFEPOINT; +#else +static jl_varbinding_t *lookup(jl_stenv_t *e, jl_tvar_t *v) JL_GLOBALLY_ROOTED JL_NOTSAFEPOINT { jl_varbinding_t *b = e->vars; while (b != NULL) { @@ -108,15 +113,16 @@ static jl_varbinding_t *lookup(jl_stenv_t *e, jl_tvar_t *v) } return b; } +#endif -static int statestack_get(jl_unionstate_t *st, int i) +static int statestack_get(jl_unionstate_t *st, int i) JL_NOTSAFEPOINT { assert(i >= 0 && i < sizeof(st->stack) * 8); // get the `i`th bit in an array of 32-bit words return (st->stack[i>>5] & (1<<(i&31))) != 0; } -static void statestack_set(jl_unionstate_t *st, int i, int val) +static void statestack_set(jl_unionstate_t *st, int i, int val) JL_NOTSAFEPOINT { assert(i >= 0 && i < sizeof(st->stack) * 8); if (val) @@ -140,6 +146,10 @@ static void save_env(jl_stenv_t *e, jl_value_t **root, jl_savedenv_t *se) } *root = (jl_value_t*)jl_alloc_svec(len*3); se->buf = (int8_t*)(len ? malloc(len*2) : NULL); +#ifdef __clang_analyzer__ + if (len) + memset(se->buf, 0, len*2); +#endif int i=0, j=0; v = e->vars; while (v != NULL) { jl_svecset(*root, i++, v->lb); @@ -152,7 +162,7 @@ static void save_env(jl_stenv_t *e, jl_value_t **root, jl_savedenv_t *se) se->rdepth = e->Runions.depth; } -static void restore_env(jl_stenv_t *e, jl_value_t *root, jl_savedenv_t *se) +static void restore_env(jl_stenv_t *e, jl_value_t *root, jl_savedenv_t *se) JL_NOTSAFEPOINT { jl_varbinding_t *v = e->vars; int i = 0, j = 0; @@ -163,6 +173,7 @@ static void restore_env(jl_stenv_t *e, jl_value_t *root, jl_savedenv_t *se) i++; if (root) v->innervars = (jl_array_t*)jl_svecref(root, i); i++; + assert(se->buf); v->occurs_inv = se->buf[j++]; v->occurs_cov = se->buf[j++]; v = v->prev; @@ -416,7 +427,7 @@ static jl_unionall_t *rename_unionall(jl_unionall_t *u) static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param); -static jl_value_t *pick_union_element(jl_value_t *u, jl_stenv_t *e, int8_t R) +static jl_value_t *pick_union_element(jl_value_t *u JL_PROPAGATES_ROOT, jl_stenv_t *e, int8_t R) JL_NOTSAFEPOINT { jl_unionstate_t *state = R ? &e->Runions : &e->Lunions; do { @@ -467,7 +478,7 @@ static int subtype_ccheck(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) // use the current context to record where a variable occurred, for the purpose // of determining whether the variable is concrete. -static void record_var_occurrence(jl_varbinding_t *vb, jl_stenv_t *e, int param) +static void record_var_occurrence(jl_varbinding_t *vb, jl_stenv_t *e, int param) JL_NOTSAFEPOINT { if (vb != NULL && param) { // saturate counters at 2; we don't need values bigger than that @@ -552,7 +563,7 @@ static int var_gt(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int param) // check that a type is concrete or quasi-concrete (Type{T}). // this is used to check concrete typevars: // issubtype is false if the lower bound of a concrete type var is not concrete. -static int is_leaf_bound(jl_value_t *v) +static int is_leaf_bound(jl_value_t *v) JL_NOTSAFEPOINT { if (v == jl_bottom_type) return 1; @@ -567,12 +578,12 @@ static int is_leaf_bound(jl_value_t *v) return !jl_is_type(v) && !jl_is_typevar(v); } -static int is_leaf_typevar(jl_tvar_t *v) +static int is_leaf_typevar(jl_tvar_t *v) JL_NOTSAFEPOINT { return is_leaf_bound(v->lb); } -static jl_value_t *widen_Type(jl_value_t *t) +static jl_value_t *widen_Type(jl_value_t *t JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT { if (jl_is_type_type(t) && !jl_is_typevar(jl_tparam0(t))) return jl_typeof(jl_tparam0(t)); @@ -594,7 +605,7 @@ JL_DLLEXPORT jl_array_t *jl_find_free_typevars(jl_value_t *v); // but this causes us to infer the larger `Type{T} where T<:Vector` instead. // However this is needed because many contexts check `isa(sp, TypeVar)` to determine // when a static parameter value is not known exactly. -static jl_value_t *fix_inferred_var_bound(jl_tvar_t *var, jl_value_t *ty) +static jl_value_t *fix_inferred_var_bound(jl_tvar_t *var, jl_value_t *ty JL_MAYBE_UNROOTED) { if (!jl_is_typevar(ty) && jl_has_free_typevars(ty)) { jl_value_t *ans = ty; @@ -612,7 +623,7 @@ static jl_value_t *fix_inferred_var_bound(jl_tvar_t *var, jl_value_t *ty) return ty; } -static int var_occurs_inside(jl_value_t *v, jl_tvar_t *var, int inside, int want_inv); +static int var_occurs_inside(jl_value_t *v, jl_tvar_t *var, int inside, int want_inv) JL_NOTSAFEPOINT; // compare UnionAll type `u` to `t`. `R==1` if `u` came from the right side of A <: B. static int subtype_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_t *e, int8_t R, int param) @@ -729,8 +740,9 @@ static int subtype_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_t *e, int8 } // unwrap <=2 layers of UnionAlls, leaving the vars in *p1 and *p2 and returning the body -static jl_value_t *unwrap_2_unionall(jl_value_t *t, jl_tvar_t **p1, jl_tvar_t **p2) +static jl_value_t *unwrap_2_unionall(jl_value_t *t, jl_tvar_t **p1, jl_tvar_t **p2) JL_NOTSAFEPOINT { + assert(t); if (jl_is_unionall(t)) { *p1 = ((jl_unionall_t*)t)->var; t = ((jl_unionall_t*)t)->body; @@ -950,6 +962,7 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param) jl_value_t *ux = jl_unwrap_unionall(x); jl_value_t *uy = jl_unwrap_unionall(y); if ((x != ux || y != uy) && y != (jl_value_t*)jl_any_type && jl_is_datatype(ux) && jl_is_datatype(uy)) { + assert(ux); jl_datatype_t *xd = (jl_datatype_t*)ux, *yd = (jl_datatype_t*)uy; while (xd != NULL && xd != jl_any_type && xd->name != yd->name) { xd = xd->super; @@ -1330,7 +1343,7 @@ static jl_value_t *intersect_ufirst(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, } // set a variable to a non-type constant -static jl_value_t *set_var_to_const(jl_varbinding_t *bb, jl_value_t *v, jl_varbinding_t *othervar) +static jl_value_t *set_var_to_const(jl_varbinding_t *bb, jl_value_t *v JL_MAYBE_UNROOTED, jl_varbinding_t *othervar) { int offset = bb->offset; if (othervar && offset == 0) @@ -1474,7 +1487,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int // test whether `var` occurs inside constructors. `want_inv` tests only inside // invariant constructors. `inside` means we are currently inside a constructor of the // requested kind. -static int var_occurs_inside(jl_value_t *v, jl_tvar_t *var, int inside, int want_inv) +static int var_occurs_inside(jl_value_t *v, jl_tvar_t *var, int inside, int want_inv) JL_NOTSAFEPOINT { if (v == (jl_value_t*)var) { return inside; @@ -1503,7 +1516,7 @@ static int var_occurs_inside(jl_value_t *v, jl_tvar_t *var, int inside, int want } // Caller might not have rooted `res` -static jl_value_t *finish_unionall(jl_value_t *res, jl_varbinding_t *vb, jl_stenv_t *e) +static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbinding_t *vb, jl_stenv_t *e) { jl_value_t *varval = NULL; jl_tvar_t *newvar = vb->var; @@ -1605,7 +1618,7 @@ static jl_value_t *finish_unionall(jl_value_t *res, jl_varbinding_t *vb, jl_sten if (res != jl_bottom_type && vb->innervars != NULL) { int i; for(i=0; i < jl_array_len(vb->innervars); i++) { - jl_tvar_t *var = (jl_tvar_t*)jl_arrayref(vb->innervars, i); + jl_tvar_t *var = (jl_tvar_t*)jl_array_ptr_ref(vb->innervars, i); if (jl_has_typevar(res, var)) res = jl_new_struct(jl_unionall_type, (jl_tvar_t*)var, res); } @@ -1896,13 +1909,15 @@ static jl_value_t *intersect_invariant(jl_value_t *x, jl_value_t *y, jl_stenv_t if (jl_is_typevar(x) && jl_is_typevar(y) && (jl_is_typevar(ii) || !jl_is_type(ii))) return ii; if (ii == jl_bottom_type) { - if (!subtype_in_env(x, ii, e)) + if (!subtype_in_env(x, jl_bottom_type, e)) return NULL; flip_vars(e); - if (!subtype_in_env(y, ii, e)) - ii = NULL; + if (!subtype_in_env(y, jl_bottom_type, e)) { + flip_vars(e); + return NULL; + } flip_vars(e); - return ii; + return jl_bottom_type; } /* TODO: This is a band-aid for issue #23685. A better solution would be to @@ -2482,7 +2497,7 @@ static int type_morespecific_(jl_value_t *a, jl_value_t *b, int invariant, jl_ty static int num_occurs(jl_tvar_t *v, jl_typeenv_t *env); -static jl_value_t *nth_tuple_elt(jl_datatype_t *t, size_t i) +static jl_value_t *nth_tuple_elt(jl_datatype_t *t JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT { size_t len = jl_field_count(t); if (len == 0) From 4eeb8f7120d13a6998d22f7a2889ef7f1f7830b9 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 19 Aug 2018 15:48:28 -0400 Subject: [PATCH 077/110] Add static analysis annotations for sys.c --- src/support/ios.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/support/ios.h b/src/support/ios.h index 0f47b61e387fc..1a8cfc42f3f42 100644 --- a/src/support/ios.h +++ b/src/support/ios.h @@ -80,7 +80,7 @@ JL_DLLEXPORT int64_t ios_seek(ios_t *s, int64_t pos); // absolute seek JL_DLLEXPORT int64_t ios_seek_end(ios_t *s); JL_DLLEXPORT int64_t ios_skip(ios_t *s, int64_t offs); // relative seek JL_DLLEXPORT int64_t ios_pos(ios_t *s); // get current position -JL_DLLEXPORT int ios_trunc(ios_t *s, size_t size); +JL_DLLEXPORT int ios_trunc(ios_t *s, size_t size) JL_NOTSAFEPOINT; JL_DLLEXPORT int ios_eof(ios_t *s); JL_DLLEXPORT int ios_eof_blocking(ios_t *s); JL_DLLEXPORT int ios_flush(ios_t *s); @@ -88,14 +88,14 @@ JL_DLLEXPORT void ios_close(ios_t *s); JL_DLLEXPORT int ios_isopen(ios_t *s); JL_DLLEXPORT char *ios_take_buffer(ios_t *s, size_t *psize); // release buffer to caller // set buffer space to use -JL_DLLEXPORT int ios_setbuf(ios_t *s, char *buf, size_t size, int own); +JL_DLLEXPORT int ios_setbuf(ios_t *s, char *buf, size_t size, int own) JL_NOTSAFEPOINT; JL_DLLEXPORT int ios_bufmode(ios_t *s, bufmode_t mode); JL_DLLEXPORT int ios_get_readable(ios_t *s); JL_DLLEXPORT int ios_get_writable(ios_t *s); JL_DLLEXPORT void ios_set_readonly(ios_t *s); JL_DLLEXPORT size_t ios_copy(ios_t *to, ios_t *from, size_t nbytes); JL_DLLEXPORT size_t ios_copyall(ios_t *to, ios_t *from); -JL_DLLEXPORT size_t ios_copyuntil(ios_t *to, ios_t *from, char delim); +JL_DLLEXPORT size_t ios_copyuntil(ios_t *to, ios_t *from, char delim) JL_NOTSAFEPOINT; JL_DLLEXPORT size_t ios_nchomp(ios_t *from, size_t ntowrite); // ensure at least n bytes are buffered if possible. returns # available. JL_DLLEXPORT size_t ios_readprep(ios_t *from, size_t n); @@ -104,7 +104,7 @@ JL_DLLEXPORT size_t ios_readprep(ios_t *from, size_t n); JL_DLLEXPORT ios_t *ios_file(ios_t *s, const char *fname, int rd, int wr, int create, int trunc); JL_DLLEXPORT ios_t *ios_mkstemp(ios_t *f, char *fname); -JL_DLLEXPORT ios_t *ios_mem(ios_t *s, size_t initsize); +JL_DLLEXPORT ios_t *ios_mem(ios_t *s, size_t initsize) JL_NOTSAFEPOINT; ios_t *ios_str(ios_t *s, char *str); ios_t *ios_static_buffer(ios_t *s, char *buf, size_t sz); JL_DLLEXPORT ios_t *ios_fd(ios_t *s, long fd, int isfile, int own); From f82084c6b96044e5edd9ee246fb85ff11c88421f Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 19 Aug 2018 16:51:59 -0400 Subject: [PATCH 078/110] Add static analysis annotations for task.c --- src/julia_internal.h | 6 +++--- src/julia_threads.h | 7 +++++++ src/task.c | 13 ++++++++----- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/julia_internal.h b/src/julia_internal.h index 81e3f7924ab45..db144ef1a1754 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -488,7 +488,7 @@ void *jl_init_llvm(void); void jl_init_codegen(void); void jl_init_intrinsic_functions(void); void jl_init_intrinsic_properties(void); -void jl_init_tasks(void); +void jl_init_tasks(void) JL_GC_DISABLED; void jl_init_stack_limits(int ismaster); void jl_init_root_task(void *stack, size_t ssize); void jl_init_serializer(void); @@ -635,8 +635,8 @@ typedef unw_cursor_t bt_cursor_t; typedef int bt_context_t; typedef int bt_cursor_t; #endif -size_t rec_backtrace(uintptr_t *data, size_t maxsize); -size_t rec_backtrace_ctx(uintptr_t *data, size_t maxsize, bt_context_t *ctx); +size_t rec_backtrace(uintptr_t *data, size_t maxsize) JL_NOTSAFEPOINT; +size_t rec_backtrace_ctx(uintptr_t *data, size_t maxsize, bt_context_t *ctx) JL_NOTSAFEPOINT; #ifdef LIBOSXUNWIND size_t rec_backtrace_ctx_dwarf(uintptr_t *data, size_t maxsize, bt_context_t *ctx); #endif diff --git a/src/julia_threads.h b/src/julia_threads.h index b2f99422b50a0..204e358a39763 100644 --- a/src/julia_threads.h +++ b/src/julia_threads.h @@ -209,10 +209,17 @@ STATIC_INLINE int8_t jl_gc_state_save_and_set(jl_ptls_t ptls, { return jl_gc_state_set(ptls, state, jl_gc_state(ptls)); } +#ifdef __clang_analyzer__ +int8_t jl_gc_unsafe_enter(jl_ptls_t ptls); // Can be a safepoint +int8_t jl_gc_unsafe_leave(jl_ptls_t ptls, int8_t state) JL_NOTSAFEPOINT; +int8_t jl_gc_safe_enter(jl_ptls_t ptls) JL_NOTSAFEPOINT; +int8_t jl_gc_safe_leave(jl_ptls_t ptls, int8_t state); // Can be a safepoint +#else #define jl_gc_unsafe_enter(ptls) jl_gc_state_save_and_set(ptls, 0) #define jl_gc_unsafe_leave(ptls, state) ((void)jl_gc_state_set(ptls, (state), 0)) #define jl_gc_safe_enter(ptls) jl_gc_state_save_and_set(ptls, JL_GC_STATE_SAFE) #define jl_gc_safe_leave(ptls, state) ((void)jl_gc_state_set(ptls, (state), JL_GC_STATE_SAFE)) +#endif JL_DLLEXPORT void (jl_gc_safepoint)(void); JL_DLLEXPORT void jl_gc_enable_finalizers(jl_ptls_t ptls, int on); diff --git a/src/task.c b/src/task.c index 7ec5f7e4be09c..f83dfcf6df561 100644 --- a/src/task.c +++ b/src/task.c @@ -41,7 +41,9 @@ volatile int jl_in_stackwalk = 0; #endif /* This probing code is derived from Douglas Jones' user thread library */ +static void _probe_arch(void); +#ifndef __clang_analyzer__ /* true if stack grows up, false if down */ static int _stack_grows_up; @@ -137,6 +139,7 @@ static void _probe_arch(void) intptr_t prior_diff = p.probe_local - p.prior_local; _frame_offset = labs(prior_diff); } +#endif /* end probing code */ @@ -196,7 +199,7 @@ static void NOINLINE restore_stack(jl_ptls_t ptls, char *p) static jl_function_t *task_done_hook_func=NULL; -static void JL_NORETURN finish_task(jl_task_t *t, jl_value_t *resultval) +static void JL_NORETURN finish_task(jl_task_t *t, jl_value_t *resultval JL_MAYBE_UNROOTED) { jl_ptls_t ptls = jl_get_ptls_states(); JL_SIGATOMIC_BEGIN(); @@ -240,7 +243,7 @@ static void JL_NORETURN finish_task(jl_task_t *t, jl_value_t *resultval) abort(); } -static void record_backtrace(void) +static void record_backtrace(void) JL_NOTSAFEPOINT { jl_ptls_t ptls = jl_get_ptls_states(); ptls->bt_size = rec_backtrace(ptls->bt_data, JL_MAX_BT_SIZE); @@ -532,7 +535,7 @@ static void init_task(jl_task_t *t, char *stack) #endif /* !COPY_STACKS */ jl_timing_block_t *jl_pop_timing_block(jl_timing_block_t *cur_block); -JL_DLLEXPORT JL_NORETURN void jl_no_exc_handler(jl_value_t *e) +JL_DLLEXPORT JL_NORETURN void jl_no_exc_handler(jl_value_t *e) JL_NOTSAFEPOINT { jl_printf(JL_STDERR, "fatal: error thrown and no exception handler available.\n"); jl_static_show(JL_STDERR, e); @@ -542,7 +545,7 @@ JL_DLLEXPORT JL_NORETURN void jl_no_exc_handler(jl_value_t *e) } // yield to exception handler -void JL_NORETURN throw_internal(jl_value_t *e) +void JL_NORETURN throw_internal(jl_value_t *e JL_MAYBE_UNROOTED) { jl_ptls_t ptls = jl_get_ptls_states(); ptls->io_wait = 0; @@ -667,7 +670,7 @@ JL_DLLEXPORT jl_value_t *jl_get_current_task(void) jl_function_t *jl_unprotect_stack_func; // Do one-time initializations for task system -void jl_init_tasks(void) +void jl_init_tasks(void) JL_GC_DISABLED { _probe_arch(); jl_task_type = (jl_datatype_t*) From 5a1d3b57691dfdde4c4aca50c29e4e327999537c Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 19 Aug 2018 17:01:37 -0400 Subject: [PATCH 079/110] Add static analysis annotations for threading.c --- src/julia_internal.h | 2 +- src/threading.c | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/julia_internal.h b/src/julia_internal.h index db144ef1a1754..eb57bb5bbe723 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -452,7 +452,7 @@ void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_module_t *mod, jl_sym_t *n jl_method_instance_t *jl_method_lookup(jl_methtable_t *mt JL_PROPAGATES_ROOT, jl_value_t **args, size_t nargs, int cache, size_t world); jl_value_t *jl_gf_invoke(jl_value_t *types, jl_value_t **args, size_t nargs); -jl_method_instance_t *jl_lookup_generic(jl_value_t **args, uint32_t nargs, uint32_t callsite, size_t world); +jl_method_instance_t *jl_lookup_generic(jl_value_t **args, uint32_t nargs, uint32_t callsite, size_t world) JL_ALWAYS_LEAFTYPE; JL_DLLEXPORT jl_value_t *jl_matching_methods(jl_tupletype_t *types, int lim, int include_ambiguous, size_t world, size_t *min_valid, size_t *max_valid); diff --git a/src/threading.c b/src/threading.c index 1f142204b2f60..e75c0949d9ce8 100644 --- a/src/threading.c +++ b/src/threading.c @@ -396,6 +396,7 @@ void ti_threadfun(void *arg) ti_threadgroup_fork(tg, ptls->tid, (void **)&work, init); init = 0; + JL_GC_PROMISE_ROOTED(work); #if PROFILE_JL_THREADING uint64_t tfork = uv_hrtime(); @@ -609,12 +610,15 @@ void jl_start_threads(void) mask[0] = 0; } + // The analyzer doesn't know jl_n_threads doesn't change, help it + size_t nthreads = jl_n_threads; + // create threads - targs = (ti_threadarg_t **)malloc((jl_n_threads - 1) * sizeof (ti_threadarg_t *)); + targs = (ti_threadarg_t **)malloc((nthreads - 1) * sizeof (ti_threadarg_t *)); - uv_barrier_init(&thread_init_done, jl_n_threads); + uv_barrier_init(&thread_init_done, nthreads); - for (i = 0; i < jl_n_threads - 1; ++i) { + for (i = 0; i < nthreads - 1; ++i) { targs[i] = (ti_threadarg_t *)malloc(sizeof (ti_threadarg_t)); targs[i]->state = TI_THREAD_INIT; targs[i]->tid = i + 1; @@ -628,13 +632,13 @@ void jl_start_threads(void) } // set up the world thread group - ti_threadgroup_create(1, jl_n_threads, 1, &tgworld); - for (i = 0; i < jl_n_threads; ++i) + ti_threadgroup_create(1, nthreads, 1, &tgworld); + for (i = 0; i < nthreads; ++i) ti_threadgroup_addthread(tgworld, i, NULL); ti_threadgroup_initthread(tgworld, ptls->tid); // give the threads the world thread group; they will block waiting for fork - for (i = 0; i < jl_n_threads - 1; ++i) { + for (i = 0; i < nthreads - 1; ++i) { targs[i]->tg = tgworld; jl_atomic_store_release(&targs[i]->state, TI_THREAD_WORK); } @@ -719,6 +723,7 @@ JL_DLLEXPORT jl_value_t *jl_threading_run(jl_value_t *_args) #endif // this thread must do work too (TODO: reduction?) + JL_GC_PROMISE_ROOTED(threadwork.mfunc); tw->ret = ti_run_fun(threadwork.fptr, threadwork.mfunc, args, nargs); #if PROFILE_JL_THREADING From 8af9d37034d3043a0c63999c8b557683ceb42473 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 19 Aug 2018 17:44:11 -0400 Subject: [PATCH 080/110] Add static analysis annotations for toplevel.c --- src/support/analyzer_annotations.h | 8 ++++++++ src/toplevel.c | 19 ++++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/support/analyzer_annotations.h b/src/support/analyzer_annotations.h index cb21993d007fe..caf8c6003cbe3 100644 --- a/src/support/analyzer_annotations.h +++ b/src/support/analyzer_annotations.h @@ -1,5 +1,13 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license +#ifndef __has_feature +#define __has_feature(x) 0 +#endif +#if !(defined(__clang__) && __has_feature(nullability)) +#define _Nonnull +#endif +#define JL_NONNULL _Nonnull + #ifdef __clang_analyzer__ #define JL_PROPAGATES_ROOT __attribute__((annotate("julia_propagates_root"))) diff --git a/src/toplevel.c b/src/toplevel.c index 6da0ab47b98f5..e425f7bf37e92 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -73,7 +73,7 @@ JL_DLLEXPORT jl_module_t *jl_new_main_module(void) return old_main; } -static jl_function_t *jl_module_get_initializer(jl_module_t *m) +static jl_function_t *jl_module_get_initializer(jl_module_t *m JL_PROPAGATES_ROOT) { return (jl_function_t*)jl_get_global(m, jl_symbol("__init__")); } @@ -273,7 +273,9 @@ jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex) JL_TRY { size_t i, l = module_stack.len; for (i = stackidx; i < l; i++) { - jl_module_load_time_initialize((jl_module_t*)module_stack.items[i]); + jl_module_t *m = (jl_module_t*)module_stack.items[i]; + JL_GC_PROMISE_ROOTED(m); + jl_module_load_time_initialize(m); } assert(module_stack.len == l); module_stack.len = stackidx; @@ -418,7 +420,7 @@ static void body_attributes(jl_array_t *body, int *has_intrinsics, int *has_defs } } -static jl_module_t *call_require(jl_module_t *mod, jl_sym_t *var) +static jl_module_t *call_require(jl_module_t *mod, jl_sym_t *var) JL_GLOBALLY_ROOTED { static jl_value_t *require_func = NULL; static size_t require_world = 0; @@ -451,7 +453,7 @@ static jl_module_t *call_require(jl_module_t *mod, jl_sym_t *var) // either: // - sets *name and returns the module to import *name from // - sets *name to NULL and returns a module to import -static jl_module_t *eval_import_path(jl_module_t *where, jl_module_t *from, jl_array_t *args, jl_sym_t **name, const char *keyword) +static jl_module_t *eval_import_path(jl_module_t *where, jl_module_t *from JL_PROPAGATES_ROOT, jl_array_t *args, jl_sym_t **name, const char *keyword) JL_GLOBALLY_ROOTED { jl_sym_t *var = (jl_sym_t*)jl_array_ptr_ref(args, 0); size_t i = 1; @@ -488,6 +490,7 @@ static jl_module_t *eval_import_path(jl_module_t *where, jl_module_t *from, jl_a if (var != dot_sym) break; i++; + assert(m); m = m->parent; } } @@ -501,6 +504,7 @@ static jl_module_t *eval_import_path(jl_module_t *where, jl_module_t *from, jl_a if (i == jl_array_len(args)-1) break; m = (jl_module_t*)jl_eval_global_var(m, var); + JL_GC_PROMISE_ROOTED(m); if (!jl_is_module(m)) jl_errorf("invalid %s path: \"%s\" does not name a module", keyword, jl_symbol_name(var)); i++; @@ -535,8 +539,9 @@ static jl_method_instance_t *method_instance_for_thunk(jl_code_info_t *src, jl_m return li; } -static void import_module(jl_module_t *m, jl_module_t *import) +static void import_module(jl_module_t *JL_NONNULL m, jl_module_t *import) { + assert(m); jl_sym_t *name = import->name; jl_binding_t *b; if (jl_binding_resolved_p(m, name)) { @@ -558,7 +563,7 @@ static void import_module(jl_module_t *m, jl_module_t *import) } // in `import A.B: x, y, ...`, evaluate the `A.B` part if it exists -static jl_module_t *eval_import_from(jl_module_t *m, jl_expr_t *ex, const char *keyword) +static jl_module_t *eval_import_from(jl_module_t *m JL_PROPAGATES_ROOT, jl_expr_t *ex, const char *keyword) { if (jl_expr_nargs(ex) == 1 && jl_is_expr(jl_exprarg(ex, 0))) { jl_expr_t *fr = (jl_expr_t*)jl_exprarg(ex, 0); @@ -582,7 +587,7 @@ static jl_module_t *eval_import_from(jl_module_t *m, jl_expr_t *ex, const char * return NULL; } -jl_value_t *jl_toplevel_eval_flex(jl_module_t *m, jl_value_t *e, int fast, int expanded) +jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_value_t *e, int fast, int expanded) { jl_ptls_t ptls = jl_get_ptls_states(); if (!jl_is_expr(e)) { From 2caef761fea9804451efcf9c859fa5565284e7d5 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 19 Aug 2018 22:04:19 -0400 Subject: [PATCH 081/110] Make a bunch of progress on anntations for typemap.c --- src/julia.h | 9 ++++++++- src/typemap.c | 18 +++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/julia.h b/src/julia.h index cef517bc8b9b5..58871b8533418 100644 --- a/src/julia.h +++ b/src/julia.h @@ -747,6 +747,12 @@ JL_DLLEXPORT void *jl_gc_managed_realloc(void *d, size_t sz, size_t oldsz, #define jl_svec_set_len_unsafe(t,n) (((jl_svec_t*)(t))->length=(n)) #define jl_svec_data(t) ((jl_value_t**)((char*)(t) + sizeof(jl_svec_t))) +#ifdef __clang_analyzer__ +STATIC_INLINE jl_value_t *jl_svecref(void *t JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; +STATIC_INLINE jl_value_t *jl_svecset( + void *t JL_ROOTING_ARGUMENT JL_PROPAGATES_ROOT, + size_t i, void *x JL_ROOTED_ARGUMENT) JL_NOTSAFEPOINT; +#else STATIC_INLINE jl_value_t *jl_svecref(void *t JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT { assert(jl_typeis(t,jl_simplevector_type)); @@ -763,6 +769,7 @@ STATIC_INLINE jl_value_t *jl_svecset( if (x) jl_gc_wb(t, x); return (jl_value_t*)x; } +#endif #ifdef STORE_ARRAY_LEN #define jl_array_len(a) (((jl_array_t*)(a))->length) @@ -1245,7 +1252,7 @@ STATIC_INLINE jl_vararg_kind_t jl_vararg_kind(jl_value_t *v) JL_NOTSAFEPOINT return JL_VARARG_UNBOUND; } -STATIC_INLINE int jl_is_va_tuple(jl_datatype_t *t) +STATIC_INLINE int jl_is_va_tuple(jl_datatype_t *t) JL_NOTSAFEPOINT { assert(jl_is_tuple_type(t)); size_t l = jl_svec_len(t->parameters); diff --git a/src/typemap.c b/src/typemap.c index 03f9ec7564c58..5d0a28641bfb6 100644 --- a/src/typemap.c +++ b/src/typemap.c @@ -177,7 +177,7 @@ static inline int sig_match_simple(jl_value_t **args, size_t n, jl_value_t **sig // ----- MethodCache helper functions ----- // -static inline size_t jl_intref(const jl_array_t *arr, size_t idx) +static inline size_t jl_intref(const jl_array_t *arr, size_t idx) JL_NOTSAFEPOINT { jl_value_t *el = jl_tparam0(jl_typeof(arr)); if (el == (jl_value_t*)jl_uint8_type) @@ -190,7 +190,7 @@ static inline size_t jl_intref(const jl_array_t *arr, size_t idx) abort(); } -static inline void jl_intset(const jl_array_t *arr, size_t idx, size_t val) +static inline void jl_intset(const jl_array_t *arr, size_t idx, size_t val) JL_NOTSAFEPOINT { jl_value_t *el = jl_tparam0(jl_typeof(arr)); if (el == (jl_value_t*)jl_uint8_type) @@ -224,14 +224,14 @@ static jl_array_t *jl_alloc_int_1d(size_t np, size_t len) ty = jl_array_uint8_type; } else if (np < 0xFFFF) { - static jl_value_t *int16 = NULL; + static jl_value_t *int16 JL_ALWAYS_LEAFTYPE = NULL; if (int16 == NULL) int16 = jl_apply_array_type((jl_value_t*)jl_uint16_type, 1); ty = int16; } else { assert(np < 0x7FFFFFFF); - static jl_value_t *int32 = NULL; + static jl_value_t *int32 JL_ALWAYS_LEAFTYPE = NULL; if (int32 == NULL) int32 = jl_apply_array_type((jl_value_t*)jl_uint32_type, 1); ty = int32; @@ -242,7 +242,7 @@ static jl_array_t *jl_alloc_int_1d(size_t np, size_t len) } static inline -union jl_typemap_t mtcache_hash_lookup(const struct jl_ordereddict_t *a, jl_value_t *ty, int8_t tparam, int8_t offs) +union jl_typemap_t mtcache_hash_lookup(const struct jl_ordereddict_t *a JL_PROPAGATES_ROOT, jl_value_t *ty, int8_t tparam, int8_t offs) JL_NOTSAFEPOINT { uintptr_t uid = ((jl_datatype_t*)ty)->uid; union jl_typemap_t ml; @@ -328,7 +328,7 @@ void jl_typemap_rehash(union jl_typemap_t ml, int8_t offs) { } } -static union jl_typemap_t *mtcache_hash_bp(struct jl_ordereddict_t *pa, jl_value_t *ty, +static union jl_typemap_t *mtcache_hash_bp(struct jl_ordereddict_t *pa JL_PROPAGATES_ROOT, jl_value_t *ty, int8_t tparam, int8_t offs, jl_value_t *parent) { if (jl_is_datatype(ty)) { @@ -380,7 +380,7 @@ static union jl_typemap_t *mtcache_hash_bp(struct jl_ordereddict_t *pa, jl_value static int jl_typemap_array_visitor(struct jl_ordereddict_t *a, jl_typemap_visitor_fptr fptr, void *closure) { size_t i, l = jl_array_len(a->values); - union jl_typemap_t *data = (union jl_typemap_t*)jl_array_data(a->values); + union jl_typemap_t *data = (union jl_typemap_t*)jl_array_ptr_data(a->values); for(i=0; i < l; i++) { if (!jl_typemap_visitor(data[i], fptr, closure)) return 0; @@ -428,7 +428,7 @@ static int jl_typemap_intersection_array_visitor(struct jl_ordereddict_t *a, jl_ int offs, struct typemap_intersection_env *closure) { size_t i, l = jl_array_len(a->values); - union jl_typemap_t *data = (union jl_typemap_t*)jl_array_data(a->values); + union jl_typemap_t *data = (union jl_typemap_t*)jl_array_ptr_data(a->values); for (i = 0; i < l; i++) { union jl_typemap_t ml = data[i]; if (ml.unknown == jl_nothing) @@ -846,7 +846,7 @@ jl_typemap_entry_t *jl_typemap_level_assoc_exact(jl_typemap_level_t *cache, jl_v // ----- Method List Insertion Management ----- // -static unsigned jl_typemap_list_count(jl_typemap_entry_t *ml) +static unsigned jl_typemap_list_count(jl_typemap_entry_t *ml) JL_NOTSAFEPOINT { unsigned count = 0; while (ml != (void*)jl_nothing) { From 81b04cf170b2d6bb82bacb1f6e77f8dd07974663 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 19 Aug 2018 22:15:10 -0400 Subject: [PATCH 082/110] Some more work on gf.c --- src/gf.c | 3 ++- src/julia_internal.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gf.c b/src/gf.c index a7b442732c486..46d8878c9d776 100644 --- a/src/gf.c +++ b/src/gf.c @@ -1413,7 +1413,7 @@ static int invalidate_backedges(jl_typemap_entry_t *oldentry, struct typemap_int jl_array_t *backedges = def.replaced->backedges; if (backedges) { size_t i, l = jl_array_len(backedges); - jl_method_instance_t **replaced = (jl_method_instance_t**)jl_array_data(backedges); + jl_method_instance_t **replaced = (jl_method_instance_t**)jl_array_ptr_data(backedges); for (i = 0; i < l; i++) { invalidate_method_instance(replaced[i], closure->max_world, 0); } @@ -1921,6 +1921,7 @@ JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types) { size_t world = jl_world_counter; jl_method_instance_t *li = jl_get_specialization1(types, world, 1); + JL_GC_PROMISE_ROOTED(li); // Rooted via types since mt_cache==1 if (li == NULL) return 0; if (jl_generating_output()) { diff --git a/src/julia_internal.h b/src/julia_internal.h index eb57bb5bbe723..d1b767ec99e7d 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -332,7 +332,7 @@ jl_llvm_functions_t jl_compile_linfo( jl_callptr_t jl_compile_method_internal(jl_method_instance_t **pmeth, size_t world); JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types); jl_code_info_t *jl_code_for_interpreter(jl_method_instance_t *lam); -int jl_code_requires_compiler(jl_code_info_t *src); +int jl_code_requires_compiler(jl_code_info_t *src) JL_NOTSAFEPOINT; jl_code_info_t *jl_new_code_info_from_ast(jl_expr_t *ast); JL_DLLEXPORT jl_code_info_t *jl_new_code_info_uninit(void); From 81850b6eaa7cc079005db752d1e381f7fb654196 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Wed, 22 Aug 2018 12:10:22 +0200 Subject: [PATCH 083/110] improve performance of parse (#28787) --- base/parse.jl | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/base/parse.jl b/base/parse.jl index d0037ca6a6574..50b76e0577eb1 100644 --- a/base/parse.jl +++ b/base/parse.jl @@ -106,14 +106,21 @@ function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos:: return nothing end - base = convert(T,base) - m::T = div(typemax(T)-base+1,base) + base = convert(T, base) + m::T = div(typemax(T) - base + 1, base) n::T = 0 a::Int = base <= 36 ? 10 : 36 + _0 = UInt32('0') + _9 = UInt32('9') + _A = UInt32('A') + _a = UInt32('a') + _Z = UInt32('Z') + _z = UInt32('z') while n <= m - d::T = '0' <= c <= '9' ? c-'0' : - 'A' <= c <= 'Z' ? c-'A'+10 : - 'a' <= c <= 'z' ? c-'a'+a : base + _c = UInt32(c) + d::T = _0 <= _c <= _9 ? _c-_0 : + _A <= _c <= _Z ? _c-_A+ UInt32(10) : + _a <= _c <= _z ? _c-_a+a : base if d >= base raise && throw(ArgumentError("invalid base $base digit $(repr(c)) in $(repr(SubString(s,startpos,endpos)))")) return nothing @@ -129,9 +136,10 @@ function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos:: end (T <: Signed) && (n *= sgn) while !isspace(c) - d::T = '0' <= c <= '9' ? c-'0' : - 'A' <= c <= 'Z' ? c-'A'+10 : - 'a' <= c <= 'z' ? c-'a'+a : base + _c = UInt32(c) + d::T = _0 <= _c <= _9 ? _c-_0 : + _A <= _c <= _Z ? _c-_A+ UInt32(10) : + _a <= _c <= _z ? _c-_a+a : base if d >= base raise && throw(ArgumentError("invalid base $base digit $(repr(c)) in $(repr(SubString(s,startpos,endpos)))")) return nothing From f2f1f4322f05a874eab24e308f28c5e1d2bf7eb6 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Tue, 21 Aug 2018 14:30:04 -0400 Subject: [PATCH 084/110] Switch jl_typemap_t from unions to bare pointers The clang static analyzer has very poor support for unions. Thus in an attempt to get the GC analysis through without any false positives, stop using unions for typemaps. This commit should have no changes other than that. GC annotations for this code will come after I rip out the hacks to support unions from the static analyzer. --- src/builtins.c | 2 +- src/codegen.cpp | 19 +++-- src/datatype.c | 4 +- src/dump.c | 19 +++-- src/gf.c | 34 ++++----- src/julia.h | 26 ++++--- src/julia_internal.h | 20 ++--- src/method.c | 4 +- src/module.c | 2 +- src/staticdata.c | 2 +- src/typemap.c | 176 ++++++++++++++++++++++--------------------- 11 files changed, 157 insertions(+), 151 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index e98ac120b4ce5..8428a55b6dd71 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1175,7 +1175,7 @@ static void add_builtin(const char *name, jl_value_t *v) jl_fptr_args_t jl_get_builtin_fptr(jl_value_t *b) { assert(jl_isa(b, (jl_value_t*)jl_builtin_type)); - return jl_gf_mtable(b)->cache.leaf->func.linfo->specptr.fptr1; + return ((jl_typemap_entry_t*)jl_gf_mtable(b)->cache)->func.linfo->specptr.fptr1; } static void add_builtin_func(const char *name, jl_fptr_args_t fptr) diff --git a/src/codegen.cpp b/src/codegen.cpp index 4d00a02d96a11..1b4e5938fba91 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4861,15 +4861,14 @@ static Function *jl_cfunction_object(jl_value_t *ff, jl_value_t *declrt, jl_tupl // first split on `ft` using a simple eqtable // then use the typemap to split on argt // and finally, pick declrt from the pair-list - union jl_typemap_t cache_l2 = { NULL }; - // cache_l2.unknown = NULL; + jl_typemap_t *cache_l2 = NULL; jl_typemap_entry_t *cache_l3 = NULL; if (!jl_cfunction_list) { jl_cfunction_list = jl_alloc_vec_any(16); } else { - cache_l2.unknown = jl_eqtable_get(jl_cfunction_list, ft, NULL); - if (cache_l2.unknown) { + cache_l2 = jl_eqtable_get(jl_cfunction_list, ft, NULL); + if (cache_l2) { cache_l3 = jl_typemap_assoc_by_type(cache_l2, (jl_value_t*)argt, NULL, /*subtype*/0, /*offs*/0, /*world*/1, /*max_world_mask*/0); if (cache_l3) { @@ -4886,13 +4885,13 @@ static Function *jl_cfunction_object(jl_value_t *ff, jl_value_t *declrt, jl_tupl } if (cache_l3 == NULL) { - union jl_typemap_t insert = cache_l2; - if (!insert.unknown) - insert.unknown = jl_nothing; - cache_l3 = jl_typemap_insert(&insert, (jl_value_t*)insert.unknown, (jl_tupletype_t*)argt, + jl_typemap_t *insert = cache_l2; + if (!insert) + insert = jl_nothing; + cache_l3 = jl_typemap_insert(&insert, (jl_value_t*)insert, (jl_tupletype_t*)argt, NULL, jl_emptysvec, (jl_value_t*)jl_emptysvec, /*offs*/0, &cfunction_cache, 1, ~(size_t)0, NULL); - if (insert.unknown != cache_l2.unknown) - jl_cfunction_list = jl_eqtable_put(jl_cfunction_list, ft, insert.unknown, NULL); + if (insert != cache_l2) + jl_cfunction_list = jl_eqtable_put(jl_cfunction_list, ft, insert, NULL); } // compute / validate return type diff --git a/src/datatype.c b/src/datatype.c index c4d3fcc2a2da3..b26c48443b96b 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -40,8 +40,8 @@ JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *mo jl_methtable_type); mt->name = jl_demangle_typename(name); mt->module = module; - mt->defs.unknown = jl_nothing; - mt->cache.unknown = jl_nothing; + mt->defs = jl_nothing; + mt->cache = jl_nothing; mt->max_args = 0; mt->kwsorter = NULL; mt->backedges = NULL; diff --git a/src/dump.c b/src/dump.c index 17d72a5ab86be..0820a7542557c 100644 --- a/src/dump.c +++ b/src/dump.c @@ -580,7 +580,7 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li arraylist_push(&reinit_list, (void*)pos); arraylist_push(&reinit_list, (void*)3); } - if (jl_is_method(v) && jl_typeof(((jl_method_t*)v)->specializations.unknown) == (jl_value_t*)jl_typemap_level_type) { + if (jl_is_method(v) && jl_typeof(((jl_method_t*)v)->specializations) == (jl_value_t*)jl_typemap_level_type) { arraylist_push(&reinit_list, (void*)pos); arraylist_push(&reinit_list, (void*)4); } @@ -781,8 +781,7 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li jl_datatype_t *gf = jl_first_argument_datatype((jl_value_t*)m->sig); assert(jl_is_datatype(gf) && gf->name->mt); external_mt = !module_in_worklist(gf->name->mt->module); - union jl_typemap_t *tf = &m->specializations; - jl_serialize_value(s, tf->unknown); + jl_serialize_value(s, m->specializations); jl_serialize_value(s, (jl_value_t*)m->name); jl_serialize_value(s, (jl_value_t*)m->file); write_int32(s->s, m->line); @@ -801,7 +800,7 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li jl_serialize_value(s, (jl_value_t*)m->source); jl_serialize_value(s, (jl_value_t*)m->unspecialized); jl_serialize_value(s, (jl_value_t*)m->generator); - jl_serialize_value(s, (jl_value_t*)m->invokes.unknown); + jl_serialize_value(s, (jl_value_t*)m->invokes); } else if (jl_is_method_instance(v)) { write_uint8(s->s, TAG_METHOD_INSTANCE); @@ -999,7 +998,7 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li jl_serialize_value(s, jl_nothing); jl_serialize_value(s, node->targ.values); jl_serialize_value(s, node->linear); - jl_serialize_value(s, node->any.unknown); + jl_serialize_value(s, node->any); jl_serialize_value(s, node->key); return; } @@ -1638,8 +1637,8 @@ static jl_value_t *jl_deserialize_value_method(jl_serializer_state *s, jl_value_ arraylist_push(&flagref_list, (void*)pos); return (jl_value_t*)m; } - m->specializations.unknown = jl_deserialize_value(s, (jl_value_t**)&m->specializations); - jl_gc_wb(m, m->specializations.unknown); + m->specializations = jl_deserialize_value(s, (jl_value_t**)&m->specializations); + jl_gc_wb(m, m->specializations); m->name = (jl_sym_t*)jl_deserialize_value(s, NULL); jl_gc_wb(m, m->name); m->file = (jl_sym_t*)jl_deserialize_value(s, NULL); @@ -1668,8 +1667,8 @@ static jl_value_t *jl_deserialize_value_method(jl_serializer_state *s, jl_value_ m->generator = jl_deserialize_value(s, (jl_value_t**)&m->generator); if (m->generator) jl_gc_wb(m, m->generator); - m->invokes.unknown = jl_deserialize_value(s, (jl_value_t**)&m->invokes); - jl_gc_wb(m, m->invokes.unknown); + m->invokes = jl_deserialize_value(s, (jl_value_t**)&m->invokes); + jl_gc_wb(m, m->invokes); m->traced = 0; JL_MUTEX_INIT(&m->writelock); return (jl_value_t*)m; @@ -2330,7 +2329,7 @@ static void jl_finalize_serializer(jl_serializer_state *s) write_int32(s->s, -1); } -void jl_typemap_rehash(union jl_typemap_t ml, int8_t offs); +void jl_typemap_rehash(jl_typemap_t *ml, int8_t offs); static void jl_reinit_item(jl_value_t *v, int how, arraylist_t *tracee_list) { jl_ptls_t ptls = jl_get_ptls_states(); diff --git a/src/gf.c b/src/gf.c index 46d8878c9d776..b7f5f4ce2198e 100644 --- a/src/gf.c +++ b/src/gf.c @@ -333,7 +333,7 @@ static void update_world_bound(jl_method_instance_t *replaced, jl_typemap_visito // update the world-valid in the specializations caches jl_typemap_visitor(m->specializations, fptr, (void*)&update); // update the world-valid in the invoke cache - if (m->invokes.unknown != NULL) + if (m->invokes != NULL) jl_typemap_visitor(m->invokes, fptr, (void*)&update); // update the world-valid in the gf cache jl_datatype_t *gf = jl_first_argument_datatype((jl_value_t*)m->sig); @@ -510,8 +510,8 @@ void jl_foreach_reachable_mtable(void (*visit)(jl_methtable_t *mt, void *env), v static void reset_mt_caches(jl_methtable_t *mt, void *env) { // removes all method caches - if (mt->defs.unknown != jl_nothing) // make sure not to reset builtin functions - mt->cache.unknown = jl_nothing; + if (mt->defs != jl_nothing) // make sure not to reset builtin functions + mt->cache = jl_nothing; jl_typemap_visitor(mt->defs, get_method_unspec_list, env); } @@ -576,7 +576,7 @@ jl_value_t *jl_nth_slot_type(jl_value_t *sig, size_t i) // return 1; //} -static jl_value_t *ml_matches(union jl_typemap_t ml, int offs, +static jl_value_t *ml_matches(jl_typemap_t *ml, int offs, jl_tupletype_t *type, int lim, int include_ambiguous, size_t world, size_t *min_valid, size_t *max_valid); @@ -921,7 +921,7 @@ JL_DLLEXPORT int jl_isa_compileable_sig( } static jl_method_instance_t *cache_method( - jl_methtable_t *mt, union jl_typemap_t *cache, jl_value_t *parent JL_PROPAGATES_ROOT, + jl_methtable_t *mt, jl_typemap_t **cache, jl_value_t *parent JL_PROPAGATES_ROOT, jl_tupletype_t *tt, // the original tupletype of the signature jl_method_t *definition, size_t world, @@ -1152,7 +1152,7 @@ void print_func_loc(JL_STREAM *s, jl_method_t *m) */ struct ambiguous_matches_env { struct typemap_intersection_env match; - union jl_typemap_t defs; + jl_typemap_t *defs; jl_typemap_entry_t *newentry; jl_value_t *shadowed; int after; @@ -1167,7 +1167,7 @@ static int check_ambiguous_visitor(jl_typemap_entry_t *oldentry, struct typemap_ } if (oldentry->max_world < ~(size_t)0) return 1; - union jl_typemap_t map = closure->defs; + jl_typemap_t *map = closure->defs; jl_tupletype_t *type = (jl_tupletype_t*)closure->match.type; jl_method_t *m = closure->newentry->func.method; jl_tupletype_t *sig = oldentry->sig; @@ -1248,7 +1248,7 @@ static int check_ambiguous_visitor(jl_typemap_entry_t *oldentry, struct typemap_ return 1; } -static jl_value_t *check_ambiguous_matches(union jl_typemap_t defs, jl_typemap_entry_t *newentry, jl_typemap_intersection_visitor_fptr fptr) +static jl_value_t *check_ambiguous_matches(jl_typemap_t *defs, jl_typemap_entry_t *newentry, jl_typemap_intersection_visitor_fptr fptr) { jl_tupletype_t *type = newentry->sig; jl_tupletype_t *ttypes = (jl_tupletype_t*)jl_unwrap_unionall((jl_value_t*)type); @@ -1401,7 +1401,7 @@ static int invalidate_backedges(jl_typemap_entry_t *oldentry, struct typemap_int jl_method_t *m = def.replaced->def.method; // truncate the max-valid in the invoke cache - if (m->invokes.unknown != NULL) + if (m->invokes != NULL) jl_typemap_visitor(m->invokes, set_max_world2, (void*)&def); // invalidate mt cache entries jl_datatype_t *gf = jl_first_argument_datatype((jl_value_t*)m->sig); @@ -2231,7 +2231,7 @@ jl_value_t *jl_gf_invoke(jl_value_t *types0, jl_value_t **args, size_t nargs) jl_method_t *method = entry->func.method; jl_method_instance_t *mfunc = NULL; jl_typemap_entry_t *tm = NULL; - if (method->invokes.unknown != NULL) + if (method->invokes != NULL) tm = jl_typemap_assoc_exact(method->invokes, args, nargs, jl_cachearg_offset(mt), world); if (tm) { mfunc = tm->func.linfo; @@ -2244,8 +2244,8 @@ jl_value_t *jl_gf_invoke(jl_value_t *types0, jl_value_t **args, size_t nargs) assert(sub); (void)sub; } - if (method->invokes.unknown == NULL) - method->invokes.unknown = jl_nothing; + if (method->invokes == NULL) + method->invokes = jl_nothing; mfunc = cache_method(mt, &method->invokes, entry->func.value, tt, method, world, tpenv, 1); JL_UNLOCK(&method->writelock); @@ -2265,7 +2265,7 @@ JL_DLLEXPORT jl_value_t *jl_get_invoke_lambda(jl_methtable_t *mt, jl_method_t *method = entry->func.method; jl_typemap_entry_t *tm = NULL; - if (method->invokes.unknown != NULL) { + if (method->invokes != NULL) { tm = jl_typemap_assoc_by_type(method->invokes, tt, NULL, /*subtype*/1, jl_cachearg_offset(mt), world, /*max_world_mask*/0); if (tm) { @@ -2274,7 +2274,7 @@ JL_DLLEXPORT jl_value_t *jl_get_invoke_lambda(jl_methtable_t *mt, } JL_LOCK(&method->writelock); - if (method->invokes.unknown != NULL) { + if (method->invokes != NULL) { tm = jl_typemap_assoc_by_type(method->invokes, tt, NULL, /*subtype*/1, jl_cachearg_offset(mt), world, /*max_world_mask*/0); if (tm) { @@ -2292,8 +2292,8 @@ JL_DLLEXPORT jl_value_t *jl_get_invoke_lambda(jl_methtable_t *mt, (void)ti; } - if (method->invokes.unknown == NULL) - method->invokes.unknown = jl_nothing; + if (method->invokes == NULL) + method->invokes = jl_nothing; jl_method_instance_t *mfunc = cache_method(mt, &method->invokes, entry->func.value, (jl_tupletype_t*)tt, method, world, tpenv, 1); @@ -2488,7 +2488,7 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio // // Returns a match as an array of svec(argtypes, static_params, Method). // See below for the meaning of lim. -static jl_value_t *ml_matches(union jl_typemap_t defs, int offs, +static jl_value_t *ml_matches(jl_typemap_t *defs, int offs, jl_tupletype_t *type, int lim, int include_ambiguous, size_t world, size_t *min_valid, size_t *max_valid) { diff --git a/src/julia.h b/src/julia.h index 58871b8533418..8e518b6c429f6 100644 --- a/src/julia.h +++ b/src/julia.h @@ -195,11 +195,7 @@ struct _jl_method_instance_t; // when key is a leaftype, (but only when the tree has enough entries for this to be // more efficient than storing them sorted linearly) // otherwise the leaf entries are stored sorted, linearly -union jl_typemap_t { - struct _jl_typemap_level_t *node; - struct _jl_typemap_entry_t *leaf; - struct _jl_value_t *unknown; // nothing -}; +typedef jl_value_t jl_typemap_t; typedef jl_value_t *(jl_call_t)(struct _jl_method_instance_t*, jl_value_t**, uint32_t); typedef jl_call_t *jl_callptr_t; @@ -269,7 +265,7 @@ typedef struct _jl_method_t { jl_value_t *ambig; // table of all argument types for which we've inferred or compiled this code - union jl_typemap_t specializations; + jl_typemap_t *specializations; jl_svec_t *sparam_syms; // symbols giving static parameter names jl_value_t *source; // original code template (jl_code_info_t, but may be compressed), null for builtins @@ -280,7 +276,7 @@ typedef struct _jl_method_t { // cache of specializations of this method for invoke(), i.e. // cases where this method was called even though it was not necessarily // the most specific for the argument types. - union jl_typemap_t invokes; + jl_typemap_t *invokes; int32_t nargs; int32_t called; // bit flags: whether each of the first 8 arguments is called @@ -478,14 +474,14 @@ typedef struct _jl_typemap_entry_t { // indexed by key if it is a sublevel in an array struct jl_ordereddict_t { jl_array_t *indices; // Array{Int{8,16,32}} - jl_array_t *values; // Array{union jl_typemap_t} + jl_array_t *values; // Array{jl_typemap_t*} }; typedef struct _jl_typemap_level_t { JL_DATA_TYPE struct jl_ordereddict_t arg1; struct jl_ordereddict_t targ; - jl_typemap_entry_t *linear; // union jl_typemap_t (but no more levels) - union jl_typemap_t any; // type at offs is Any + jl_typemap_entry_t *linear; // jl_typemap_t * (but no more levels) + jl_typemap_t *any; // type at offs is Any jl_value_t *key; // [nullable] } jl_typemap_level_t; @@ -493,8 +489,8 @@ typedef struct _jl_typemap_level_t { typedef struct _jl_methtable_t { JL_DATA_TYPE jl_sym_t *name; - union jl_typemap_t defs; - union jl_typemap_t cache; + jl_typemap_t *defs; + jl_typemap_t *cache; intptr_t max_args; // max # of non-vararg arguments in a signature jl_value_t *kwsorter; // keyword argument sorter function jl_module_t *module; // used for incremental serialization to locate original binding @@ -1107,6 +1103,12 @@ STATIC_INLINE int jl_is_concrete_type(jl_value_t *v) JL_NOTSAFEPOINT return jl_is_datatype(v) && ((jl_datatype_t*)v)->isconcretetype; } +STATIC_INLINE jl_value_t *jl_typemap_entry_sig(jl_typemap_t *tmap) JL_NOTSAFEPOINT +{ + assert(jl_typeof(tmap) == (jl_value_t*)jl_typemap_entry_type); + return (jl_value_t*)((jl_typemap_entry_t*)tmap)->sig; +} + // type constructors JL_DLLEXPORT jl_typename_t *jl_new_typename_in(jl_sym_t *name, jl_module_t *inmodule); JL_DLLEXPORT jl_tvar_t *jl_new_typevar(jl_sym_t *name, jl_value_t *lb, jl_value_t *ub); diff --git a/src/julia_internal.h b/src/julia_internal.h index d1b767ec99e7d..2c084703f9b0d 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -860,7 +860,7 @@ struct jl_typemap_info { jl_datatype_t **jl_contains; // the type that is being put in this }; -jl_typemap_entry_t *jl_typemap_insert(union jl_typemap_t *cache, +jl_typemap_entry_t *jl_typemap_insert(jl_typemap_t **cache, jl_value_t *parent JL_PROPAGATES_ROOT, jl_tupletype_t *type, jl_tupletype_t *simpletype, jl_svec_t *guardsigs, @@ -870,27 +870,29 @@ jl_typemap_entry_t *jl_typemap_insert(union jl_typemap_t *cache, jl_value_t **overwritten); jl_typemap_entry_t *jl_typemap_assoc_by_type( - union jl_typemap_t ml_or_cache JL_PROPAGATES_ROOT, + jl_typemap_t *ml_or_cache JL_PROPAGATES_ROOT, jl_value_t *types, jl_svec_t **penv, int8_t subtype, int8_t offs, size_t world, size_t max_world_mask); jl_typemap_entry_t *jl_typemap_level_assoc_exact(jl_typemap_level_t *cache, jl_value_t **args, size_t n, int8_t offs, size_t world); jl_typemap_entry_t *jl_typemap_entry_assoc_exact(jl_typemap_entry_t *mn, jl_value_t **args, size_t n, size_t world); STATIC_INLINE jl_typemap_entry_t *jl_typemap_assoc_exact( - union jl_typemap_t ml_or_cache JL_PROPAGATES_ROOT, + jl_typemap_t *ml_or_cache JL_PROPAGATES_ROOT, jl_value_t **args, size_t n, int8_t offs, size_t world) { // NOTE: This function is a huge performance hot spot!! - if (jl_typeof(ml_or_cache.unknown) == (jl_value_t*)jl_typemap_entry_type) { - return jl_typemap_entry_assoc_exact(ml_or_cache.leaf, args, n, world); + if (jl_typeof(ml_or_cache) == (jl_value_t *)jl_typemap_entry_type) { + return jl_typemap_entry_assoc_exact( + (jl_typemap_entry_t *)ml_or_cache, args, n, world); } - else if (jl_typeof(ml_or_cache.unknown) == (jl_value_t*)jl_typemap_level_type) { - return jl_typemap_level_assoc_exact(ml_or_cache.node, args, n, offs, world); + else if (jl_typeof(ml_or_cache) == (jl_value_t*)jl_typemap_level_type) { + return jl_typemap_level_assoc_exact( + (jl_typemap_level_t *)ml_or_cache, args, n, offs, world); } return NULL; } typedef int (*jl_typemap_visitor_fptr)(jl_typemap_entry_t *l, void *closure); -int jl_typemap_visitor(union jl_typemap_t a, jl_typemap_visitor_fptr fptr, void *closure); +int jl_typemap_visitor(jl_typemap_t *a, jl_typemap_visitor_fptr fptr, void *closure); struct typemap_intersection_env; typedef int (*jl_typemap_intersection_visitor_fptr)(jl_typemap_entry_t *l, struct typemap_intersection_env *closure); @@ -904,7 +906,7 @@ struct typemap_intersection_env { jl_svec_t *env; // intersection env (initialize to null to perform intersection without an environment) int issubty; // if `a <: b` is true in `intersect(a,b)` }; -int jl_typemap_intersection_visitor(union jl_typemap_t a, int offs, struct typemap_intersection_env *closure); +int jl_typemap_intersection_visitor(jl_typemap_t *a, int offs, struct typemap_intersection_env *closure); unsigned jl_special_vector_alignment(size_t nfields, jl_value_t *field_type); diff --git a/src/method.c b/src/method.c index 4acae10b713f1..4365def7f3d11 100644 --- a/src/method.c +++ b/src/method.c @@ -576,7 +576,7 @@ JL_DLLEXPORT jl_method_t *jl_new_method_uninit(jl_module_t *module) jl_ptls_t ptls = jl_get_ptls_states(); jl_method_t *m = (jl_method_t*)jl_gc_alloc(ptls, sizeof(jl_method_t), jl_method_type); - m->specializations.unknown = jl_nothing; + m->specializations = jl_nothing; m->sig = NULL; m->sparam_syms = NULL; m->ambig = jl_nothing; @@ -590,7 +590,7 @@ JL_DLLEXPORT jl_method_t *jl_new_method_uninit(jl_module_t *module) m->line = 0; m->called = 0xff; m->nospecialize = module->nospecialize; - m->invokes.unknown = NULL; + m->invokes = NULL; m->isva = 0; m->nargs = 0; m->traced = 0; diff --git a/src/module.c b/src/module.c index a0f75bffc4345..b393543668cf3 100644 --- a/src/module.c +++ b/src/module.c @@ -588,7 +588,7 @@ void jl_binding_deprecation_warning(jl_module_t *m, jl_binding_t *b) } else { jl_methtable_t *mt = jl_gf_mtable(v); - if (mt != NULL && (mt->defs.unknown != jl_nothing || + if (mt != NULL && (mt->defs != jl_nothing || jl_isa(v, (jl_value_t*)jl_builtin_type))) { jl_printf(JL_STDERR, ", use "); if (mt->module != jl_core_module) { diff --git a/src/staticdata.c b/src/staticdata.c index 0f1aa9d1356ae..eb9d6c81cf1f6 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -1094,7 +1094,7 @@ static void jl_finalize_serializer(jl_serializer_state *s) } -void jl_typemap_rehash(union jl_typemap_t ml, int8_t offs); +void jl_typemap_rehash(jl_typemap_t *ml, int8_t offs); static void jl_reinit_item(jl_value_t *v, int how, arraylist_t *tracee_list) { jl_ptls_t ptls = jl_get_ptls_states(); diff --git a/src/typemap.c b/src/typemap.c index 5d0a28641bfb6..13abae4c31f5a 100644 --- a/src/typemap.c +++ b/src/typemap.c @@ -242,30 +242,28 @@ static jl_array_t *jl_alloc_int_1d(size_t np, size_t len) } static inline -union jl_typemap_t mtcache_hash_lookup(const struct jl_ordereddict_t *a JL_PROPAGATES_ROOT, jl_value_t *ty, int8_t tparam, int8_t offs) JL_NOTSAFEPOINT +jl_typemap_t *mtcache_hash_lookup(const struct jl_ordereddict_t *a JL_PROPAGATES_ROOT, jl_value_t *ty, int8_t tparam, int8_t offs) { uintptr_t uid = ((jl_datatype_t*)ty)->uid; - union jl_typemap_t ml; - ml.unknown = jl_nothing; + jl_typemap_t *ml = jl_nothing; if (!uid) return ml; size_t idx = jl_intref(a->indices, uid & (a->indices->nrows-1)); if (idx > 0) { - ml.unknown = jl_array_ptr_ref(a->values, idx - 1); - if (ml.unknown == jl_nothing) + ml = jl_array_ptr_ref(a->values, idx - 1); + if (ml == jl_nothing) return ml; jl_value_t *t; - if (jl_typeof(ml.unknown) == (jl_value_t*)jl_typemap_level_type) { - t = ml.node->key; + if (jl_typeof(ml) == (jl_value_t*)jl_typemap_level_type) { + t = ((jl_typemap_level_t*)ml)->key; } else { - assert(jl_typeof(ml.unknown) == (jl_value_t*)jl_typemap_entry_type); - t = jl_field_type(jl_unwrap_unionall((jl_value_t*)ml.leaf->sig), offs); + t = jl_field_type(jl_unwrap_unionall(jl_typemap_entry_sig(ml)), offs); if (tparam) t = jl_tparam0(t); } if (t != ty) - ml.unknown = jl_nothing; + ml = jl_nothing; } return ml; } @@ -275,17 +273,15 @@ static void mtcache_rehash(struct jl_ordereddict_t *pa, size_t newlen, jl_value_ size_t i, nval = jl_array_len(pa->values); jl_array_t *n = jl_alloc_int_1d(nval + 1, newlen); for (i = 1; i <= nval; i++) { - union jl_typemap_t ml; - ml.unknown = jl_array_ptr_ref(pa->values, i - 1); - if (ml.unknown == jl_nothing) + jl_typemap_t *ml = jl_array_ptr_ref(pa->values, i - 1); + if (ml == jl_nothing) continue; jl_value_t *t; - if (jl_typeof(ml.unknown) == (jl_value_t*)jl_typemap_level_type) { - t = ml.node->key; + if (jl_typeof(ml) == (jl_value_t*)jl_typemap_level_type) { + t = ((jl_typemap_level_t*)ml)->key; } else { - assert(jl_typeof(ml.unknown) == (jl_value_t*)jl_typemap_entry_type); - t = jl_field_type(jl_unwrap_unionall((jl_value_t*)ml.leaf->sig), offs); + t = jl_field_type(jl_unwrap_unionall(jl_typemap_entry_sig(ml)), offs); if (tparam) t = jl_tparam0(t); } @@ -306,30 +302,31 @@ static void mtcache_rehash(struct jl_ordereddict_t *pa, size_t newlen, jl_value_ } // Recursively rehash a TypeMap (for example, after deserialization) -void jl_typemap_rehash(union jl_typemap_t ml, int8_t offs); +void jl_typemap_rehash(jl_typemap_t *ml, int8_t offs); void jl_typemap_rehash_array(struct jl_ordereddict_t *pa, jl_value_t *parent, int8_t tparam, int8_t offs) { size_t i, len = jl_array_len(pa->values); for (i = 0; i < len; i++) { - union jl_typemap_t ml; - ml.unknown = jl_array_ptr_ref(pa->values, i); - assert(ml.unknown != NULL); + jl_typemap_t *ml = jl_array_ptr_ref(pa->values, i); + assert(ml != NULL); jl_typemap_rehash(ml, offs+1); } mtcache_rehash(pa, 4 * next_power_of_two(len), parent, tparam, offs); } -void jl_typemap_rehash(union jl_typemap_t ml, int8_t offs) { - if (jl_typeof(ml.unknown) == (jl_value_t*)jl_typemap_level_type) { - if (ml.node->targ.values != (void*)jl_nothing) - jl_typemap_rehash_array(&ml.node->targ, ml.unknown, 1, offs); - if (ml.node->arg1.values != (void*)jl_nothing) - jl_typemap_rehash_array(&ml.node->arg1, ml.unknown, 0, offs); - jl_typemap_rehash(ml.node->any, offs+1); +void jl_typemap_rehash(jl_typemap_t *ml, int8_t offs) +{ + if (jl_typeof(ml) == (jl_value_t*)jl_typemap_level_type) { + jl_typemap_level_t *node = (jl_typemap_level_t*)ml; + if (node->targ.values != (void *)jl_nothing) + jl_typemap_rehash_array(&node->targ, ml, 1, offs); + if (node->arg1.values != (void *)jl_nothing) + jl_typemap_rehash_array(&node->arg1, ml, 0, offs); + jl_typemap_rehash(node->any, offs + 1); } } -static union jl_typemap_t *mtcache_hash_bp(struct jl_ordereddict_t *pa JL_PROPAGATES_ROOT, jl_value_t *ty, - int8_t tparam, int8_t offs, jl_value_t *parent) +static jl_typemap_t **mtcache_hash_bp(struct jl_ordereddict_t *pa JL_PROPAGATES_ROOT, jl_value_t *ty, + int8_t tparam, int8_t offs, jl_value_t *parent) { if (jl_is_datatype(ty)) { uintptr_t uid = ((jl_datatype_t*)ty)->uid; @@ -352,18 +349,19 @@ static union jl_typemap_t *mtcache_hash_bp(struct jl_ordereddict_t *pa JL_PROPAG if (idx > jl_max_int(pa->indices)) mtcache_rehash(pa, jl_array_len(pa->indices), parent, tparam, offs); jl_intset(pa->indices, slot, idx); - return &((union jl_typemap_t*)jl_array_data(pa->values))[idx - 1]; + return &((jl_typemap_t **)jl_array_data(pa->values))[idx - 1]; } - union jl_typemap_t *pml = &((union jl_typemap_t*)jl_array_data(pa->values))[idx - 1]; - if (pml->unknown == jl_nothing) + jl_typemap_t **pml = &((jl_typemap_t **)jl_array_ptr_data(pa->values))[idx - 1]; + if (*pml == jl_nothing) return pml; jl_value_t *t; - if (jl_typeof(pml->unknown) == (jl_value_t*)jl_typemap_level_type) { - t = pml->node->key; + if (jl_typeof(*pml) == (jl_value_t*)jl_typemap_level_type) { + t = ((jl_typemap_level_t*)*pml)->key; } else { - assert(jl_typeof(pml->unknown) == (jl_value_t*)jl_typemap_entry_type); - t = jl_field_type(jl_unwrap_unionall((jl_value_t*)pml->leaf->sig), offs); + t = jl_field_type(jl_unwrap_unionall( + jl_typemap_entry_sig(*pml)), + offs); if (tparam) t = jl_tparam0(t); } @@ -380,7 +378,7 @@ static union jl_typemap_t *mtcache_hash_bp(struct jl_ordereddict_t *pa JL_PROPAG static int jl_typemap_array_visitor(struct jl_ordereddict_t *a, jl_typemap_visitor_fptr fptr, void *closure) { size_t i, l = jl_array_len(a->values); - union jl_typemap_t *data = (union jl_typemap_t*)jl_array_ptr_data(a->values); + jl_typemap_t **data = (jl_typemap_t **)jl_array_ptr_data(a->values); for(i=0; i < l; i++) { if (!jl_typemap_visitor(data[i], fptr, closure)) return 0; @@ -399,21 +397,22 @@ static int jl_typemap_node_visitor(jl_typemap_entry_t *ml, jl_typemap_visitor_fp return 1; } -int jl_typemap_visitor(union jl_typemap_t cache, jl_typemap_visitor_fptr fptr, void *closure) +int jl_typemap_visitor(jl_typemap_t *cache, jl_typemap_visitor_fptr fptr, void *closure) { - if (jl_typeof(cache.unknown) == (jl_value_t*)jl_typemap_level_type) { - if (cache.node->targ.values != (void*)jl_nothing) - if (!jl_typemap_array_visitor(&cache.node->targ, fptr, closure)) + if (jl_typeof(cache) == (jl_value_t*)jl_typemap_level_type) { + jl_typemap_level_t *node = (jl_typemap_level_t*)cache; + if (node->targ.values != (void*)jl_nothing) + if (!jl_typemap_array_visitor(&node->targ, fptr, closure)) return 0; - if (cache.node->arg1.values != (void*)jl_nothing) - if (!jl_typemap_array_visitor(&cache.node->arg1, fptr, closure)) + if (node->arg1.values != (void*)jl_nothing) + if (!jl_typemap_array_visitor(&node->arg1, fptr, closure)) return 0; - if (!jl_typemap_node_visitor(cache.node->linear, fptr, closure)) + if (!jl_typemap_node_visitor(node->linear, fptr, closure)) return 0; - return jl_typemap_visitor(cache.node->any, fptr, closure); + return jl_typemap_visitor(node->any, fptr, closure); } else { - return jl_typemap_node_visitor(cache.leaf, fptr, closure); + return jl_typemap_node_visitor((jl_typemap_entry_t*)cache, fptr, closure); } } @@ -428,17 +427,17 @@ static int jl_typemap_intersection_array_visitor(struct jl_ordereddict_t *a, jl_ int offs, struct typemap_intersection_env *closure) { size_t i, l = jl_array_len(a->values); - union jl_typemap_t *data = (union jl_typemap_t*)jl_array_ptr_data(a->values); + jl_typemap_t **data = (jl_typemap_t **)jl_array_ptr_data(a->values); for (i = 0; i < l; i++) { - union jl_typemap_t ml = data[i]; - if (ml.unknown == jl_nothing) + jl_typemap_t *ml = data[i]; + if (ml == jl_nothing) continue; jl_value_t *t; - if (jl_typeof(ml.unknown) == (jl_value_t*)jl_typemap_level_type) { - t = ml.node->key; + if (jl_typeof(ml) == (jl_value_t *)jl_typemap_level_type) { + t = ((jl_typemap_level_t*)ml)->key; } else { - t = jl_field_type(jl_unwrap_unionall((jl_value_t*)ml.leaf->sig), offs); + t = jl_field_type(jl_unwrap_unionall(jl_typemap_entry_sig(ml)), offs); if (tparam) t = jl_tparam0(t); } @@ -493,11 +492,11 @@ static int jl_typemap_intersection_node_visitor(jl_typemap_entry_t *ml, struct t return 1; } -int jl_typemap_intersection_visitor(union jl_typemap_t map, int offs, +int jl_typemap_intersection_visitor(jl_typemap_t *map, int offs, struct typemap_intersection_env *closure) { - if (jl_typeof(map.unknown) == (jl_value_t*)jl_typemap_level_type) { - jl_typemap_level_t *cache = map.node; + if (jl_typeof(map) == (jl_value_t *)jl_typemap_level_type) { + jl_typemap_level_t *cache = (jl_typemap_level_t*)map; jl_value_t *ty = NULL; jl_value_t *ttypes = jl_unwrap_unionall(closure->type); assert(jl_is_datatype(ttypes)); @@ -524,8 +523,8 @@ int jl_typemap_intersection_visitor(union jl_typemap_t map, int offs, if (typetype) { if (is_cache_leaf(typetype)) { // direct lookup of leaf types - union jl_typemap_t ml = mtcache_hash_lookup(&cache->targ, typetype, 1, offs); - if (ml.unknown != jl_nothing) { + jl_typemap_t *ml = mtcache_hash_lookup(&cache->targ, typetype, 1, offs); + if (ml != jl_nothing) { if (!jl_typemap_intersection_visitor(ml, offs+1, closure)) return 0; } } @@ -540,8 +539,8 @@ int jl_typemap_intersection_visitor(union jl_typemap_t map, int offs, if (cache->arg1.values != (void*)jl_nothing) { if (is_cache_leaf(ty)) { // direct lookup of leaf types - union jl_typemap_t ml = mtcache_hash_lookup(&cache->arg1, ty, 0, offs); - if (ml.unknown != jl_nothing) { + jl_typemap_t *ml = mtcache_hash_lookup(&cache->arg1, ty, 0, offs); + if (ml != jl_nothing) { if (!jl_typemap_intersection_visitor(ml, offs+1, closure)) return 0; } } @@ -551,12 +550,13 @@ int jl_typemap_intersection_visitor(union jl_typemap_t map, int offs, } } } - if (!jl_typemap_intersection_node_visitor(map.node->linear, closure)) + if (!jl_typemap_intersection_node_visitor(cache->linear, closure)) return 0; - return jl_typemap_intersection_visitor(map.node->any, offs+1, closure); + return jl_typemap_intersection_visitor(cache->any, offs+1, closure); } else { - return jl_typemap_intersection_node_visitor(map.leaf, closure); + return jl_typemap_intersection_node_visitor( + (jl_typemap_entry_t*)map, closure); } } @@ -667,11 +667,11 @@ static jl_typemap_entry_t *jl_typemap_lookup_by_type_(jl_typemap_entry_t *ml, jl // this is the general entry point for looking up a type in the cache // as a subtype, or with type_equal -jl_typemap_entry_t *jl_typemap_assoc_by_type(union jl_typemap_t ml_or_cache, jl_value_t *types, jl_svec_t **penv, +jl_typemap_entry_t *jl_typemap_assoc_by_type(jl_typemap_t *ml_or_cache, jl_value_t *types, jl_svec_t **penv, int8_t subtype, int8_t offs, size_t world, size_t max_world_mask) { - if (jl_typeof(ml_or_cache.unknown) == (jl_value_t*)jl_typemap_level_type) { - jl_typemap_level_t *cache = ml_or_cache.node; + if (jl_typeof(ml_or_cache) == (jl_value_t *)jl_typemap_level_type) { + jl_typemap_level_t *cache = (jl_typemap_level_t*)ml_or_cache; // called object is the primary key for constructors, otherwise first argument jl_value_t *ty = NULL; jl_value_t *ttypes = jl_unwrap_unionall((jl_value_t*)types); @@ -703,8 +703,8 @@ jl_typemap_entry_t *jl_typemap_assoc_by_type(union jl_typemap_t ml_or_cache, jl_ if (jl_is_type_type(ty)) { jl_value_t *a0 = jl_tparam0(ty); if (cache->targ.values != (void*)jl_nothing && jl_is_datatype(a0)) { - union jl_typemap_t ml = mtcache_hash_lookup(&cache->targ, a0, 1, offs); - if (ml.unknown != jl_nothing) { + jl_typemap_t *ml = mtcache_hash_lookup(&cache->targ, a0, 1, offs); + if (ml != jl_nothing) { jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, types, penv, subtype, offs + 1, world, max_world_mask); if (li) return li; @@ -713,8 +713,8 @@ jl_typemap_entry_t *jl_typemap_assoc_by_type(union jl_typemap_t ml_or_cache, jl_ if (!subtype && is_cache_leaf(a0)) return NULL; } if (cache->arg1.values != (void*)jl_nothing && jl_is_datatype(ty)) { - union jl_typemap_t ml = mtcache_hash_lookup(&cache->arg1, ty, 0, offs); - if (ml.unknown != jl_nothing) { + jl_typemap_t *ml = mtcache_hash_lookup(&cache->arg1, ty, 0, offs); + if (ml != jl_nothing) { jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, types, penv, subtype, offs + 1, world, max_world_mask); if (li) return li; @@ -733,9 +733,10 @@ jl_typemap_entry_t *jl_typemap_assoc_by_type(union jl_typemap_t ml_or_cache, jl_ } } else { + jl_typemap_entry_t *leaf = (jl_typemap_entry_t*)ml_or_cache; return subtype ? - jl_typemap_assoc_by_type_(ml_or_cache.leaf, types, penv, world, max_world_mask) : - jl_typemap_lookup_by_type_(ml_or_cache.leaf, types, world, max_world_mask); + jl_typemap_assoc_by_type_(leaf, types, penv, world, max_world_mask) : + jl_typemap_lookup_by_type_(leaf, types, world, max_world_mask); } } @@ -824,12 +825,12 @@ jl_typemap_entry_t *jl_typemap_level_assoc_exact(jl_typemap_level_t *cache, jl_v jl_value_t *ty = (jl_value_t*)jl_typeof(a1); assert(jl_is_datatype(ty)); if (ty == (jl_value_t*)jl_datatype_type && cache->targ.values != (void*)jl_nothing) { - union jl_typemap_t ml_or_cache = mtcache_hash_lookup(&cache->targ, a1, 1, offs); + jl_typemap_t *ml_or_cache = mtcache_hash_lookup(&cache->targ, a1, 1, offs); jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, args, n, offs+1, world); if (ml) return ml; } if (cache->arg1.values != (void*)jl_nothing) { - union jl_typemap_t ml_or_cache = mtcache_hash_lookup(&cache->arg1, ty, 0, offs); + jl_typemap_t *ml_or_cache = mtcache_hash_lookup(&cache->arg1, ty, 0, offs); jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, args, n, offs+1, world); if (ml) return ml; } @@ -838,7 +839,7 @@ jl_typemap_entry_t *jl_typemap_level_assoc_exact(jl_typemap_level_t *cache, jl_v jl_typemap_entry_t *ml = jl_typemap_entry_assoc_exact(cache->linear, args, n, world); if (ml) return ml; } - if (cache->any.unknown != jl_nothing) + if (cache->any != jl_nothing) return jl_typemap_assoc_exact(cache->any, args, n, offs+1, world); return NULL; } @@ -868,7 +869,7 @@ static jl_typemap_level_t *jl_new_typemap_level(void) jl_typemap_level_type); cache->key = NULL; cache->linear = (jl_typemap_entry_t*)jl_nothing; - cache->any.unknown = jl_nothing; + cache->any = jl_nothing; cache->targ.indices = (jl_array_t*)jl_nothing; cache->targ.values = (jl_array_t*)jl_nothing; cache->arg1.indices = (jl_array_t*)jl_nothing; @@ -907,31 +908,34 @@ static void jl_typemap_list_insert_(jl_typemap_entry_t **pml, jl_value_t *parent } } -static void jl_typemap_insert_generic(union jl_typemap_t *pml, jl_value_t *parent, +static void jl_typemap_insert_generic(jl_typemap_t **pml, jl_value_t *parent, jl_typemap_entry_t *newrec, jl_value_t *key, int8_t offs, const struct jl_typemap_info *tparams) { - if (jl_typeof(pml->unknown) == (jl_value_t*)jl_typemap_level_type) { - jl_typemap_level_insert_(pml->node, newrec, offs, tparams); + if (jl_typeof(*pml) == (jl_value_t*)jl_typemap_level_type) { + jl_typemap_level_insert_((jl_typemap_level_t*)*pml, newrec, offs, tparams); return; } - unsigned count = jl_typemap_list_count(pml->leaf); + unsigned count = jl_typemap_list_count((jl_typemap_entry_t*)*pml); if (count > MAX_METHLIST_COUNT) { - pml->node = jl_method_convert_list_to_cache(pml->leaf, key, offs, tparams); - jl_gc_wb(parent, pml->node); - jl_typemap_level_insert_(pml->node, newrec, offs, tparams); + *pml = (jl_typemap_t*)jl_method_convert_list_to_cache( + (jl_typemap_entry_t *)*pml, + key, offs, tparams); + jl_gc_wb(parent, *pml); + jl_typemap_level_insert_((jl_typemap_level_t*)*pml, newrec, offs, tparams); return; } - jl_typemap_list_insert_(&pml->leaf, parent, newrec, tparams); + jl_typemap_list_insert_((jl_typemap_entry_t **)pml, + parent, newrec, tparams); } static int jl_typemap_array_insert_(struct jl_ordereddict_t *cache, jl_value_t *key, jl_typemap_entry_t *newrec, jl_value_t *parent, int8_t tparam, int8_t offs, const struct jl_typemap_info *tparams) { - union jl_typemap_t *pml = mtcache_hash_bp(cache, key, tparam, offs, (jl_value_t*)parent); + jl_typemap_t **pml = mtcache_hash_bp(cache, key, tparam, offs, (jl_value_t*)parent); if (pml) jl_typemap_insert_generic(pml, (jl_value_t*)cache->values, newrec, key, offs+1, tparams); return pml != NULL; @@ -979,7 +983,7 @@ static void jl_typemap_level_insert_(jl_typemap_level_t *cache, jl_typemap_entry jl_typemap_list_insert_(&cache->linear, (jl_value_t*)cache, newrec, tparams); } -jl_typemap_entry_t *jl_typemap_insert(union jl_typemap_t *cache, jl_value_t *parent, +jl_typemap_entry_t *jl_typemap_insert(jl_typemap_t **cache, jl_value_t *parent, jl_tupletype_t *type, jl_tupletype_t *simpletype, jl_svec_t *guardsigs, jl_value_t *newvalue, int8_t offs, From 351bcd54801c3d54dbb22812d0df0a1a9ed0b11f Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Tue, 21 Aug 2018 20:20:55 -0400 Subject: [PATCH 085/110] More analyzer annotations This gets us far enough to pass all the .c files without warning. The .cpp files are another issue (partly because C++ is more complicated, partly because they play a bit fast and lose with GC rooting). However, once this is merged, we should be able to set up CI for the .c files at least. --- src/array.c | 4 +- src/dump.c | 4 +- src/gf.c | 64 ++++++++++++++++++------------ src/jlapi.c | 2 + src/julia.h | 13 +++--- src/julia_internal.h | 4 +- src/staticdata.c | 21 +++++----- src/support/analyzer_annotations.h | 4 +- src/support/ios.h | 6 +-- src/toplevel.c | 6 +-- src/typemap.c | 4 +- 11 files changed, 78 insertions(+), 54 deletions(-) diff --git a/src/array.c b/src/array.c index a3bf9068cb045..54bee07cfc59d 100644 --- a/src/array.c +++ b/src/array.c @@ -547,13 +547,15 @@ JL_DLLEXPORT int jl_array_isassigned(jl_array_t *a, size_t i) return 1; } -JL_DLLEXPORT void jl_arrayset(jl_array_t *a, jl_value_t *rhs, size_t i) +JL_DLLEXPORT void jl_arrayset(jl_array_t *a JL_ROOTING_ARGUMENT, jl_value_t *rhs JL_ROOTED_ARGUMENT JL_MAYBE_UNROOTED, size_t i) { assert(i < jl_array_len(a)); jl_value_t *eltype = jl_tparam0(jl_typeof(a)); if (eltype != (jl_value_t*)jl_any_type) { + JL_GC_PUSH1(&rhs); if (!jl_isa(rhs, eltype)) jl_type_error("arrayset", eltype, rhs); + JL_GC_POP(); } if (!a->flags.ptrarray) { if (jl_is_uniontype(eltype)) { diff --git a/src/dump.c b/src/dump.c index 0820a7542557c..f970009de5ea8 100644 --- a/src/dump.c +++ b/src/dump.c @@ -3116,8 +3116,10 @@ static jl_value_t *_jl_restore_incremental(ios_t *f, jl_array_t *mod_array) jl_gc_enable_finalizers(ptls, 1); // make sure we don't run any Julia code concurrently before this point if (tracee_list) { jl_methtable_t *mt; - while ((mt = (jl_methtable_t*)arraylist_pop(tracee_list)) != NULL) + while ((mt = (jl_methtable_t*)arraylist_pop(tracee_list)) != NULL) { + JL_GC_PROMISE_ROOTED(mt); jl_typemap_visitor(mt->defs, trace_method, NULL); + } arraylist_free(tracee_list); free(tracee_list); } diff --git a/src/gf.c b/src/gf.c index b7f5f4ce2198e..7480524a16872 100644 --- a/src/gf.c +++ b/src/gf.c @@ -146,7 +146,7 @@ static int8_t jl_cachearg_offset(jl_methtable_t *mt) /// ----- Insertion logic for special entries ----- /// // get or create the MethodInstance for a specialization -JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m, jl_value_t *type, jl_svec_t *sparams, size_t world) +JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m JL_PROPAGATES_ROOT, jl_value_t *type, jl_svec_t *sparams, size_t world) { assert(world >= m->min_world && "typemap lookup is corrupted"); JL_LOCK(&m->writelock); @@ -240,7 +240,7 @@ void jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_args_t fptr // returns the inferred source, and may cache the result in li // if successful, also updates the li argument to describe the validity of this src // if inference doesn't occur (or can't finish), returns NULL instead -jl_code_info_t *jl_type_infer(jl_method_instance_t **pli, size_t world, int force) +jl_code_info_t *jl_type_infer(jl_method_instance_t **pli JL_ROOTS_TEMPORARILY, size_t world, int force) { JL_TIMING(INFERENCE); if (jl_typeinf_func == NULL) @@ -1395,22 +1395,25 @@ static int invalidate_backedges(jl_typemap_entry_t *oldentry, struct typemap_int { struct invalidate_conflicting_env *closure = container_of(closure0, struct invalidate_conflicting_env, match); if (oldentry->max_world > closure->max_world) { - struct set_world def; - def.replaced = oldentry->func.linfo; - def.world = closure->max_world; - jl_method_t *m = def.replaced->def.method; - - // truncate the max-valid in the invoke cache - if (m->invokes != NULL) - jl_typemap_visitor(m->invokes, set_max_world2, (void*)&def); - // invalidate mt cache entries - jl_datatype_t *gf = jl_first_argument_datatype((jl_value_t*)m->sig); - assert(jl_is_datatype(gf) && gf->name->mt && "method signature invalid?"); - jl_typemap_visitor(gf->name->mt->cache, set_max_world2, (void*)&def); + jl_method_instance_t *replaced_linfo = oldentry->func.linfo; + { + struct set_world def; + def.replaced = oldentry->func.linfo; + def.world = closure->max_world; + jl_method_t *m = def.replaced->def.method; + + // truncate the max-valid in the invoke cache + if (m->invokes != NULL) + jl_typemap_visitor(m->invokes, set_max_world2, (void*)&def); + // invalidate mt cache entries + jl_datatype_t *gf = jl_first_argument_datatype((jl_value_t*)m->sig); + assert(jl_is_datatype(gf) && gf->name->mt && "method signature invalid?"); + jl_typemap_visitor(gf->name->mt->cache, set_max_world2, (void*)&def); + } // invalidate backedges - JL_LOCK_NOGC(&def.replaced->def.method->writelock); - jl_array_t *backedges = def.replaced->backedges; + JL_LOCK_NOGC(&replaced_linfo->def.method->writelock); + jl_array_t *backedges = replaced_linfo->backedges; if (backedges) { size_t i, l = jl_array_len(backedges); jl_method_instance_t **replaced = (jl_method_instance_t**)jl_array_ptr_data(backedges); @@ -1419,8 +1422,8 @@ static int invalidate_backedges(jl_typemap_entry_t *oldentry, struct typemap_int } } closure->invalidated = 1; - def.replaced->backedges = NULL; - JL_UNLOCK_NOGC(&def.replaced->def.method->writelock); + replaced_linfo->backedges = NULL; + JL_UNLOCK_NOGC(&replaced_linfo->def.method->writelock); } return 1; } @@ -1494,11 +1497,20 @@ static int typemap_search(jl_typemap_entry_t *entry, void *closure) return 1; } +static jl_typemap_entry_t *do_typemap_search(jl_methtable_t *mt JL_PROPAGATES_ROOT, jl_method_t *method) JL_NOTSAFEPOINT; + +#ifndef __clang_analyzer__ +static jl_typemap_entry_t *do_typemap_search(jl_methtable_t *mt JL_PROPAGATES_ROOT, jl_method_t *method) JL_NOTSAFEPOINT { + jl_value_t *closure = (jl_value_t*)(method); + if (jl_typemap_visitor(mt->defs, typemap_search, &closure)) + jl_error("method not in method table"); + return (jl_typemap_entry_t *)closure; +} +#endif + JL_DLLEXPORT void jl_method_table_disable(jl_methtable_t *mt, jl_method_t *method) { - jl_typemap_entry_t *methodentry = (jl_typemap_entry_t*)(method); - if (jl_typemap_visitor(mt->defs, typemap_search, &methodentry)) - jl_error("method not in method table"); + jl_typemap_entry_t *methodentry = do_typemap_search(mt, method); JL_LOCK(&mt->writelock); // Narrow the world age on the method to make it uncallable methodentry->max_world = jl_world_counter++; @@ -1539,7 +1551,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method else { oldvalue = check_ambiguous_matches(mt->defs, newentry, check_ambiguous_visitor); if (mt->backedges) { - jl_value_t **backedges = (jl_value_t**)jl_array_data(mt->backedges); + jl_value_t **backedges = jl_array_ptr_data(mt->backedges); size_t i, na = jl_array_len(mt->backedges); size_t ins = 0; for (i = 1; i < na; i += 2) { @@ -1862,7 +1874,7 @@ JL_DLLEXPORT int32_t jl_invoke_api(jl_method_instance_t *mi) } // compile-time method lookup -jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types, size_t world, int mt_cache) +jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES_ROOT, size_t world, int mt_cache) { JL_TIMING(METHOD_LOOKUP_COMPILE); if (jl_has_free_typevars((jl_value_t*)types)) @@ -1921,7 +1933,6 @@ JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types) { size_t world = jl_world_counter; jl_method_instance_t *li = jl_get_specialization1(types, world, 1); - JL_GC_PROMISE_ROOTED(li); // Rooted via types since mt_cache==1 if (li == NULL) return 0; if (jl_generating_output()) { @@ -1949,6 +1960,7 @@ JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types) // additional useful methods that should be compiled //ALT: if (jl_is_datatype(types) && ((jl_datatype_t*)types)->isdispatchtuple && !jl_egal(li->specTypes, types)) //ALT: if (jl_subtype(types, li->specTypes)) + JL_GC_PROMISE_ROOTED(li); if (!jl_subtype(li->specTypes, (jl_value_t*)types)) { jl_svec_t *tpenv2 = jl_emptysvec; jl_value_t *types2 = NULL; @@ -2039,7 +2051,7 @@ static void show_call(jl_value_t *F, jl_value_t **args, uint32_t nargs) } #endif -static jl_value_t *verify_type(jl_value_t *v) +static jl_value_t *verify_type(jl_value_t *v) JL_NOTSAFEPOINT { assert(jl_typeof(jl_typeof(v))); return v; @@ -2180,6 +2192,7 @@ JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t **args, uint32_t nargs) jl_method_instance_t *mfunc = jl_lookup_generic_(args, nargs, jl_int32hash_fast(jl_return_address()), jl_get_ptls_states()->world_age); + JL_GC_PROMISE_ROOTED(mfunc); jl_value_t *res = mfunc->invoke(mfunc, args, nargs); return verify_type(res); } @@ -2251,6 +2264,7 @@ jl_value_t *jl_gf_invoke(jl_value_t *types0, jl_value_t **args, size_t nargs) JL_UNLOCK(&method->writelock); } JL_GC_POP(); + JL_GC_PROMISE_ROOTED(mfunc); return mfunc->invoke(mfunc, args, nargs); } diff --git a/src/jlapi.c b/src/jlapi.c index a5bf650839c54..e6d75801e21e4 100644 --- a/src/jlapi.c +++ b/src/jlapi.c @@ -386,6 +386,7 @@ JL_DLLEXPORT jl_value_t *(jl_typeof)(jl_value_t *v) return jl_typeof(v); } +#ifndef __clang_analyzer__ JL_DLLEXPORT int8_t (jl_gc_unsafe_enter)(void) { jl_ptls_t ptls = jl_get_ptls_states(); @@ -409,6 +410,7 @@ JL_DLLEXPORT void (jl_gc_safe_leave)(int8_t state) jl_ptls_t ptls = jl_get_ptls_states(); jl_gc_safe_leave(ptls, state); } +#endif JL_DLLEXPORT void (jl_gc_safepoint)(void) { diff --git a/src/julia.h b/src/julia.h index 8e518b6c429f6..009d3c6ba373f 100644 --- a/src/julia.h +++ b/src/julia.h @@ -96,9 +96,12 @@ JL_EXTENSION struct _jl_taggedvalue_t { }; #ifdef __clang_analyzer__ -JL_DLLEXPORT jl_taggedvalue_t *jl_astaggedvalue(jl_value_t *v JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; -jl_value_t *jl_valueof(jl_taggedvalue_t *tv JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; -JL_DLLEXPORT jl_value_t *jl_typeof(jl_value_t *v JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; +JL_DLLEXPORT jl_taggedvalue_t *_jl_astaggedvalue(jl_value_t *v JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; +#define jl_astaggedvalue(v) _jl_astaggedvalue((jl_value_t*)v) +jl_value_t *_jl_valueof(jl_taggedvalue_t *tv JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; +#define jl_valueof(v) _jl_valueof((jl_taggedvalue_t*)v) +JL_DLLEXPORT jl_value_t *_jl_typeof(jl_value_t *v JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; +#define jl_typeof(v) _jl_typeof((jl_value_t*)v) #else #define jl_astaggedvalue(v) \ ((jl_taggedvalue_t*)((char*)(v) - sizeof(jl_taggedvalue_t))) @@ -1103,7 +1106,7 @@ STATIC_INLINE int jl_is_concrete_type(jl_value_t *v) JL_NOTSAFEPOINT return jl_is_datatype(v) && ((jl_datatype_t*)v)->isconcretetype; } -STATIC_INLINE jl_value_t *jl_typemap_entry_sig(jl_typemap_t *tmap) JL_NOTSAFEPOINT +STATIC_INLINE jl_value_t *jl_typemap_entry_sig(jl_typemap_t *tmap JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT { assert(jl_typeof(tmap) == (jl_value_t*)jl_typemap_entry_type); return (jl_value_t*)((jl_typemap_entry_t*)tmap)->sig; @@ -1306,7 +1309,7 @@ JL_DLLEXPORT jl_value_t *jl_array_to_string(jl_array_t *a); JL_DLLEXPORT jl_array_t *jl_alloc_vec_any(size_t n); JL_DLLEXPORT jl_value_t *jl_arrayref(jl_array_t *a, size_t i); // 0-indexed JL_DLLEXPORT jl_value_t *jl_ptrarrayref(jl_array_t *a JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; // 0-indexed -JL_DLLEXPORT void jl_arrayset(jl_array_t *a JL_ROOTING_ARGUMENT, jl_value_t *v JL_ROOTED_ARGUMENT, size_t i) JL_NOTSAFEPOINT; // 0-indexed +JL_DLLEXPORT void jl_arrayset(jl_array_t *a JL_ROOTING_ARGUMENT, jl_value_t *v JL_ROOTED_ARGUMENT JL_MAYBE_UNROOTED, size_t i); // 0-indexed JL_DLLEXPORT void jl_arrayunset(jl_array_t *a, size_t i); // 0-indexed JL_DLLEXPORT int jl_array_isassigned(jl_array_t *a, size_t i); // 0-indexed JL_DLLEXPORT void jl_array_grow_end(jl_array_t *a, size_t inc); diff --git a/src/julia_internal.h b/src/julia_internal.h index 2c084703f9b0d..f795442a8ee8e 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -445,7 +445,7 @@ jl_value_t *jl_interpret_toplevel_thunk(jl_module_t *m, jl_code_info_t *src); jl_value_t *jl_interpret_toplevel_expr_in(jl_module_t *m, jl_value_t *e, jl_code_info_t *src, jl_svec_t *sparam_vals); -int jl_is_toplevel_only_expr(jl_value_t *e); +int jl_is_toplevel_only_expr(jl_value_t *e) JL_NOTSAFEPOINT; jl_value_t *jl_call_scm_on_ast(const char *funcname, jl_value_t *expr, jl_module_t *inmodule); void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_module_t *mod, jl_sym_t *name); @@ -568,7 +568,7 @@ static inline void jl_set_gc_and_wait(void) JL_DLLEXPORT jl_value_t *jl_dump_fptr_asm(uint64_t fptr, int raw_mc, const char* asm_variant); void jl_dump_native(const char *bc_fname, const char *unopt_bc_fname, const char *obj_fname, const char *sysimg_data, size_t sysimg_len); -int32_t jl_get_llvm_gv(jl_value_t *p); +int32_t jl_get_llvm_gv(jl_value_t *p) JL_NOTSAFEPOINT; int32_t jl_assign_functionID(const char *fname); // the first argument to jl_idtable_rehash is used to return a value // make sure it is rooted if it is used after the function returns diff --git a/src/staticdata.c b/src/staticdata.c index eb9d6c81cf1f6..340f76811d73b 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -128,12 +128,12 @@ typedef enum { #define write_uint8(s, n) ios_putc((n), (s)) #define read_uint8(s) ((uint8_t)ios_getc((s))) -static void write_uint32(ios_t *s, uint32_t i) +static void write_uint32(ios_t *s, uint32_t i) JL_NOTSAFEPOINT { ios_write(s, (char*)&i, 4); } -static uint32_t read_uint32(ios_t *s) +static uint32_t read_uint32(ios_t *s) JL_NOTSAFEPOINT { uint32_t x = 0; ios_read(s, (char*)&x, 4); @@ -305,7 +305,7 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v) } } -static void ios_ensureroom(ios_t *s, size_t newsize) +static void ios_ensureroom(ios_t *s, size_t newsize) JL_NOTSAFEPOINT { size_t prevsize = s->size; if (prevsize < newsize) { @@ -315,7 +315,7 @@ static void ios_ensureroom(ios_t *s, size_t newsize) } } -static void record_gvar(jl_serializer_state *s, int gid, uintptr_t reloc_id) +static void record_gvar(jl_serializer_state *s, int gid, uintptr_t reloc_id) JL_NOTSAFEPOINT { if (gid == 0) return; @@ -326,7 +326,7 @@ static void record_gvar(jl_serializer_state *s, int gid, uintptr_t reloc_id) } -static void write_padding(ios_t *s, size_t nb) +static void write_padding(ios_t *s, size_t nb) JL_NOTSAFEPOINT { static const char zeros[16] = {0}; while (nb > 16) { @@ -338,7 +338,7 @@ static void write_padding(ios_t *s, size_t nb) } -static void write_pointer(ios_t *s) +static void write_pointer(ios_t *s) JL_NOTSAFEPOINT { assert((ios_pos(s) & (sizeof(void*) - 1)) == 0 && "stream misaligned for writing a word-sized value"); write_padding(s, sizeof(void*)); @@ -346,7 +346,7 @@ static void write_pointer(ios_t *s) #define backref_id(s, v) _backref_id(s, (jl_value_t*)(v)) -static uintptr_t _backref_id(jl_serializer_state *s, jl_value_t *v) +static uintptr_t _backref_id(jl_serializer_state *s, jl_value_t *v) JL_NOTSAFEPOINT { assert(v != NULL && "cannot get backref to NULL object"); void *idx = HT_NOTFOUND; @@ -374,7 +374,7 @@ static uintptr_t _backref_id(jl_serializer_state *s, jl_value_t *v) } -static void write_pointerfield(jl_serializer_state *s, jl_value_t *fld) +static void write_pointerfield(jl_serializer_state *s, jl_value_t *fld) JL_NOTSAFEPOINT { if (fld != NULL) { arraylist_push(&s->relocs_list, (void*)(uintptr_t)ios_pos(s->s)); @@ -383,7 +383,7 @@ static void write_pointerfield(jl_serializer_state *s, jl_value_t *fld) write_pointer(s->s); } -static void write_gctaggedfield(jl_serializer_state *s, uintptr_t ref) +static void write_gctaggedfield(jl_serializer_state *s, uintptr_t ref) JL_NOTSAFEPOINT { arraylist_push(&s->gctags_list, (void*)(uintptr_t)ios_pos(s->s)); arraylist_push(&s->gctags_list, (void*)ref); @@ -473,7 +473,7 @@ static void jl_write_module(jl_serializer_state *s, uintptr_t item, jl_module_t write_pointer(s->s); tot += sizeof(void*); } - newm = (jl_module_t*)&s->s->buf[reloc_offset]; + // newm = (jl_module_t*)&s->s->buf[reloc_offset]; } } } @@ -1487,6 +1487,7 @@ static void jl_restore_system_image_from_stream(ios_t *f) deser_tag.items[0] = (void*)const_data.buf; jl_read_relocations(&s, GC_OLD_MARKED); // gctags size_t sizeof_tags = ios_pos(&relocs); + (void)sizeof_tags; jl_read_relocations(&s, 0); // general relocs ios_close(&relocs); ios_close(&const_data); diff --git a/src/support/analyzer_annotations.h b/src/support/analyzer_annotations.h index caf8c6003cbe3..62e6f27765dff 100644 --- a/src/support/analyzer_annotations.h +++ b/src/support/analyzer_annotations.h @@ -23,8 +23,8 @@ #ifdef __cplusplus extern "C" { #endif - void JL_GC_PROMISE_ROOTED(void *v); - void jl_may_leak(uintptr_t); + void JL_GC_PROMISE_ROOTED(void *v) JL_NOTSAFEPOINT; + void jl_may_leak(uintptr_t) JL_NOTSAFEPOINT; #ifdef __cplusplus } #endif diff --git a/src/support/ios.h b/src/support/ios.h index 1a8cfc42f3f42..aafb1d6446010 100644 --- a/src/support/ios.h +++ b/src/support/ios.h @@ -76,10 +76,10 @@ extern void (*ios_set_io_wait_func)(int); JL_DLLEXPORT size_t ios_read(ios_t *s, char *dest, size_t n); JL_DLLEXPORT size_t ios_readall(ios_t *s, char *dest, size_t n); JL_DLLEXPORT size_t ios_write(ios_t *s, const char *data, size_t n) JL_NOTSAFEPOINT; -JL_DLLEXPORT int64_t ios_seek(ios_t *s, int64_t pos); // absolute seek +JL_DLLEXPORT int64_t ios_seek(ios_t *s, int64_t pos) JL_NOTSAFEPOINT; // absolute seek JL_DLLEXPORT int64_t ios_seek_end(ios_t *s); JL_DLLEXPORT int64_t ios_skip(ios_t *s, int64_t offs); // relative seek -JL_DLLEXPORT int64_t ios_pos(ios_t *s); // get current position +JL_DLLEXPORT int64_t ios_pos(ios_t *s) JL_NOTSAFEPOINT; // get current position JL_DLLEXPORT int ios_trunc(ios_t *s, size_t size) JL_NOTSAFEPOINT; JL_DLLEXPORT int ios_eof(ios_t *s); JL_DLLEXPORT int ios_eof_blocking(ios_t *s); @@ -102,7 +102,7 @@ JL_DLLEXPORT size_t ios_readprep(ios_t *from, size_t n); /* stream creation */ JL_DLLEXPORT -ios_t *ios_file(ios_t *s, const char *fname, int rd, int wr, int create, int trunc); +ios_t *ios_file(ios_t *s, const char *fname, int rd, int wr, int create, int trunc) JL_NOTSAFEPOINT; JL_DLLEXPORT ios_t *ios_mkstemp(ios_t *f, char *fname); JL_DLLEXPORT ios_t *ios_mem(ios_t *s, size_t initsize) JL_NOTSAFEPOINT; ios_t *ios_str(ios_t *s, char *str); diff --git a/src/toplevel.c b/src/toplevel.c index e425f7bf37e92..0f0eff0e9ae31 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -323,7 +323,7 @@ JL_DLLEXPORT jl_module_t *jl_base_relative_to(jl_module_t *m) return jl_top_module; } -static void expr_attributes(jl_value_t *v, int *has_intrinsics, int *has_defs) +static void expr_attributes(jl_value_t *v, int *has_intrinsics, int *has_defs) JL_NOTSAFEPOINT { if (!jl_is_expr(v)) return; @@ -362,7 +362,7 @@ static void expr_attributes(jl_value_t *v, int *has_intrinsics, int *has_defs) jl_module_t *mod = jl_globalref_mod(f); jl_sym_t *name = jl_globalref_name(f); if (jl_binding_resolved_p(mod, name)) { - jl_binding_t *b = jl_get_binding(mod, name); + jl_binding_t *b = jl_get_module_binding(mod, name); if (b && b->value && b->constp) called = b->value; } @@ -513,7 +513,7 @@ static jl_module_t *eval_import_path(jl_module_t *where, jl_module_t *from JL_PR return m; } -int jl_is_toplevel_only_expr(jl_value_t *e) +int jl_is_toplevel_only_expr(jl_value_t *e) JL_NOTSAFEPOINT { return jl_is_expr(e) && (((jl_expr_t*)e)->head == module_sym || diff --git a/src/typemap.c b/src/typemap.c index 13abae4c31f5a..42e5fb6e82b22 100644 --- a/src/typemap.c +++ b/src/typemap.c @@ -242,7 +242,7 @@ static jl_array_t *jl_alloc_int_1d(size_t np, size_t len) } static inline -jl_typemap_t *mtcache_hash_lookup(const struct jl_ordereddict_t *a JL_PROPAGATES_ROOT, jl_value_t *ty, int8_t tparam, int8_t offs) +jl_typemap_t *mtcache_hash_lookup(const struct jl_ordereddict_t *a JL_PROPAGATES_ROOT, jl_value_t *ty, int8_t tparam, int8_t offs) JL_NOTSAFEPOINT { uintptr_t uid = ((jl_datatype_t*)ty)->uid; jl_typemap_t *ml = jl_nothing; @@ -349,7 +349,7 @@ static jl_typemap_t **mtcache_hash_bp(struct jl_ordereddict_t *pa JL_PROPAGATES_ if (idx > jl_max_int(pa->indices)) mtcache_rehash(pa, jl_array_len(pa->indices), parent, tparam, offs); jl_intset(pa->indices, slot, idx); - return &((jl_typemap_t **)jl_array_data(pa->values))[idx - 1]; + return &((jl_typemap_t **)jl_array_ptr_data(pa->values))[idx - 1]; } jl_typemap_t **pml = &((jl_typemap_t **)jl_array_ptr_data(pa->values))[idx - 1]; if (*pml == jl_nothing) From 85cc84f13fc6efeef837e84f0c9ea1476f492375 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Wed, 22 Aug 2018 23:36:24 +0200 Subject: [PATCH 086/110] Add a short warning to the doc-frontpage if the docs (#28791) are for an in-development version of Julia. --- doc/src/index.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/doc/src/index.md b/doc/src/index.md index 855e45db671f1..a6279791f3ec2 100644 --- a/doc/src/index.md +++ b/doc/src/index.md @@ -1,6 +1,23 @@ -# Julia 1.0 Documentation +```@eval +io = IOBuffer() +release = isempty(VERSION.prerelease) +v = "$(VERSION.major).$(VERSION.minor)" +!release && (v = v*"-$(first(VERSION.prerelease))") +print(io, """ + # Julia $(v) Documentation -Welcome to the documentation for Julia 1.0. + Welcome to the documentation for Julia $(v). + + """) +if !release + print(io,""" + !!! warning "Work in progress!" + This documentation is for an unreleased, in-development, version of Julia. + """) +end +import Markdown +Markdown.parse(String(take!(io))) +``` Please read the [release blog post](https://julialang.org/blog/2018/08/one-point-zero) for a general overview of the language and many of the changes since Julia v0.6. Note that version 0.7 was released alongside From 6a2dcc600b4c0b944757eb696965847e8c0b7aee Mon Sep 17 00:00:00 2001 From: Jutho Date: Thu, 23 Aug 2018 00:09:59 +0200 Subject: [PATCH 087/110] Make copyto!(A,I) work for rectangular matrices (#28790) * Make copyto!(A,I) work for rectangular matrices * add tests for `copyto!` add tests for `copyto!(::Matrix, ::UniformScaling)` * fix whitespace --- stdlib/LinearAlgebra/src/uniformscaling.jl | 3 +-- stdlib/LinearAlgebra/test/uniformscaling.jl | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/stdlib/LinearAlgebra/src/uniformscaling.jl b/stdlib/LinearAlgebra/src/uniformscaling.jl index 57037473f4b29..54db4d8a6b893 100644 --- a/stdlib/LinearAlgebra/src/uniformscaling.jl +++ b/stdlib/LinearAlgebra/src/uniformscaling.jl @@ -207,10 +207,9 @@ isapprox(A::AbstractMatrix, J::UniformScaling; kwargs...) = isapprox(J, A; kwarg function copyto!(A::AbstractMatrix, J::UniformScaling) @assert !has_offset_axes(A) - size(A,1)==size(A,2) || throw(DimensionMismatch("a UniformScaling can only be copied to a square matrix")) fill!(A, 0) λ = J.λ - for i = 1:size(A,1) + for i = 1:min(size(A,1),size(A,2)) @inbounds A[i,i] = λ end return A diff --git a/stdlib/LinearAlgebra/test/uniformscaling.jl b/stdlib/LinearAlgebra/test/uniformscaling.jl index 52271177a1f96..2e2b33a08250e 100644 --- a/stdlib/LinearAlgebra/test/uniformscaling.jl +++ b/stdlib/LinearAlgebra/test/uniformscaling.jl @@ -86,6 +86,13 @@ let @test cond(J) == (λ ≠ zero(λ) ? one(real(λ)) : oftype(real(λ), Inf)) end + @testset "copyto!" begin + A = Matrix{Int}(undef, (3,3)) + @test copyto!(A, I) == one(A) + B = Matrix{ComplexF64}(undef, (1,2)) + @test copyto!(B, J) == [λ zero(λ)] + end + @testset "binary ops with matrices" begin B = bitrand(2, 2) @test B + I == B + Matrix(I, size(B)) From f31e28a50e029942d5d96977f5993defb2f60c13 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Tue, 21 Aug 2018 20:56:41 -0700 Subject: [PATCH 088/110] Run ambiguity test inside a clean process; fixes 28804 --- stdlib/LinearAlgebra/test/ambiguous_exec.jl | 4 ++++ stdlib/LinearAlgebra/test/matmul.jl | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 stdlib/LinearAlgebra/test/ambiguous_exec.jl diff --git a/stdlib/LinearAlgebra/test/ambiguous_exec.jl b/stdlib/LinearAlgebra/test/ambiguous_exec.jl new file mode 100644 index 0000000000000..6dce4926f4610 --- /dev/null +++ b/stdlib/LinearAlgebra/test/ambiguous_exec.jl @@ -0,0 +1,4 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +using Test, LinearAlgebra +@test detect_ambiguities(LinearAlgebra; imported=true, recursive=true) == [] diff --git a/stdlib/LinearAlgebra/test/matmul.jl b/stdlib/LinearAlgebra/test/matmul.jl index a61445128e263..bd1cc3072bc79 100644 --- a/stdlib/LinearAlgebra/test/matmul.jl +++ b/stdlib/LinearAlgebra/test/matmul.jl @@ -446,7 +446,11 @@ end end @testset "method ambiguity" begin - @test detect_ambiguities(LinearAlgebra, Base; imported=true, recursive=true) == [] + # Ambiguity test is run inside a clean process. + # https://github.com/JuliaLang/julia/issues/28804 + script = joinpath(@__DIR__, "ambiguous_exec.jl") + cmd = `$(Base.julia_cmd()) --startup-file=no $script` + @test success(pipeline(cmd; stdout=stdout, stderr=stderr)) end end # module TestMatmul From c366143deb8a5a1b279187d822ee3569e466afdc Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Tue, 21 Aug 2018 14:16:38 +0200 Subject: [PATCH 089/110] doc: change the canonical url to v1 instead of stable. --- doc/make.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/make.jl b/doc/make.jl index 466d4705814af..126ef0a81eac5 100644 --- a/doc/make.jl +++ b/doc/make.jl @@ -162,7 +162,7 @@ makedocs( analytics = "UA-28835595-6", pages = PAGES, html_prettyurls = ("deploy" in ARGS), - html_canonical = ("deploy" in ARGS) ? "https://docs.julialang.org/en/stable/" : nothing, + html_canonical = ("deploy" in ARGS) ? "https://docs.julialang.org/en/v1/" : nothing, assets = ["assets/julia-manual.css", ] ) From f9f3c4f45a5b22dacd1bc8d4cde33b5b05550fa6 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Wed, 22 Aug 2018 23:05:50 +0200 Subject: [PATCH 090/110] Patch Documenter v0.19.6 to create a correct version selector Co-authored-by: Morten Piibeleht Co-authored-by: Fredrik Ekre --- doc/make.jl | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/doc/make.jl b/doc/make.jl index 126ef0a81eac5..e4d849ec167bf 100644 --- a/doc/make.jl +++ b/doc/make.jl @@ -166,6 +166,36 @@ makedocs( assets = ["assets/julia-manual.css", ] ) +# This overloads the function in Documenter that generates versions.js, to include +# v1/ in the version selector, instead of stable/. +# +# The function is identical to the version found in Documenter v0.19.6, except that +# it includes "v1" instead of "stable". +# +# Original: +# https://github.com/JuliaDocs/Documenter.jl/blob/v0.19.6/src/Writers/HTMLWriter.jl#L481-L506 +# +import Documenter.Writers.HTMLWriter: generate_version_file +function generate_version_file(dir::AbstractString) + named_folders = ["v1", "latest"] + tag_folders = [] + for each in readdir(dir) + each == "v1" && continue # skip the v1 symlink + occursin(Base.VERSION_REGEX, each) && push!(tag_folders, each) + end + # sort tags by version number + sort!(tag_folders, lt = (x, y) -> VersionNumber(x) < VersionNumber(y), rev = true) + open(joinpath(dir, "versions.js"), "w") do buf + println(buf, "var DOC_VERSIONS = [") + for group in (named_folders, tag_folders) + for folder in group + println(buf, " \"", folder, "\",") + end + end + println(buf, "];") + end +end + # Only deploy docs from 64bit Linux to avoid committing multiple versions of the same # docs from different workers. if "deploy" in ARGS && Sys.ARCH === :x86_64 && Sys.KERNEL === :Linux From b411a58b4ef620f9a92770a5cb2deaed87d6beeb Mon Sep 17 00:00:00 2001 From: Nikita Sirgienko Date: Thu, 23 Aug 2018 10:16:28 +0300 Subject: [PATCH 091/110] Update info about `versioninfo` in devdocs (#28810) --- doc/src/devdocs/backtraces.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/devdocs/backtraces.md b/doc/src/devdocs/backtraces.md index ca750b79a320d..a65a494bbc3a4 100644 --- a/doc/src/devdocs/backtraces.md +++ b/doc/src/devdocs/backtraces.md @@ -15,10 +15,10 @@ and follow the instructions to generate the debugging information requested. Ta ## [Version/Environment info](@id dev-version-info) No matter the error, we will always need to know what version of Julia you are running. When Julia -first starts up, a header is printed out with a version number and date. Please also include the -output of `versioninfo()` in any report you create: +first starts up, a header is printed out with a version number and date. Please also include the output of `versioninfo()` (exported from the [`InteractiveUtils`](@ref InteractiveUtils.versioninfo) standard library) in any report you create: ```@repl +using InteractiveUtils versioninfo() ``` From 31c9ae94e3767a506ef5ca6cb2043cf1e7b286cd Mon Sep 17 00:00:00 2001 From: Christian Kurz Date: Thu, 23 Aug 2018 12:00:57 +0200 Subject: [PATCH 092/110] add `Regex` documentation (#28703) add `Regex` documentation. (#26919) --- base/regex.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/base/regex.jl b/base/regex.jl index 41745eddd2a21..384d6ca3dfa21 100644 --- a/base/regex.jl +++ b/base/regex.jl @@ -7,6 +7,16 @@ include("pcre.jl") const DEFAULT_COMPILER_OPTS = PCRE.UTF | PCRE.NO_UTF_CHECK | PCRE.ALT_BSUX | PCRE.UCP const DEFAULT_MATCH_OPTS = PCRE.NO_UTF_CHECK +""" + Regex(pattern[, flags]) + +A type representing a regular expression. `Regex` objects can be used to match strings +with [`match`](@ref). + +`Regex` objects can be created using the [`@r_str`](@ref) string macro. The +`Regex(pattern[, flags])` constructor is usually used if the `pattern` string needs +to be interpolated. See the documentation of the string macro for details on flags. +""" mutable struct Regex pattern::String compile_options::UInt32 @@ -81,6 +91,8 @@ listed after the ending quote, to change its behaviour: `\\s`, `\\W`, `\\w`, etc. match based on Unicode character properties. With this option, these sequences only match ASCII characters. +See `Regex` if interpolation is needed. + # Examples ```jldoctest julia> match(r"a+.*b+.*?d\$"ism, "Goodbye,\\nOh, angry,\\nBad world\\n") From b6756c52958e0c93da81ab59ed29c5a2e08e0fe8 Mon Sep 17 00:00:00 2001 From: Sukera <11753998+Seelengrab@users.noreply.github.com> Date: Thu, 23 Aug 2018 12:01:59 +0200 Subject: [PATCH 093/110] Added seekstart to getpass in base/util.jl (#28828) (#28832) --- base/util.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/util.jl b/base/util.jl index e3423491aa84d..80c790770af74 100644 --- a/base/util.jl +++ b/base/util.jl @@ -476,7 +476,7 @@ function getpass(input::TTY, output::IO, prompt::AbstractString) write(s, c) end end - return s + return seekstart(s) end else function getpass(input::TTY, output::IO, prompt::AbstractString) From 472c178da7069ead7172861923c3f9418ec059ac Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Thu, 23 Aug 2018 12:02:46 +0200 Subject: [PATCH 094/110] make cmp with BigInt return in [-1, 0, 1] (#28780) * make cmp with BigInt return in [-1, 0, 1] --- base/gmp.jl | 8 ++++---- test/bigint.jl | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/base/gmp.jl b/base/gmp.jl index d80182646732e..4a7f6945e050d 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -487,13 +487,13 @@ count_ones_abs(x::BigInt) = iszero(x) ? 0 : MPZ.mpn_popcount(x) divrem(x::BigInt, y::BigInt) = MPZ.tdiv_qr(x, y) -cmp(x::BigInt, y::BigInt) = MPZ.cmp(x, y) -cmp(x::BigInt, y::ClongMax) = MPZ.cmp_si(x, y) -cmp(x::BigInt, y::CulongMax) = MPZ.cmp_ui(x, y) +cmp(x::BigInt, y::BigInt) = sign(MPZ.cmp(x, y)) +cmp(x::BigInt, y::ClongMax) = sign(MPZ.cmp_si(x, y)) +cmp(x::BigInt, y::CulongMax) = sign(MPZ.cmp_ui(x, y)) cmp(x::BigInt, y::Integer) = cmp(x, big(y)) cmp(x::Integer, y::BigInt) = -cmp(y, x) -cmp(x::BigInt, y::CdoubleMax) = isnan(y) ? -1 : MPZ.cmp_d(x, y) +cmp(x::BigInt, y::CdoubleMax) = isnan(y) ? -1 : sign(MPZ.cmp_d(x, y)) cmp(x::CdoubleMax, y::BigInt) = -cmp(y, x) isqrt(x::BigInt) = MPZ.sqrt(x) diff --git a/test/bigint.jl b/test/bigint.jl index 01acd5449b8c3..cd4c48f44873d 100644 --- a/test/bigint.jl +++ b/test/bigint.jl @@ -401,3 +401,27 @@ end # Issue #24298 @test mod(BigInt(6), UInt(5)) == mod(6, 5) + +@testset "cmp has values in [-1, 0, 1], issue #28780" begin + # _rand produces values whose log2 is better distributed than rand + _rand(::Type{BigInt}, n=1000) = let x = big(2)^rand(1:rand(1:n)) + rand(-x:x) + end + _rand(F::Type{<:AbstractFloat}) = F(_rand(BigInt, round(Int, log2(floatmax(F))))) + rand(F) + _rand(T) = rand(T) + for T in (Base.BitInteger_types..., BigInt, Float64, Float32, Float16) + @test cmp(big(2)^130, one(T)) === 1 + @test cmp(-big(2)^130, one(T)) === -1 + c = cmp(_rand(BigInt), _rand(T)) + @test c ∈ (-1, 0, 1) + @test c isa Int + (T <: Integer && T !== BigInt) || continue + x = rand(T) + @test cmp(big(2)^130, x) === cmp(x, -big(2)^130) === 1 + @test cmp(-big(2)^130, x) === cmp(x, big(2)^130) === -1 + @test cmp(big(x), x) === cmp(x, big(x)) === 0 + end + c = cmp(_rand(BigInt), _rand(BigInt)) + @test c ∈ (-1, 0, 1) + @test c isa Int +end From 6d4ff5e7f8fd3bfe033a9d400206e12a7184990c Mon Sep 17 00:00:00 2001 From: Israel Herraiz Date: Thu, 23 Aug 2018 12:03:13 +0200 Subject: [PATCH 095/110] @schedule is deprecated, the code is no longer valid in 1.0 (#28800) * @schedule is deprecated, the code is no longer valid in 1.0 * Additional changes for 1.0 compliance --- doc/src/manual/parallel-computing.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/src/manual/parallel-computing.md b/doc/src/manual/parallel-computing.md index a07312182904b..5b5570dc5d105 100644 --- a/doc/src/manual/parallel-computing.md +++ b/doc/src/manual/parallel-computing.md @@ -77,7 +77,7 @@ A channel can be visualized as a pipe, i.e., it has a write end and a read end : # we can schedule `n` instances of `foo` to be active concurrently. for _ in 1:n - @schedule foo() + @async foo() end ``` * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects @@ -184,16 +184,16 @@ julia> function make_jobs(n) julia> n = 12; -julia> @schedule make_jobs(n); # feed the jobs channel with "n" jobs +julia> @async make_jobs(n); # feed the jobs channel with "n" jobs julia> for i in 1:4 # start 4 tasks to process requests in parallel - @schedule do_work() + @async do_work() end julia> @elapsed while n > 0 # print out results job_id, exec_time = take!(results) - println("$job_id finished in $(round(exec_time,2)) seconds") - n = n - 1 + println("$job_id finished in $(round(exec_time; digits=2)) seconds") + global n = n - 1 end 4 finished in 0.22 seconds 3 finished in 0.45 seconds From cd850de63cce34f53ec9120e04b26bde7e38ac2c Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 23 Aug 2018 15:21:11 -0400 Subject: [PATCH 096/110] fix #28593, macro hygiene problems in type definitions (#28706) --- src/julia-syntax.scm | 18 +++++++++++++----- src/macroexpand.scm | 36 ++++++++++++++++++++++++++---------- test/syntax.jl | 27 +++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index abce5e47b6c20..4a3d43613cff1 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -200,9 +200,17 @@ (let ((bounds (map analyze-typevar params))) (values (map car bounds) bounds))) +(define (unmangled-name v) + (if (eq? v '||) + v + (let ((s (string v))) + (if (eqv? (string.char s 0) #\#) + (symbol (last (string-split s "#"))) + v)))) + ;; construct expression to allocate a TypeVar -(define (bounds-to-TypeVar v) - (let ((v (car v)) +(define (bounds-to-TypeVar v (unmangle #f)) + (let ((v ((if unmangle unmangled-name identity) (car v))) (lb (cadr v)) (ub (caddr v))) `(call (core TypeVar) ',v @@ -836,7 +844,7 @@ (block (global ,name) (const ,name) ,@(map (lambda (v) `(local ,v)) params) - ,@(map (lambda (n v) (make-assignment n (bounds-to-TypeVar v))) params bounds) + ,@(map (lambda (n v) (make-assignment n (bounds-to-TypeVar v #t))) params bounds) (struct_type ,name (call (core svec) ,@params) (call (core svec) ,@(map quotify field-names)) ,super (call (core svec) ,@field-types) ,mut ,min-initialized))) @@ -877,7 +885,7 @@ (scope-block (block ,@(map (lambda (v) `(local ,v)) params) - ,@(map (lambda (n v) (make-assignment n (bounds-to-TypeVar v))) params bounds) + ,@(map (lambda (n v) (make-assignment n (bounds-to-TypeVar v #t))) params bounds) (abstract_type ,name (call (core svec) ,@params) ,super)))))) (define (primitive-type-def-expr n name params super) @@ -888,7 +896,7 @@ (scope-block (block ,@(map (lambda (v) `(local ,v)) params) - ,@(map (lambda (n v) (make-assignment n (bounds-to-TypeVar v))) params bounds) + ,@(map (lambda (n v) (make-assignment n (bounds-to-TypeVar v #t))) params bounds) (primitive_type ,name (call (core svec) ,@params) ,n ,super)))))) ;; take apart a type signature, e.g. T{X} <: S{Y} diff --git a/src/macroexpand.scm b/src/macroexpand.scm index 2c7a040e39f53..abad3407656fd 100644 --- a/src/macroexpand.scm +++ b/src/macroexpand.scm @@ -135,16 +135,21 @@ (if var (list 'varlist var) '())) ;; type definition - (pattern-lambda (struct mut (<: (curly tn . tvars) super) body) - (list* 'varlist (cons (unescape tn) (unescape tn)) '(new . new) - (typevar-names tvars))) - (pattern-lambda (struct mut (curly tn . tvars) body) - (list* 'varlist (cons (unescape tn) (unescape tn)) '(new . new) - (typevar-names tvars))) - (pattern-lambda (struct mut (<: tn super) body) - (list 'varlist (cons (unescape tn) (unescape tn)) '(new . new))) - (pattern-lambda (struct mut tn body) - (list 'varlist (cons (unescape tn) (unescape tn)) '(new . new))) + (pattern-lambda (struct mut spec body) + (let ((tn (typedef-expr-name spec)) + (tv (typedef-expr-tvars spec))) + (list* 'varlist (cons (unescape tn) (unescape tn)) '(new . new) + (typevar-names tv)))) + (pattern-lambda (abstract spec) + (let ((tn (typedef-expr-name spec)) + (tv (typedef-expr-tvars spec))) + (list* 'varlist (cons (unescape tn) (unescape tn)) + (typevar-names tv)))) + (pattern-lambda (primitive spec nb) + (let ((tn (typedef-expr-name spec)) + (tv (typedef-expr-tvars spec))) + (list* 'varlist (cons (unescape tn) (unescape tn)) + (typevar-names tv)))) )) ; vars-introduced-by-patterns @@ -178,6 +183,17 @@ (cadr e) e)) +(define (typedef-expr-name e) + (cond ((atom? e) e) + ((or (eq? (car e) 'curly) (eq? (car e) '<:)) (typedef-expr-name (cadr e))) + (else e))) + +(define (typedef-expr-tvars e) + (cond ((atom? e) '()) + ((eq? (car e) '<:) (typedef-expr-tvars (cadr e))) + ((eq? (car e) 'curly) (cddr e)) + (else '()))) + (define (typevar-expr-name e) (car (analyze-typevar e))) ;; get the list of names from a list of `where` variable expressions diff --git a/test/syntax.jl b/test/syntax.jl index 4e4417dd5a3b6..9e12206ad8325 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -1646,3 +1646,30 @@ end # issue #28576 @test Meta.isexpr(Meta.parse("1 == 2 ?"), :incomplete) @test Meta.isexpr(Meta.parse("1 == 2 ? 3 :"), :incomplete) + +# issue #28593 +macro a28593() + quote + abstract type A28593{S<:Real, V<:AbstractVector{S}} end + end +end + +macro b28593() + quote + struct B28593{S<:Real, V<:AbstractVector{S}} end + end +end + +macro c28593() + quote + primitive type C28593{S<:Real, V<:AbstractVector{S}} 32 end + end +end + +@a28593 +@b28593 +@c28593 + +@test A28593.var.name === :S +@test B28593.var.name === :S +@test C28593.var.name === :S From 157fb343200e00abad048c47fc83de214532ac5c Mon Sep 17 00:00:00 2001 From: tchr Date: Thu, 23 Aug 2018 15:00:26 -0400 Subject: [PATCH 097/110] fix doc-string references to bit-rotted variables x(->v) and v(->itr) in var, varm, std, stdm, & quantiles --- stdlib/Statistics/src/Statistics.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stdlib/Statistics/src/Statistics.jl b/stdlib/Statistics/src/Statistics.jl index 28d2cae7837e3..bc7a857079e88 100644 --- a/stdlib/Statistics/src/Statistics.jl +++ b/stdlib/Statistics/src/Statistics.jl @@ -248,7 +248,7 @@ end Compute the sample variance of a collection `v` with known mean(s) `m`, optionally over the given dimensions. `m` may contain means for each dimension of `v`. If `corrected` is `true`, then the sum is scaled with `n-1`, -whereas the sum is scaled with `n` if `corrected` is `false` where `n = length(x)`. +whereas the sum is scaled with `n` if `corrected` is `false` where `n = length(v)`. !!! note If array contains `NaN` or [`missing`](@ref) values, the result is also @@ -278,7 +278,7 @@ The algorithm will return an estimator of the generative distribution's variance under the assumption that each entry of `v` is an IID drawn from that generative distribution. This computation is equivalent to calculating `sum(abs2, v - mean(v)) / (length(v) - 1)`. If `corrected` is `true`, then the sum is scaled with `n-1`, -whereas the sum is scaled with `n` if `corrected` is `false` where `n = length(x)`. +whereas the sum is scaled with `n` if `corrected` is `false` where `n = length(v)`. The mean `mean` over the region may be provided. !!! note @@ -345,7 +345,7 @@ deviation under the assumption that each entry of `v` is an IID drawn from that distribution. This computation is equivalent to calculating `sqrt(sum((v - mean(v)).^2) / (length(v) - 1))`. A pre-computed `mean` may be provided. If `corrected` is `true`, then the sum is scaled with `n-1`, whereas the sum is scaled with `n` if `corrected` is -`false` where `n = length(x)`. +`false` where `n = length(v)`. !!! note If array contains `NaN` or [`missing`](@ref) values, the result is also @@ -376,7 +376,7 @@ std(iterable; corrected::Bool=true, mean=nothing) = Compute the sample standard deviation of a vector `v` with known mean `m`. If `corrected` is `true`, then the sum is scaled with `n-1`, whereas the sum is -scaled with `n` if `corrected` is `false` where `n = length(x)`. +scaled with `n` if `corrected` is `false` where `n = length(v)`. !!! note If array contains `NaN` or [`missing`](@ref) values, the result is also @@ -882,7 +882,7 @@ probabilities `p` on the interval [0,1]. The keyword argument `sorted` indicates `itr` can be assumed to be sorted. Quantiles are computed via linear interpolation between the points `((k-1)/(n-1), v[k])`, -for `k = 1:n` where `n = length(v)`. This corresponds to Definition 7 of Hyndman and Fan +for `k = 1:n` where `n = length(itr)`. This corresponds to Definition 7 of Hyndman and Fan (1996), and is the same as the R default. !!! note From 293c90424d26d7b090038dd4a7cf5b419f005040 Mon Sep 17 00:00:00 2001 From: Paul Bartlett Date: Fri, 24 Aug 2018 00:24:03 +0100 Subject: [PATCH 098/110] Correct typeof result for one of the Union types (#28843) This union is type-equivalent to `Real`, so the output is a bit misleading, since this just evaluates `typeof(Real)` in disguised form. Remove as suggested by yuyichao. --- doc/src/manual/types.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/src/manual/types.md b/doc/src/manual/types.md index 44eb1c76ea39b..5f307edaa989b 100644 --- a/doc/src/manual/types.md +++ b/doc/src/manual/types.md @@ -1152,9 +1152,6 @@ what their types are: julia> typeof(Rational{Int}) DataType -julia> typeof(Union{Real,Float64,Rational}) -DataType - julia> typeof(Union{Real,String}) Union ``` From d55b04430c9eebc229b6dafd8725697d86acf1b3 Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Thu, 23 Aug 2018 18:25:13 -0500 Subject: [PATCH 099/110] Fix ambiguity test failure when arrayops and LinearAlgebra run on the same worker (#28836) --- test/arrayops.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/arrayops.jl b/test/arrayops.jl index 7c7ae0404510b..3edc8516838eb 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -2455,13 +2455,13 @@ end # Ensure we can hash strange custom structs — and they hash the same in arrays struct totally_not_five26034 end -Base.isequal(::totally_not_five26034, x)=isequal(5,x); -Base.isequal(x, ::totally_not_five26034)=isequal(5,x); +Base.isequal(::totally_not_five26034, x::Number)=isequal(5,x); +Base.isequal(x::Number, ::totally_not_five26034)=isequal(5,x); Base.isequal(::totally_not_five26034, ::totally_not_five26034)=true; Base.hash(::totally_not_five26034, h::UInt)=hash(5, h); import Base.== -==(::totally_not_five26034, x)= (5==x); -==(x,::totally_not_five26034)= (5==x); +==(::totally_not_five26034, x::Number)= (5==x); +==(x::Number,::totally_not_five26034)= (5==x); ==(::totally_not_five26034,::totally_not_five26034)=true; @testset "issue #26034" begin n5 = totally_not_five26034() From eb8a9333b040b8dc86b2ed7a93bb23e70830cf14 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Fri, 24 Aug 2018 21:12:14 +0200 Subject: [PATCH 100/110] Absolutify project path specified with --project and JULIA_PROJECT. (#28625) --- base/initdefs.jl | 3 ++- src/init.c | 2 ++ test/loading.jl | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/base/initdefs.jl b/base/initdefs.jl index 0846a47534886..d93590af4d63c 100644 --- a/base/initdefs.jl +++ b/base/initdefs.jl @@ -138,8 +138,9 @@ function init_load_path() unsafe_string(Base.JLOptions().project) : get(ENV, "JULIA_PROJECT", nothing)) HOME_PROJECT[] = + project == nothing ? nothing : project == "" ? nothing : - project == "@." ? current_project() : project + project == "@." ? current_project() : abspath(project) append!(empty!(LOAD_PATH), paths) end diff --git a/src/init.c b/src/init.c index 98e8bfe7cf4e5..51ae861473f24 100644 --- a/src/init.c +++ b/src/init.c @@ -593,6 +593,8 @@ static void jl_resolve_sysimg_location(JL_IMAGE_SEARCH rel) jl_options.outputbc = abspath(jl_options.outputbc, 0); if (jl_options.machine_file) jl_options.machine_file = abspath(jl_options.machine_file, 0); + if (jl_options.project && strncmp(jl_options.project, "@.", strlen(jl_options.project)) != 0) + jl_options.project = abspath(jl_options.project, 0); const char **cmdp = jl_options.cmds; if (cmdp) { diff --git a/test/loading.jl b/test/loading.jl index 289c25e582b0a..259f55a87c999 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -547,6 +547,22 @@ finally popfirst!(LOAD_PATH) end +@testset "--project and JULIA_PROJECT paths should be absolutified" begin + mktempdir() do dir; cd(dir) do + mkdir("foo") + script = """ + using Test + old = Base.active_project() + cd("foo") + @test Base.active_project() == old + """ + @test success(`$(Base.julia_cmd()) --project=foo -e $(script)`) + withenv("JULIA_PROJECT" => "foo") do + @test success(`$(Base.julia_cmd()) -e $(script)`) + end + end; end +end + ## cleanup after tests ## for env in keys(envs) From 35c67e5fd81c21eef1dc8d05d22ad99af5f9728f Mon Sep 17 00:00:00 2001 From: Harmen Stoppels Date: Fri, 24 Aug 2018 23:56:39 +0300 Subject: [PATCH 101/110] Make sure iterate(::Tuple) does not throw (#28847) --- base/tuple.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/tuple.jl b/base/tuple.jl index 987b6764f1401..518715644f677 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -38,7 +38,7 @@ _setindex(v, i::Integer) = () ## iterating ## -iterate(t::Tuple, i::Int=1) = length(t) < i ? nothing : (t[i], i+1) +iterate(@nospecialize(t::Tuple), i::Int=1) = 1 <= i <= length(t) ? (@inbounds t[i], i+1) : nothing keys(@nospecialize t::Tuple) = OneTo(length(t)) From 145224f3318af5178573c2771216b2d08814e5eb Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Fri, 24 Aug 2018 15:25:31 -0700 Subject: [PATCH 102/110] Support ranges with different integer widths in `preduce` (#28651) --- stdlib/Distributed/src/macros.jl | 2 +- stdlib/Distributed/test/distributed_exec.jl | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/stdlib/Distributed/src/macros.jl b/stdlib/Distributed/src/macros.jl index f04ad345f10bc..15faadb3c31fa 100644 --- a/stdlib/Distributed/src/macros.jl +++ b/stdlib/Distributed/src/macros.jl @@ -251,7 +251,7 @@ end function preduce(reducer, f, R) N = length(R) - chunks = splitrange(N, nworkers()) + chunks = splitrange(Int(N), nworkers()) all_w = workers()[1:length(chunks)] w_exec = Task[] diff --git a/stdlib/Distributed/test/distributed_exec.jl b/stdlib/Distributed/test/distributed_exec.jl index f17d97697c27e..383a6783a311d 100644 --- a/stdlib/Distributed/test/distributed_exec.jl +++ b/stdlib/Distributed/test/distributed_exec.jl @@ -1527,6 +1527,14 @@ end a27933 = :_not_defined_27933 @test remotecall_fetch(()->a27933, first(workers())) === a27933 +# PR #28651 +for T in (UInt8, Int8, UInt16, Int16, UInt32, Int32, UInt64) + n = @distributed (+) for i in Base.OneTo(T(10)) + i + end + @test n == 55 +end + # Run topology tests last after removing all workers, since a given # cluster at any time only supports a single topology. rmprocs(workers()) From 7e1f739d3c628e387cc5827a35ca086fc17006c6 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Sat, 25 Aug 2018 17:45:59 +0200 Subject: [PATCH 103/110] fix doccing call overload without named argument (#28875) --- base/docs/Docs.jl | 2 +- test/docs.jl | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/base/docs/Docs.jl b/base/docs/Docs.jl index c9de490bcb67f..d409eea9a6ca8 100644 --- a/base/docs/Docs.jl +++ b/base/docs/Docs.jl @@ -281,7 +281,7 @@ function astname(x::Expr, ismacro::Bool) ismacro ? macroname(x) : x # Call overloading, e.g. `(a::A)(b) = b` or `function (a::A)(b) b end` should document `A(b)` elseif (isexpr(x, :function) || isexpr(x, :(=))) && isexpr(x.args[1], :call) && isexpr(x.args[1].args[1], :(::)) - return astname(x.args[1].args[1].args[2], ismacro) + return astname(x.args[1].args[1].args[end], ismacro) else n = isexpr(x, (:module, :struct)) ? 2 : 1 astname(x.args[n], ismacro) diff --git a/test/docs.jl b/test/docs.jl index 3a925d65a4334..c6cbb3847ae28 100644 --- a/test/docs.jl +++ b/test/docs.jl @@ -1121,6 +1121,13 @@ struct A_20087 end @test docstrings_equal(@doc(A_20087()), doc"a") +struct B_20087 end + +"""b""" +(::B_20087)() = a + +@test docstrings_equal(@doc(B_20087()), doc"b") + # issue #27832 _last_atdoc = Core.atdoc From a5bfabccd8d9c351cc3b0026992fe7314ff022db Mon Sep 17 00:00:00 2001 From: Ronan Arraes Jardim Chagas Date: Sat, 25 Aug 2018 12:46:24 -0300 Subject: [PATCH 104/110] Fix note tag in the documentation (#28877) --- doc/src/manual/performance-tips.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index cd81e9eaf0c59..a3e08d63ad605 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -1151,7 +1151,7 @@ The common idiom of using 1:n to index into an AbstractArray is not safe if the and may cause a segmentation fault if bounds checking is turned off. Use `LinearIndices(x)` or `eachindex(x)` instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays)). -!!!note +!!! note While `@simd` needs to be placed directly in front of an innermost `for` loop, both `@inbounds` and `@fastmath` can be applied to either single expressions or all the expressions that appear within nested blocks of code, e.g., using `@inbounds begin` or `@inbounds for ...`. From 910736559f32c1c14a9d099dfdfad25ba2f71315 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 25 Aug 2018 18:06:05 -0400 Subject: [PATCH 105/110] Update variables after normalizing varargs (#28812) This code was a bit odd. It started by normalzing the varargs, but then used `va0` and `va1` from the original, unnormalized type. Either the unormalized version was intended in which case normalizing first was wasteful, or the normalized version was intended in which case the code was incorrct. Talking with Jeff, he believes the latter was intended, so update the code to do that instead. --- src/jltypes.c | 28 +++++++++++++++------------- test/core.jl | 4 ++++ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/jltypes.c b/src/jltypes.c index a9f8fff425b02..6258b3bfb3cdb 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -1131,9 +1131,9 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value } jl_datatype_t *ndt = NULL; - JL_GC_PUSH2(&p, &ndt); - jl_value_t *last = iparams[ntp - 1]; + JL_GC_PUSH3(&p, &ndt, &last); + int isvatuple = 0; if (istuple && ntp > 0 && jl_is_vararg_type(last)) { isvatuple = 1; @@ -1149,17 +1149,13 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value JL_GC_POP(); return (jl_value_t*)jl_anytuple_type; } - { - JL_GC_PUSH1(&last); - jl_value_t *last2 = normalize_vararg(last); - if (last2 != last) { - last = last2; - p = jl_alloc_svec(ntp); - for (size_t i = 0; i < ntp-1; i++) - jl_svecset(p, i, iparams[i]); - jl_svecset(p, ntp-1, last); - } - JL_GC_POP(); + int did_normalize = 0; + jl_value_t *last2 = normalize_vararg(last); + if (last2 != last) { + last = last2; + did_normalize = 1; + va = jl_unwrap_unionall(last); + va0 = jl_tparam0(va); va1 = jl_tparam1(va); } if (jl_is_long(va1)) { ssize_t nt = jl_unbox_long(va1); @@ -1183,6 +1179,12 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value return ndt; } } + if (did_normalize) { + p = jl_alloc_svec(ntp); + for (size_t i = 0; i < ntp-1; i++) + jl_svecset(p, i, iparams[i]); + jl_svecset(p, ntp-1, last); + } } // move array of instantiated parameters to heap; we need to keep it diff --git a/test/core.jl b/test/core.jl index 822fa6fca76c7..f6f467183de83 100644 --- a/test/core.jl +++ b/test/core.jl @@ -6702,3 +6702,7 @@ end @test_throws ErrorException Array{Int, 2}(undef, 0, -10) @test_throws ErrorException Array{Int, 2}(undef, -10, 0) @test_throws ErrorException Array{Int, 2}(undef, -1, -1) + +# issue #28812 +@test Tuple{Vararg{Array{T},3} where T} === Tuple{Array,Array,Array} +@test Tuple{Vararg{Array{T} where T,3}} === Tuple{Array,Array,Array} From b18f589b978ea2b16874a355057b17ba47783591 Mon Sep 17 00:00:00 2001 From: Scott Thomas Date: Sat, 25 Aug 2018 23:43:25 +0000 Subject: [PATCH 106/110] Fix typo in length(::AbstractString) doc [ci skip] (#28867) --- base/strings/basic.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/strings/basic.jl b/base/strings/basic.jl index 37117e3910846..603e13c8beee9 100644 --- a/base/strings/basic.jl +++ b/base/strings/basic.jl @@ -326,7 +326,7 @@ isless(a::Symbol, b::Symbol) = cmp(a, b) < 0 The number of characters in string `s` from indices `i` through `j`. This is computed as the number of code unit indices from `i` to `j` which are valid -character indices. Without only a single string argument, this computes the +character indices. With only a single string argument, this computes the number of characters in the entire string. With `i` and `j` arguments it computes the number of indices between `i` and `j` inclusive that are valid indices in the string `s`. In addition to in-bounds values, `i` may take the From 304cbd991a84f981d160bdaeca7cdf8e762ba5cd Mon Sep 17 00:00:00 2001 From: Jan Magnusson Date: Sun, 26 Aug 2018 11:50:28 +0200 Subject: [PATCH 107/110] improve docstring of pathof (#28817) * improve docstring of pathof --- base/loading.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base/loading.jl b/base/loading.jl index f55f75498d90e..18a8765d68480 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -254,6 +254,9 @@ locate_package(::Nothing) = nothing Return the path of `m.jl` file that was used to `import` module `m`, or `nothing` if `m` was not imported from a package. + +Use [`dirname`](@ref) to get the directory part and [`basename`](@ref) +to get the file name part of the path. """ function pathof(m::Module) pkgid = get(Base.module_keys, m, nothing) From 24de931f41d205574b00e89b12388691210add3f Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sun, 26 Aug 2018 04:51:56 -0500 Subject: [PATCH 108/110] issubset: check IteratorSize trait before calling length (#28871) --- base/abstractset.jl | 17 +++++++++-------- test/sets.jl | 13 +++++++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/base/abstractset.jl b/base/abstractset.jl index 2c2ec47c0c041..100383a126a1d 100644 --- a/base/abstractset.jl +++ b/base/abstractset.jl @@ -226,14 +226,15 @@ end <=(l::AbstractSet, r::AbstractSet) = l ⊆ r function issubset(l, r) - - rlen = length(r) - #This threshold was empirically determined by repeatedly - #sampling using these two methods. - lenthresh = 70 - - if rlen > lenthresh && !isa(r, AbstractSet) - return issubset(l, Set(r)) + if haslength(r) + rlen = length(r) + #This threshold was empirically determined by repeatedly + #sampling using these two methods (see #26198) + lenthresh = 70 + + if rlen > lenthresh && !isa(r, AbstractSet) + return issubset(l, Set(r)) + end end for elt in l diff --git a/test/sets.jl b/test/sets.jl index ea523d43afb72..35155633abb9d 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -604,3 +604,16 @@ end end end end + +struct OpenInterval{T} + lower::T + upper::T +end +Base.in(x, i::OpenInterval) = i.lower < x < i.upper +Base.IteratorSize(::Type{<:OpenInterval}) = Base.SizeUnknown() + +@testset "Continuous sets" begin + i = OpenInterval(2, 4) + @test 3 ∈ i + @test issubset(3, i) +end From 731424953a325323fce325afa4c36433d96e2b51 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Sun, 26 Aug 2018 12:16:46 +0200 Subject: [PATCH 109/110] improve performance for string(...) (#28876) * improve performance for various string methods --- base/strings/io.jl | 38 +++++++++++++++++++++++++------------- base/strings/substring.jl | 31 ++++++++++++++++++++++--------- test/strings/basic.jl | 1 + 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/base/strings/io.jl b/base/strings/io.jl index 64b9a613c084e..e2a759c473189 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -103,31 +103,43 @@ function sprint(f::Function, args...; context=nothing, sizehint::Integer=0) String(resize!(s.data, s.size)) end -tostr_sizehint(x) = 0 +tostr_sizehint(x) = 8 tostr_sizehint(x::AbstractString) = lastindex(x) tostr_sizehint(x::Float64) = 20 tostr_sizehint(x::Float32) = 12 -function print_to_string(xs...; env=nothing) +function print_to_string(xs...) if isempty(xs) return "" end + siz = 0 + for x in xs + siz += tostr_sizehint(x) + end # specialized for performance reasons - s = IOBuffer(sizehint=tostr_sizehint(xs[1])) - if env !== nothing - env_io = IOContext(s, env) - for x in xs - print(env_io, x) - end - else - for x in xs - print(s, x) - end + s = IOBuffer(sizehint=siz) + for x in xs + print(s, x) end String(resize!(s.data, s.size)) end -string_with_env(env, xs...) = print_to_string(xs...; env=env) +function string_with_env(env, xs...) + if isempty(xs) + return "" + end + siz = 0 + for x in xs + siz += tostr_sizehint(x) + end + # specialized for performance reasons + s = IOBuffer(sizehint=siz) + env_io = IOContext(s, env) + for x in xs + print(env_io, x) + end + String(resize!(s.data, s.size)) +end """ string(xs...) diff --git a/base/strings/substring.jl b/base/strings/substring.jl index d6fba1b41c9bf..9b9e0d1e7424b 100644 --- a/base/strings/substring.jl +++ b/base/strings/substring.jl @@ -142,19 +142,32 @@ function reverse(s::Union{String,SubString{String}})::String end end -function string(a::Union{String, SubString{String}}...) - if length(a) == 1 - return String(a[1]) - end +string(a::String) = String(a) +string(a::SubString{String}) = String(a) + +function string(a::Union{Char, String, SubString{String}}...) n = 0 - for str in a - n += sizeof(str) + for v in a + if v isa Char + n += codelen(v) + else + n += sizeof(v) + end end out = _string_n(n) offs = 1 - for str in a - unsafe_copyto!(pointer(out,offs), pointer(str), sizeof(str)) - offs += sizeof(str) + for v in a + if v isa Char + x = bswap(reinterpret(UInt32, v)) + for j in 1:codelen(v) + unsafe_store!(pointer(out, offs), x % UInt8) + offs += 1 + x >>= 8 + end + else + unsafe_copyto!(pointer(out,offs), pointer(v), sizeof(v)) + offs += sizeof(v) + end end return out end diff --git a/test/strings/basic.jl b/test/strings/basic.jl index 034d45bee9596..521dfa6d52b99 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -34,6 +34,7 @@ using Random @test string("∀∃", "1∀∃") === "∀∃1∀∃" @test string(SubString("∀∃"), SubString("1∀∃", 2)) === "∀∃∀∃" @test string(s"123") === s"123" + @test string("123", 'α', SubString("1∀∃", 2), 'a', "foo") === "123α∀∃afoo" codegen_egal_of_strings(x, y) = (x===y, x!==y) @test codegen_egal_of_strings(string("ab", 'c'), "abc") === (true, false) let strs = ["", "a", "a b c", "до свидания"] From a2a1506b6e4174e4dc2489b04dece3b7d66c973d Mon Sep 17 00:00:00 2001 From: Andreas Noack Date: Sun, 26 Aug 2018 12:17:16 +0200 Subject: [PATCH 110/110] Compare Symbols and Chars more efficiently in Cholesky (#28873) --- stdlib/LinearAlgebra/src/cholesky.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stdlib/LinearAlgebra/src/cholesky.jl b/stdlib/LinearAlgebra/src/cholesky.jl index 3e95a92d3a0d4..5db318fabf999 100644 --- a/stdlib/LinearAlgebra/src/cholesky.jl +++ b/stdlib/LinearAlgebra/src/cholesky.jl @@ -340,11 +340,11 @@ function getproperty(C::Cholesky, d::Symbol) Cuplo = getfield(C, :uplo) info = getfield(C, :info) if d == :U - return UpperTriangular(Symbol(Cuplo) == d ? Cfactors : copy(Cfactors')) + return UpperTriangular(Cuplo === char_uplo(d) ? Cfactors : copy(Cfactors')) elseif d == :L - return LowerTriangular(Symbol(Cuplo) == d ? Cfactors : copy(Cfactors')) + return LowerTriangular(Cuplo === char_uplo(d) ? Cfactors : copy(Cfactors')) elseif d == :UL - return (Symbol(Cuplo) == :U ? UpperTriangular(Cfactors) : LowerTriangular(Cfactors)) + return (Cuplo === 'U' ? UpperTriangular(Cfactors) : LowerTriangular(Cfactors)) else return getfield(C, d) end