Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
vchuravy committed Oct 16, 2024
1 parent e2af2b4 commit d1f0801
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 54 deletions.
4 changes: 3 additions & 1 deletion src/JuliaDialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@

namespace julia {

enum class AddressSoace {
enum AddressSpace {
Generic = 0,
Tracked = 10,
Derived = 11,
CalleeRooted = 12,
Loaded = 13,
FirstSpecial = Tracked,
LastSpecial = Loaded,
};

} // namespace xd
Expand Down
27 changes: 27 additions & 0 deletions src/JuliaDialect.td
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
include "llvm-dialects/Dialect/Dialect.td"

def Speculatable : LlvmEnumAttributeTrait<"Speculatable">;


def NonNull : LlvmEnumAttributeTrait<"NonNull">;
def NoUndef : LlvmEnumAttributeTrait<"NoUndef">;
def NoCapture : LlvmEnumAttributeTrait<"NoCapture">;
def ReadNone : LlvmEnumAttributeTrait<"ReadNone">;

def JuliaDialect : Dialect {
let name = "julia";
let cppNamespace = "julia";
Expand Down Expand Up @@ -48,3 +56,22 @@ def GetPGCStackOrNew : JuliaOp<"get_pgcstack_or_new",
let description = [{}];
}

def GCLoaded : JuliaOp<"gc_loaded",
[Memory<[]>, NoSync, NoUnwind, Speculatable, WillReturn, NoRecurse]> {
let results = (outs LoadedPtr:$result);
let arguments = (ins TrackedPtr:$base, Ptr:$tracked);
let summary = "";
let description = [{}];
}

// declare nonnull noundef ptr(Loaded) @"julia.gc_loaded"(ptr(Tracked) nocapture nonnull noundef readnone, ptr nonnull noundef readnone)


// AttrBuilder RetAttrs(C);
// RetAttrs.addAttribute(Attribute::NonNull);
// RetAttrs.addAttribute(Attribute::NoUndef);
// return AttributeList::get(C, AttributeSet::get(C,FnAttrs), AttributeSet::get(C,RetAttrs),
// { Attributes(C, {Attribute::NonNull, Attribute::NoUndef, Attribute::ReadNone, Attribute::NoCapture}),
// Attributes(C, {Attribute::NonNull, Attribute::NoUndef, Attribute::ReadNone}) });
// },
// };
5 changes: 5 additions & 0 deletions src/aotcompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
#include <llvm/Support/FormatAdapters.h>
#include <llvm/Linker/Linker.h>

#include <llvm-dialects/Dialect/ContextExtension.h>
#include <JuliaDialect.h>

using namespace llvm;

Expand Down Expand Up @@ -1491,6 +1493,7 @@ static SmallVector<AOTOutputs, 16> add_output(Module &M, TargetMachine &TM, Stri
for (unsigned i = 0; i < threads; i++) {
std::function<void()> func = [&, i]() {
LLVMContext ctx;
auto dialectContext = llvm_dialects::DialectContext::make<julia::JuliaDialect>(ctx);
#if JL_LLVM_VERSION < 170000
SetOpaquePointer(ctx);
#endif
Expand Down Expand Up @@ -1702,6 +1705,7 @@ void jl_dump_native_impl(void *native_code,
if (z) {
JL_TIMING(NATIVE_AOT, NATIVE_Sysimg);
LLVMContext Context;
auto dialectContext = llvm_dialects::DialectContext::make<julia::JuliaDialect>(Context);
#if JL_LLVM_VERSION < 170000
SetOpaquePointer(Context);
#endif
Expand Down Expand Up @@ -1849,6 +1853,7 @@ void jl_dump_native_impl(void *native_code,
{
JL_TIMING(NATIVE_AOT, NATIVE_Metadata);
LLVMContext Context;
auto dialectContext = llvm_dialects::DialectContext::make<julia::JuliaDialect>(Context);
#if JL_LLVM_VERSION < 170000
SetOpaquePointer(Context);
#endif
Expand Down
8 changes: 4 additions & 4 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3032,10 +3032,10 @@ static bool isLoadFromConstGV(Value *v)
if (callee && callee->getName() == "julia.typeof") {
return true;
}
if (callee && callee->getName() == "julia.get_pgcstack") {
if (isa<julia::GetPGCStack>(callee)) {
return true;
}
if (callee && callee->getName() == "julia.gc_loaded") {
if (isa<julia::GCLoaded>(callee)) {
return isLoadFromConstGV(call->getArgOperand(0)) &&
isLoadFromConstGV(call->getArgOperand(1));
}
Expand Down Expand Up @@ -3375,7 +3375,7 @@ static Value *emit_genericmemoryptr(jl_codectx_t &ctx, Value *mem, const jl_data
Value *ptr = LI;
if (AS) {
assert(AS == AddressSpace::Loaded);
ptr = ctx.builder.CreateCall(prepare_call(gc_loaded_func), { mem, ptr });
ptr = ctx.builder.create<julia::GCLoaded>(mem, ptr);
}
setName(ctx.emission_context, ptr, "memory_data");
return ptr;
Expand Down Expand Up @@ -4713,7 +4713,7 @@ static Value *emit_memoryref_ptr(jl_codectx_t &ctx, const jl_cgval_t &ref, const
GEPlist.push_back(GEP);
data = GEP->getPointerOperand()->stripPointerCastsSameRepresentation();
}
data = ctx.builder.CreateCall(prepare_call(gc_loaded_func), { mem, data });
data = ctx.builder.create<julia::GCLoaded>(mem, data);
if (!GEPlist.empty()) {
for (auto &GEP : make_range(GEPlist.rbegin(), GEPlist.rend())) {
GetElementPtrInst *GEP2 = cast<GetElementPtrInst>(GEP->clone());
Expand Down
29 changes: 0 additions & 29 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1512,35 +1512,6 @@ static const auto pointer_from_objref_func = new JuliaFunction<>{
Attributes(C, {Attribute::NonNull}),
None); },
};
static const auto gc_loaded_func = new JuliaFunction<>{
"julia.gc_loaded",
// # memory(none) nosync nounwind speculatable willreturn norecurse
// declare nonnull noundef ptr(Loaded) @"julia.gc_loaded"(ptr(Tracked) nocapture nonnull noundef readnone, ptr nonnull noundef readnone)
// top:
// %metadata GC base pointer is ptr(Tracked)
// ret addrspacecast ptr to ptr(Loaded)
[](LLVMContext &C) { return FunctionType::get(PointerType::get(JuliaType::get_prjlvalue_ty(C), AddressSpace::Loaded),
{JuliaType::get_prjlvalue_ty(C), PointerType::get(JuliaType::get_prjlvalue_ty(C), 0)}, false); },
[](LLVMContext &C) {
AttrBuilder FnAttrs(C);
FnAttrs.addAttribute(Attribute::NoSync);
FnAttrs.addAttribute(Attribute::NoUnwind);
FnAttrs.addAttribute(Attribute::Speculatable);
FnAttrs.addAttribute(Attribute::WillReturn);
FnAttrs.addAttribute(Attribute::NoRecurse);
#if JL_LLVM_VERSION >= 160000
FnAttrs.addMemoryAttr(MemoryEffects::none());
#else
FnAttrs.addAttribute(Attribute::ReadNone);
#endif
AttrBuilder RetAttrs(C);
RetAttrs.addAttribute(Attribute::NonNull);
RetAttrs.addAttribute(Attribute::NoUndef);
return AttributeList::get(C, AttributeSet::get(C,FnAttrs), AttributeSet::get(C,RetAttrs),
{ Attributes(C, {Attribute::NonNull, Attribute::NoUndef, Attribute::ReadNone, Attribute::NoCapture}),
Attributes(C, {Attribute::NonNull, Attribute::NoUndef, Attribute::ReadNone}) });
},
};

// julia.call represents a call with julia calling convention, it is used as
//
Expand Down
5 changes: 5 additions & 0 deletions src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
#include <llvm/Support/TargetSelect.h>
#include <llvm/Object/SymbolSize.h>

#include <llvm-dialects/Dialect/ContextExtension.h>
#include <JuliaDialect.h>

using namespace llvm;

#include "jitlayers.h"
Expand Down Expand Up @@ -209,6 +212,7 @@ static jl_callptr_t _jl_compile_codeinst(
jl_callptr_t fptr = NULL;
// emit the code in LLVM IR form
jl_codegen_params_t params(std::move(context), jl_ExecutionEngine->getDataLayout(), jl_ExecutionEngine->getTargetTriple()); // Locks the context
auto dialectContext = llvm_dialects::DialectContext::make<julia::JuliaDialect>(params.getContext());
params.cache = true;
params.imaging_mode = imaging_default();
params.debug_level = jl_options.debug_level;
Expand Down Expand Up @@ -1566,6 +1570,7 @@ JuliaOJIT::JuliaOJIT()
DLSymOpt(std::make_unique<DLSymOptimizer>(false)),
ContextPool([](){
auto ctx = std::make_unique<LLVMContext>();
auto dialectContext = llvm_dialects::DialectContext::make<julia::JuliaDialect>(*ctx);
#if JL_LLVM_VERSION < 170000
SetOpaquePointer(*ctx);
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/llvm-alloc-helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ void jl_alloc::runEscapeAnalysis(llvm::CallInst *I, EscapeAnalysisRequiredArgs r
required.use_info.addrescaped = true;
return true;
}
if (required.pass.gc_loaded_func == callee) {
if (isa<GCLoaded>(callee)) {
required.use_info.haspreserve = true;
required.use_info.hasload = true;
return true;
Expand Down
2 changes: 1 addition & 1 deletion src/llvm-alloc-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ bool Optimizer::isSafepoint(Instruction *inst)
if (auto callee = call->getCalledFunction()) {
// Known functions emitted in codegen that are not safepoints
if (callee == pass.pointer_from_objref_func
|| callee == pass.gc_loaded_func
|| isa<GCLoaded>(callee)
|| callee->getName() == "memcmp") {
return false;
}
Expand Down
11 changes: 2 additions & 9 deletions src/llvm-codegen-shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,8 @@ static constexpr std::nullopt_t None = std::nullopt;

#endif

enum AddressSpace {
Generic = 0,
Tracked = 10,
Derived = 11,
CalleeRooted = 12,
Loaded = 13,
FirstSpecial = Tracked,
LastSpecial = Loaded,
};
#include "JuliaDialect.h"
using namespace julia;

namespace JuliaType {
static inline llvm::StructType* get_jlvalue_ty(llvm::LLVMContext &C) {
Expand Down
10 changes: 5 additions & 5 deletions src/llvm-late-gc-lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ static std::pair<Value*,int> FindBaseValue(const State &S, Value *V, bool UseCac
}
else if (auto CI = dyn_cast<CallInst>(CurrentV)) {
auto callee = CI->getCalledFunction();
if (callee && callee->getName() == "julia.gc_loaded") {
if (callee && isa<GCLoaded>(callee)) {
CurrentV = CI->getArgOperand(0);
continue;
}
Expand Down Expand Up @@ -873,7 +873,7 @@ static bool isLoadFromConstGV(Value *v, bool &task_local, PhiSet *seen = nullptr
task_local = true;
return true;
}
if (callee && callee->getName() == "julia.gc_loaded") {
if (isa<GCLoaded>(callee)) {
return isLoadFromConstGV(call->getArgOperand(0), task_local, seen) &&
isLoadFromConstGV(call->getArgOperand(1), task_local, seen);
}
Expand Down Expand Up @@ -1155,7 +1155,7 @@ State LateLowerGCFrame::LocalScan(Function &F) {
if (callee && callee == typeof_func) {
MaybeNoteDef(S, BBS, CI, BBS.Safepoints, SmallVector<int, 1>{-2});
}
else if (callee && callee->getName() == "julia.gc_loaded") {
else if (callee && isa<GCLoaded>(callee)) {
continue;
}
else {
Expand Down Expand Up @@ -1248,7 +1248,7 @@ State LateLowerGCFrame::LocalScan(Function &F) {
callee == pgcstack_getter || callee->getName() == XSTR(jl_egal__unboxed) ||
callee->getName() == XSTR(jl_lock_value) || callee->getName() == XSTR(jl_unlock_value) ||
callee->getName() == XSTR(jl_lock_field) || callee->getName() == XSTR(jl_unlock_field) ||
callee == write_barrier_func || callee == gc_loaded_func || callee == pop_handler_noexcept_func ||
callee == write_barrier_func || isa<GCLoaded>(callee) || callee == pop_handler_noexcept_func ||
callee->getName() == "memcmp") {
continue;
}
Expand Down Expand Up @@ -2045,7 +2045,7 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S, bool *CFGModified) {
ASCI->takeName(CI);
CI->replaceAllUsesWith(ASCI);
UpdatePtrNumbering(CI, ASCI, S);
} else if (gc_loaded_func != nullptr && callee == gc_loaded_func) {
} else if (isa<GCLoaded>(callee)) {
auto *obj = CI->getOperand(1);
auto *ASCI = new AddrSpaceCastInst(obj, CI->getType(), "", CI);
ASCI->takeName(CI);
Expand Down
3 changes: 1 addition & 2 deletions src/llvm-pass-helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ JuliaPassContext::JuliaPassContext()

pgcstack_getter(nullptr), adoptthread_func(nullptr), gc_flush_func(nullptr),
gc_preserve_begin_func(nullptr), gc_preserve_end_func(nullptr),
pointer_from_objref_func(nullptr), gc_loaded_func(nullptr), alloc_obj_func(nullptr),
pointer_from_objref_func(nullptr), alloc_obj_func(nullptr),
typeof_func(nullptr), write_barrier_func(nullptr), pop_handler_noexcept_func(nullptr),
call_func(nullptr), call2_func(nullptr), call3_func(nullptr), module(nullptr)
{
Expand All @@ -50,7 +50,6 @@ void JuliaPassContext::initFunctions(Module &M)
gc_preserve_begin_func = M.getFunction("llvm.julia.gc_preserve_begin");
gc_preserve_end_func = M.getFunction("llvm.julia.gc_preserve_end");
pointer_from_objref_func = M.getFunction("julia.pointer_from_objref");
gc_loaded_func = M.getFunction("julia.gc_loaded");
typeof_func = M.getFunction("julia.typeof");
write_barrier_func = M.getFunction("julia.write_barrier");
alloc_obj_func = M.getFunction("julia.gc_alloc_obj");
Expand Down
1 change: 0 additions & 1 deletion src/llvm-pass-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ struct JuliaPassContext {
llvm::Function *gc_preserve_begin_func;
llvm::Function *gc_preserve_end_func;
llvm::Function *pointer_from_objref_func;
llvm::Function *gc_loaded_func;
llvm::Function *alloc_obj_func;
llvm::Function *typeof_func;
llvm::Function *write_barrier_func;
Expand Down
1 change: 0 additions & 1 deletion src/llvmcalltest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ DLLEXPORT const char *MakeIdentityFunction(jl_value_t* jl_AnyTy) {

DLLEXPORT const char *MakeLoadGlobalFunction() {
LLVMContext Ctx;

auto M = new Module("shadow", Ctx);
auto intType = Type::getInt32Ty(Ctx);
auto G = new GlobalVariable(
Expand Down

0 comments on commit d1f0801

Please sign in to comment.