Skip to content

Commit

Permalink
Merge branch 'master' into ib/stdlib_parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
IanButterworth authored Mar 6, 2024
2 parents 5a82512 + 90d84d4 commit b621e03
Show file tree
Hide file tree
Showing 16 changed files with 145 additions and 56 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ else ifeq ($(JULIA_BUILD_MODE),debug)
-$(INSTALL_M) $(build_libdir)/libjulia-internal-debug.dll.a $(DESTDIR)$(libdir)/
endif
-$(INSTALL_M) $(wildcard $(build_private_libdir)/*.a) $(DESTDIR)$(private_libdir)/
-rm -f $(DESTDIR)$(private_libdir)/sys-o.a

# We have a single exception; we want 7z.dll to live in private_libexecdir,
# not bindir, so that 7z.exe can find it.
Expand Down
4 changes: 0 additions & 4 deletions base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,11 @@ function src_inlining_policy(interp::AbstractInterpreter,
return src_inlineable
elseif isa(src, IRCode)
return true
elseif isa(src, SemiConcreteResult)
return true
end
@assert !isa(src, CodeInstance) # handled by caller
return false
end

function inlining_policy end # deprecated legacy name used by Cthulhu

struct InliningState{Interp<:AbstractInterpreter}
edges::Vector{Any}
world::UInt
Expand Down
3 changes: 2 additions & 1 deletion base/compiler/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,8 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
exc_bestguess = refine_exception_type(frame.exc_bestguess, effects)
# propagate newly inferred source to the inliner, allowing efficient inlining w/o deserialization:
# note that this result is cached globally exclusively, we can use this local result destructively
volatile_inf_result = isinferred && (force_inline || src_inlining_policy(interp, result.src, NoCallInfo(), IR_FLAG_NULL) !== nothing) ?
volatile_inf_result = (isinferred && (force_inline ||
src_inlining_policy(interp, result.src, NoCallInfo(), IR_FLAG_NULL))) ?
VolatileInferenceResult(result) : nothing
return EdgeCallResult(frame.bestguess, exc_bestguess, edge, effects, volatile_inf_result)
elseif frame === true
Expand Down
1 change: 1 addition & 0 deletions base/pointer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ unsafe_convert(::Type{Ptr{Int8}}, s::String) = ccall(:jl_string_ptr, Ptr{Int8},

cconvert(::Type{<:Ptr}, a::Array) = getfield(a, :ref)
unsafe_convert(::Type{Ptr{S}}, a::AbstractArray{T}) where {S,T} = convert(Ptr{S}, unsafe_convert(Ptr{T}, a))
unsafe_convert(::Type{Ptr{T}}, a::Array{T}) where {T} = unsafe_convert(Ptr{T}, a.ref)
unsafe_convert(::Type{Ptr{T}}, a::AbstractArray{T}) where {T} = error("conversion to pointer not defined for $(typeof(a))")
# TODO: add this deprecation to give a better error:
# cconvert(::Type{<:Ptr}, a::AbstractArray) = error("conversion to pointer not defined for $(typeof(a))")
Expand Down
2 changes: 1 addition & 1 deletion base/precompilation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ function precompilepkgs(pkgs::Vector{String}=String[]; internal_call::Bool=false
# TODO: actually handle packages from other envs in the stack
return
else
error("No direct dependencies outside of the sysimage found matching $(repr([p.name for p in pkgs]))")
error("No direct dependencies outside of the sysimage found matching $(pkgs)")
end
end

Expand Down
4 changes: 2 additions & 2 deletions base/version.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ const VInt = UInt32
VersionNumber
Version number type which follows the specifications of
[semantic versioning (semver)](https://semver.org/), composed of major, minor
[semantic versioning (semver)](https://semver.org/spec/v2.0.0-rc.2.html), composed of major, minor
and patch numeric values, followed by pre-release and build
alphanumeric annotations.
`VersionNumber` objects can be compared with all of the standard comparison
operators (`==`, `<`, `<=`, etc.), with the result following semver rules.
operators (`==`, `<`, `<=`, etc.), with the result following semver v2.0.0-rc.2 rules.
`VersionNumber` has the following public fields:
- `v.major::Integer`
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0d226d1a3cf5c4cf207788fc3c5ba50c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
e9516466573c24d2bd90645edbdc9c2dbe3f4f4e1704d665525429ff6a463208ff849ebb7c4f9d2d2627d69d1b2cc56a9b305a89e30a0e16b666cbd91f34ced3
2 changes: 1 addition & 1 deletion doc/src/manual/strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -1142,7 +1142,7 @@ some confusion regarding the matter.

Version numbers can easily be expressed with non-standard string literals of the form [`v"..."`](@ref @v_str).
Version number literals create [`VersionNumber`](@ref) objects which follow the
specifications of [semantic versioning](https://semver.org/),
specifications of [semantic versioning 2.0.0-rc2](https://semver.org/spec/v2.0.0-rc.2.html),
and therefore are composed of major, minor and patch numeric values, followed by pre-release and
build alphanumeric annotations. For example, `v"0.2.1-rc1+win64"` is broken into major version
`0`, minor version `2`, patch version `1`, pre-release `rc1` and build `win64`. When entering
Expand Down
4 changes: 2 additions & 2 deletions doc/src/tutorials/creating-packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -563,10 +563,10 @@ duplicated into `[extras]`. This is an unfortunate duplication, but without
doing this the project verifier under older Julia versions will throw an error
if it finds packages under `[compat]` that is not listed in `[extras]`.

## Package naming guidelines
## Package naming rules

Package names should be sensible to most Julia users, *even to those who are not domain experts*.
The following guidelines apply to the `General` registry but may be useful for other package
The following rules apply to the `General` registry but may be useful for other package
registries as well.

Since the `General` registry belongs to the entire community, people may have opinions about
Expand Down
100 changes: 100 additions & 0 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2644,6 +2644,104 @@ static jl_cgval_t emit_unionload(jl_codectx_t &ctx, Value *addr, Value *ptindex,
return mark_julia_slot(fsz > 0 ? addr : nullptr, jfty, tindex, tbaa);
}

static bool isTBAA(MDNode *TBAA, std::initializer_list<const char*> const strset)
{
if (!TBAA)
return false;
while (TBAA->getNumOperands() > 1) {
TBAA = cast<MDNode>(TBAA->getOperand(1).get());
auto str = cast<MDString>(TBAA->getOperand(0))->getString();
for (auto str2 : strset) {
if (str == str2) {
return true;
}
}
}
return false;
}

// Check if this is a load from an immutable value. The easiest
// way to do so is to look at the tbaa and see if it derives from
// jtbaa_immut.
static bool isLoadFromImmut(LoadInst *LI)
{
if (LI->getMetadata(LLVMContext::MD_invariant_load))
return true;
MDNode *TBAA = LI->getMetadata(LLVMContext::MD_tbaa);
if (isTBAA(TBAA, {"jtbaa_immut", "jtbaa_const", "jtbaa_datatype", "jtbaa_memoryptr", "jtbaa_memorylen", "jtbaa_memoryown"}))
return true;
return false;
}

static bool isConstGV(GlobalVariable *gv)
{
return gv->isConstant() || gv->getMetadata("julia.constgv");
}

// Check if this is can be traced through constant loads to an constant global
// or otherwise globally rooted value.
// Almost all `tbaa_const` loads satisfies this with the exception of
// task local constants which are constant as far as the code is concerned but aren't
// global constants. For task local constant `task_local` will be true when this function
// returns.
// Unlike this function in llvm-late-gc-lowering, we do not examine PhiNode, as those are not emitted yet
static bool isLoadFromConstGV(LoadInst *LI);
static bool isLoadFromConstGV(Value *v)
{
v = v->stripInBoundsOffsets();
if (auto LI = dyn_cast<LoadInst>(v))
return isLoadFromConstGV(LI);
if (auto gv = dyn_cast<GlobalVariable>(v))
return isConstGV(gv);
// null pointer
if (isa<ConstantData>(v))
return true;
// literal pointers
if (auto CE = dyn_cast<ConstantExpr>(v))
return (CE->getOpcode() == Instruction::IntToPtr &&
isa<ConstantData>(CE->getOperand(0)));
if (auto SL = dyn_cast<SelectInst>(v))
return (isLoadFromConstGV(SL->getTrueValue()) &&
isLoadFromConstGV(SL->getFalseValue()));
if (auto call = dyn_cast<CallInst>(v)) {
auto callee = call->getCalledFunction();
if (callee && callee->getName() == "julia.typeof") {
return true;
}
if (callee && callee->getName() == "julia.get_pgcstack") {
return true;
}
if (callee && callee->getName() == "julia.gc_loaded") {
return isLoadFromConstGV(call->getArgOperand(0)) &&
isLoadFromConstGV(call->getArgOperand(1));
}
}
if (isa<Argument>(v)) {
return true;
}
return false;
}

// The white list implemented here and above in `isLoadFromConstGV(Value*)` should
// cover all the cases we and LLVM generates.
static bool isLoadFromConstGV(LoadInst *LI)
{
// We only emit single slot GV in codegen
// but LLVM global merging can change the pointer operands to GEPs/bitcasts
auto load_base = LI->getPointerOperand()->stripInBoundsOffsets();
assert(load_base); // Static analyzer
auto gv = dyn_cast<GlobalVariable>(load_base);
if (isLoadFromImmut(LI)) {
if (gv)
return true;
return isLoadFromConstGV(load_base);
}
if (gv)
return isConstGV(gv);
return false;
}


static MDNode *best_field_tbaa(jl_codectx_t &ctx, const jl_cgval_t &strct, jl_datatype_t *jt, unsigned idx, size_t byte_offset)
{
auto tbaa = strct.tbaa;
Expand All @@ -2664,6 +2762,8 @@ static MDNode *best_field_tbaa(jl_codectx_t &ctx, const jl_cgval_t &strct, jl_da
return ctx.tbaa().tbaa_arraysize;
}
}
if (strct.V && jl_field_isconst(jt, idx) && isLoadFromConstGV(strct.V))
return ctx.tbaa().tbaa_const;
return tbaa;
}

Expand Down
72 changes: 30 additions & 42 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8267,18 +8267,18 @@ static jl_llvm_functions_t

// step 7. allocate local variables slots
// must be in the first basic block for the llvm mem2reg pass to work
auto allocate_local = [&](jl_varinfo_t &varinfo, jl_sym_t *s) {
auto allocate_local = [&ctx, &dbuilder, &debuginfo, topdebugloc, va, debug_enabled, M](jl_varinfo_t &varinfo, jl_sym_t *s, int i) {
jl_value_t *jt = varinfo.value.typ;
assert(!varinfo.boxroot); // variables shouldn't have memory locs already
if (varinfo.value.constant) {
// no need to explicitly load/store a constant/ghost value
alloc_def_flag(ctx, varinfo);
return;
}
else if (varinfo.isArgument && !(specsig && i == (size_t)ctx.vaSlot)) {
// if we can unbox it, just use the input pointer
if (i != (size_t)ctx.vaSlot && jl_is_concrete_immutable(jt))
return;
else if (varinfo.isArgument && (!va || ctx.vaSlot == -1 || i != ctx.vaSlot)) {
// just use the input pointer, if we have it
// (we will need to attach debuginfo later to it)
return;
}
else if (jl_is_uniontype(jt)) {
bool allunbox;
Expand All @@ -8289,6 +8289,7 @@ static jl_llvm_functions_t
varinfo.value = mark_julia_slot(lv, jt, NULL, ctx.tbaa().tbaa_stack);
varinfo.pTIndex = emit_static_alloca(ctx, getInt8Ty(ctx.builder.getContext()));
setName(ctx.emission_context, varinfo.pTIndex, "tindex");
// TODO: attach debug metadata to this variable
}
else if (allunbox) {
// all ghost values just need a selector allocated
Expand All @@ -8297,6 +8298,7 @@ static jl_llvm_functions_t
varinfo.pTIndex = lv;
varinfo.value.tbaa = NULL;
varinfo.value.isboxed = false;
// TODO: attach debug metadata to this variable
}
if (lv || allunbox)
alloc_def_flag(ctx, varinfo);
Expand All @@ -8323,29 +8325,21 @@ static jl_llvm_functions_t
}
return;
}
if (!varinfo.isArgument || // always need a slot if the variable is assigned
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`)
AllocaInst *av = new AllocaInst(ctx.types().T_prjlvalue, M->getDataLayout().getAllocaAddrSpace(),
nullptr, Align(sizeof(jl_value_t*)), jl_symbol_name(s), /*InsertBefore*/ctx.topalloca);
StoreInst *SI = new StoreInst(Constant::getNullValue(ctx.types().T_prjlvalue), av, false, Align(sizeof(void*)));
SI->insertAfter(ctx.topalloca);
varinfo.boxroot = av;
if (debug_enabled && varinfo.dinfo) {
DIExpression *expr;
if ((Metadata*)varinfo.dinfo->getType() == debuginfo.jl_pvalue_dillvmt) {
expr = dbuilder.createExpression();
}
else {
SmallVector<uint64_t, 8> addr;
addr.push_back(llvm::dwarf::DW_OP_deref);
expr = dbuilder.createExpression(addr);
}
dbuilder.insertDeclare(av, varinfo.dinfo, expr,
topdebugloc,
ctx.builder.GetInsertBlock());
}
// otherwise give it a boxroot in this function
AllocaInst *av = new AllocaInst(ctx.types().T_prjlvalue, M->getDataLayout().getAllocaAddrSpace(),
nullptr, Align(sizeof(jl_value_t*)), jl_symbol_name(s), /*InsertBefore*/ctx.topalloca);
StoreInst *SI = new StoreInst(Constant::getNullValue(ctx.types().T_prjlvalue), av, false, Align(sizeof(void*)));
SI->insertAfter(ctx.topalloca);
varinfo.boxroot = av;
if (debug_enabled && varinfo.dinfo) {
SmallVector<uint64_t, 1> addr;
DIExpression *expr;
if ((Metadata*)varinfo.dinfo->getType() != debuginfo.jl_pvalue_dillvmt)
addr.push_back(llvm::dwarf::DW_OP_deref);
expr = dbuilder.createExpression(addr);
dbuilder.insertDeclare(av, varinfo.dinfo, expr,
topdebugloc,
ctx.builder.GetInsertBlock());
}
};

