Skip to content

Commit

Permalink
Merge pull request #13463 from JuliaLang/yyc/gc/tbaa
Browse files Browse the repository at this point in the history
tbaa_gcframe
  • Loading branch information
yuyichao committed Apr 2, 2016
2 parents 3c9bf14 + 0051c47 commit 3fae299
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static Value *stringConstPtr(const std::string &txt)
ssno.str());
gv->setUnnamedAddr(true);
pooledval->second = gv;
jl_ExecutionEngine->addGlobalMapping(gv, (void*)pooledtxt.data());
jl_ExecutionEngine->addGlobalMapping(gv, (void*)(uintptr_t)pooledtxt.data());
}

GlobalVariable *v = prepare_global(pooledval->second);
Expand Down
7 changes: 5 additions & 2 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ static Type *T_pppint8;
static Type *T_void;

// type-based alias analysis nodes. Indentation of comments indicates hierarchy.
static MDNode *tbaa_gcframe; // GC frame
static MDNode *tbaa_user; // User data that is mutable
static MDNode *tbaa_immut; // User data inside a heap-allocated immutable
static MDNode *tbaa_value; // Julia value
Expand Down Expand Up @@ -3503,7 +3504,8 @@ static void allocate_gc_frame(BasicBlock *b0, jl_codectx_t *ctx)
#endif
}

void jl_codegen_finalize_temp_arg(CallInst *ptlsStates, Type *T_pjlvalue);
void jl_codegen_finalize_temp_arg(CallInst *ptlsStates, Type *T_pjlvalue,
MDNode *tbaa_gcframe);
static void finalize_gc_frame(Function *F)
{
Module *M = F->getParent();
Expand All @@ -3525,7 +3527,7 @@ static void finalize_gc_frame(Function *F)
if (!ptlsStates)
return;

jl_codegen_finalize_temp_arg(ptlsStates, T_pjlvalue);
jl_codegen_finalize_temp_arg(ptlsStates, T_pjlvalue, tbaa_gcframe);

#ifdef JULIA_ENABLE_THREADING
if (imaging_mode) {
Expand Down Expand Up @@ -4891,6 +4893,7 @@ extern "C" void jl_fptr_to_llvm(jl_fptr_t fptr, jl_lambda_info_t *lam, int specs
static void init_julia_llvm_env(Module *m)
{
MDNode *tbaa_root = mbuilder->createTBAARoot("jtbaa");
tbaa_gcframe = tbaa_make_child("jtbaa_gcframe",tbaa_root);
tbaa_user = tbaa_make_child("jtbaa_user",tbaa_root);
tbaa_value = tbaa_make_child("jtbaa_value",tbaa_root);
tbaa_immut = tbaa_make_child("jtbaa_immut",tbaa_root);
Expand Down
71 changes: 60 additions & 11 deletions src/llvm-gcroot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include <vector>
#include <queue>
#include <set>

#include "julia.h"

Expand All @@ -36,7 +37,7 @@ static struct {

class JuliaGCAllocator {
public:
JuliaGCAllocator(CallInst *ptlsStates, Type *T_pjlvalue) :
JuliaGCAllocator(CallInst *ptlsStates, Type *T_pjlvalue, MDNode *tbaa) :
F(*ptlsStates->getParent()->getParent()),
M(*F.getParent()),
T_int32(Type::getInt32Ty(F.getContext())),
Expand All @@ -47,7 +48,8 @@ class JuliaGCAllocator {
gcroot_func(M.getFunction("julia.gc_root_decl")),
gckill_func(M.getFunction("julia.gc_root_kill")),
gc_store_func(M.getFunction("julia.gc_store")),
jlcall_frame_func(M.getFunction("julia.jlcall_frame_decl"))
jlcall_frame_func(M.getFunction("julia.jlcall_frame_decl")),
tbaa_gcframe(tbaa)
{
/* Algorithm sketch:
* Compute liveness for each basic block
Expand All @@ -74,6 +76,7 @@ Function *const gcroot_func;
Function *const gckill_func;
Function *const gc_store_func;
Function *const jlcall_frame_func;
MDNode *tbaa_gcframe;

typedef std::pair<CallInst*, unsigned> frame_register;
class liveness {
Expand All @@ -90,6 +93,42 @@ class liveness {
};
};

void tbaa_decorate_gcframe(Instruction *inst, std::set<Instruction*> &visited)
{
if (visited.find(inst) != visited.end())
return;
visited.insert(inst);
#ifdef LLVM35
Value::user_iterator I = inst->user_begin(), E = inst->user_end();
#else
Value::use_iterator I = inst->use_begin(), E = inst->use_end();
#endif
for (;I != E;++I) {
Instruction *user = dyn_cast<Instruction>(*I);
if (!user) {
continue;
} else if (isa<GetElementPtrInst>(user)) {
if (__likely(user->getOperand(0) == inst)) {
tbaa_decorate_gcframe(user, visited);
}
} else if (isa<StoreInst>(user)) {
if (user->getOperand(1) == inst) {
user->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
}
} else if (isa<LoadInst>(user)) {
user->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
} else if (isa<BitCastInst>(user)) {
tbaa_decorate_gcframe(user, visited);
}
}
}

void tbaa_decorate_gcframe(Instruction *inst)
{
std::set<Instruction*> visited;
tbaa_decorate_gcframe(inst, visited);
}

#ifndef NDEBUG // llvm assertions build
// gdb debugging code for inspecting the bb_uses map
void jl_dump_bb_uses(std::map<BasicBlock*, std::map<frame_register, liveness::id> > &bb_uses)
Expand Down Expand Up @@ -655,6 +694,7 @@ void allocate_frame()
// finalize all of the jlcall frames by replacing all of the frames with the appropriate gep(tempslot)
for (std::map<CallInst*, unsigned>::iterator frame = frame_offsets.begin(), framee = frame_offsets.end(); frame != framee; ++frame) {
CallInst *gcroot = frame->first;
tbaa_decorate_gcframe(gcroot);
Value* offset[1] = {ConstantInt::get(T_int32, frame->second)};
GetElementPtrInst *gep = GetElementPtrInst::Create(LLVM37_param(NULL) tempSlot, makeArrayRef(offset));
gep->insertAfter(last_gcframe_inst);
Expand Down Expand Up @@ -714,11 +754,13 @@ void allocate_frame()
}
}
#endif
tbaa_decorate_gcframe(callInst);
callInst->replaceAllUsesWith(argTempi);
argTempi->takeName(callInst);
callInst->eraseFromParent();
// Initialize the slots for function variables to NULL
StoreInst *store = new StoreInst(V_null, argTempi);
store->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
store->insertAfter(argTempi);
last_gcframe_inst = store;
}
Expand All @@ -744,6 +786,7 @@ void allocate_frame()
Instruction *argTempi = GetElementPtrInst::Create(LLVM37_param(NULL) tempSlot, ArrayRef<Value*>(ConstantInt::get(T_int32, i)));
argTempi->insertAfter(last_gcframe_inst);
StoreInst *store = new StoreInst(V_null, argTempi);
store->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
store->insertAfter(argTempi);
last_gcframe_inst = store;
}
Expand All @@ -763,10 +806,13 @@ void allocate_frame()
DebugLoc noDbg;
builder.SetCurrentDebugLocation(noDbg);

builder.CreateStore(ConstantInt::get(T_size, (argSpaceSize + maxDepth) << 1),
builder.CreateBitCast(builder.CreateConstGEP1_32(gcframe, 0), T_size->getPointerTo()));
builder.CreateStore(builder.CreateLoad(builder.Insert(get_pgcstack(ptlsStates))),
builder.CreatePointerCast(builder.CreateConstGEP1_32(gcframe, 1), PointerType::get(T_ppjlvalue,0)));
Instruction *inst =
builder.CreateStore(ConstantInt::get(T_size, (argSpaceSize + maxDepth) << 1),
builder.CreateBitCast(builder.CreateConstGEP1_32(gcframe, 0), T_size->getPointerTo()));
inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
inst = builder.CreateStore(builder.CreateLoad(builder.Insert(get_pgcstack(ptlsStates))),
builder.CreatePointerCast(builder.CreateConstGEP1_32(gcframe, 1), PointerType::get(T_ppjlvalue,0)));
inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
builder.CreateStore(gcframe, builder.Insert(get_pgcstack(ptlsStates)));

// Finish by emitting the gc pops before any return
Expand All @@ -775,9 +821,11 @@ void allocate_frame()
builder.SetInsertPoint(I->getTerminator()); // set insert *before* Ret
Instruction *gcpop =
(Instruction*)builder.CreateConstGEP1_32(gcframe, 1);
builder.CreateStore(builder.CreatePointerCast(builder.CreateLoad(gcpop),
T_ppjlvalue),
builder.Insert(get_pgcstack(ptlsStates)));
inst = builder.CreateLoad(gcpop);
inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
inst = builder.CreateStore(builder.CreatePointerCast(inst, T_ppjlvalue),
builder.Insert(get_pgcstack(ptlsStates)));
inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_gcframe);
}
}
}
Expand All @@ -791,8 +839,9 @@ void allocate_frame()

};

void jl_codegen_finalize_temp_arg(CallInst *ptlsStates, Type *T_pjlvalue)
void jl_codegen_finalize_temp_arg(CallInst *ptlsStates, Type *T_pjlvalue,
MDNode *tbaa)
{
JuliaGCAllocator allocator(ptlsStates, T_pjlvalue);
JuliaGCAllocator allocator(ptlsStates, T_pjlvalue, tbaa);
allocator.allocate_frame();
}

0 comments on commit 3fae299

Please sign in to comment.