Expand All @@ -8359,7 +8353,7 @@ static jl_llvm_functions_t
varinfo.usedUndef = false;
continue;
}
allocate_local(varinfo, s);
allocate_local(varinfo, s, (int)i);
}

std::map<int, int> upsilon_to_phic;
Expand Down Expand Up @@ -8402,7 +8396,7 @@ static jl_llvm_functions_t
vi.used = true;
vi.isVolatile = true;
vi.value = mark_julia_type(ctx, (Value*)NULL, false, typ);
allocate_local(vi, jl_symbol("phic"));
allocate_local(vi, jl_symbol("phic"), -1);
}
}
}
Expand Down Expand Up @@ -8542,7 +8536,7 @@ static jl_llvm_functions_t
ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, argPtr, Align(sizeof(void*))),
false, vi.value.typ));
theArg = mark_julia_type(ctx, load, true, vi.value.typ);
if (debug_enabled && vi.dinfo && !vi.boxroot && !vi.value.V) {
if (debug_enabled && vi.dinfo && !vi.boxroot) {
SmallVector<uint64_t, 8> addr;
addr.push_back(llvm::dwarf::DW_OP_deref);
addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
Expand All @@ -8561,21 +8555,15 @@ static jl_llvm_functions_t
assert(vi.value.V == NULL && "unexpected variable slot created for argument");
// keep track of original (possibly boxed) value to avoid re-boxing or moving
vi.value = theArg;
if (specsig && theArg.V && debug_enabled && vi.dinfo) {
SmallVector<uint64_t, 8> addr;
Value *parg;
if (debug_enabled && vi.dinfo && theArg.V) {
if (theArg.ispointer()) {
parg = theArg.V;
if ((Metadata*)vi.dinfo->getType() != debuginfo.jl_pvalue_dillvmt)
addr.push_back(llvm::dwarf::DW_OP_deref);
dbuilder.insertDeclare(theArg.V, vi.dinfo, dbuilder.createExpression(),
topdebugloc, ctx.builder.GetInsertBlock());
}
else {
parg = ctx.builder.CreateAlloca(theArg.V->getType(), NULL, jl_symbol_name(s));
ctx.builder.CreateStore(theArg.V, parg);
dbuilder.insertDbgValueIntrinsic(theArg.V, vi.dinfo, dbuilder.createExpression(),
topdebugloc, ctx.builder.GetInsertBlock());
}
dbuilder.insertDeclare(parg, vi.dinfo, dbuilder.createExpression(addr),
topdebugloc,
ctx.builder.GetInsertBlock());
}
}
else {
Expand Down
2 changes: 1 addition & 1 deletion stdlib/Pkg.version
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PKG_BRANCH = master
PKG_SHA1 = 48eea8dbd7b651cdc932b909c1b718bb9c3f94f4
PKG_SHA1 = e7d740ac82fa4c289bb58f9acb6e60eebb6d8a8e
PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git
PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1
2 changes: 2 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8127,3 +8127,5 @@ let M = @__MODULE__
@test Core.set_binding_type!(M, :a_typed_global) === nothing
@test Core.get_binding_type(M, :a_typed_global) === Tuple{Union{Integer,Nothing}}
end

@test Base.unsafe_convert(Ptr{Int}, [1]) !== C_NULL

0 comments on commit b621e03

Please sign in to comment.