Skip to content

Commit

Permalink
b
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyichao committed Jul 22, 2017
1 parent 5c56782 commit 7ad6a9c
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 87 deletions.
5 changes: 2 additions & 3 deletions src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level)
#endif
if (opt_level == 0) {
PM->add(createCFGSimplificationPass()); // Clean up disgusting code
PM->add(createAllocOptPass(false));
#if JL_LLVM_VERSION < 50000
PM->add(createBarrierNoopPass());
PM->add(createLowerExcHandlersPass());
Expand Down Expand Up @@ -148,7 +147,7 @@ void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level)
// effectiveness of the optimization, but should retain correctness.
#if JL_LLVM_VERSION < 50000
PM->add(createLowerExcHandlersPass());
PM->add(createAllocOptPass(true));
PM->add(createAllocOptPass());
PM->add(createLateLowerGCFramePass());
// Remove dead use of ptls
PM->add(createDeadCodeEliminationPass());
Expand All @@ -167,7 +166,7 @@ void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level)
// 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(true));
PM->add(createAllocOptPass());
#endif
PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl.
PM->add(createSROAPass()); // Break up aggregate allocas
Expand Down
2 changes: 1 addition & 1 deletion src/jitlayers.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ Pass *createLateLowerGCFramePass();
Pass *createLowerExcHandlersPass();
Pass *createGCInvariantVerifierPass(bool Strong);
Pass *createPropagateJuliaAddrspaces();
Pass *createAllocOptPass(bool);
Pass *createAllocOptPass();
// Whether the Function is an llvm or julia intrinsic.
static inline bool isIntrinsicFunction(Function *F)
{
Expand Down
99 changes: 16 additions & 83 deletions src/llvm-alloc-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ static bool isBundleOperand(CallInst *call, unsigned idx)
}

/**
* Promote `julia.gc_alloc_obj` which do not have escaping root to a alloca and
* lower other ones to real GC allocation.
* Promote `julia.gc_alloc_obj` which do not have escaping root to a alloca.
* Uses that are not considered to escape the object (i.e. heap address) includes,
*
* * load
Expand All @@ -74,20 +73,18 @@ static bool isBundleOperand(CallInst *call, unsigned idx)

struct AllocOpt : public FunctionPass {
static char ID;
AllocOpt(bool opt=true)
: FunctionPass(ID),
optimize(opt)
{}
AllocOpt()
: FunctionPass(ID)
{
llvm::initializeDominatorTreeWrapperPassPass(*PassRegistry::getPassRegistry());
}

private:
bool optimize;
LLVMContext *ctx;

const DataLayout *DL;

Function *alloc_obj;
Function *pool_alloc;
Function *big_alloc;
Function *ptr_from_objref;
Function *lifetime_start;
Function *lifetime_end;
Expand All @@ -99,9 +96,7 @@ struct AllocOpt : public FunctionPass {
Type *T_pint8;
Type *T_prjlvalue;
Type *T_pjlvalue;
Type *T_pjlvalue_der;
Type *T_pprjlvalue;
Type *T_ppjlvalue_der;

MDNode *tbaa_tag;

Expand Down Expand Up @@ -155,16 +150,13 @@ struct AllocOpt : public FunctionPass {
bool checkInst(Instruction *I, CheckInstStack &stack, std::set<Instruction*> &uses,
bool &ignore_tag);
void replaceUsesWith(Instruction *orig_i, Instruction *new_i, ReplaceUsesStack &stack);
void lowerAlloc(CallInst *I, size_t sz);
bool isSafepoint(Instruction *inst);
void getAnalysisUsage(AnalysisUsage &AU) const override
{
if (optimize) {
FunctionPass::getAnalysisUsage(AU);
AU.addRequired<DominatorTreeWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
AU.setPreservesCFG();
}
FunctionPass::getAnalysisUsage(AU);
AU.addRequired<DominatorTreeWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
AU.setPreservesCFG();
}
};

Expand Down Expand Up @@ -337,15 +329,6 @@ void AllocOpt::LifetimeMarker::insert(Instruction *ptr, Constant *sz, Instructio
}
}

static void addRetNoAlias(Function *F)
{
#if JL_LLVM_VERSION >= 50000
F->addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
#else
F->addAttribute(AttributeSet::ReturnIndex, Attribute::NoAlias);
#endif
}

bool AllocOpt::doInitialization(Module &M)
{
ctx = &M.getContext();
Expand All @@ -359,35 +342,14 @@ bool AllocOpt::doInitialization(Module &M)

T_prjlvalue = alloc_obj->getReturnType();
T_pjlvalue = PointerType::get(cast<PointerType>(T_prjlvalue)->getElementType(), 0);
T_pjlvalue_der = PointerType::get(cast<PointerType>(T_prjlvalue)->getElementType(),
AddressSpace::Derived);
T_pprjlvalue = PointerType::get(T_prjlvalue, 0);
T_ppjlvalue_der = PointerType::get(T_prjlvalue, AddressSpace::Derived);

T_int8 = Type::getInt8Ty(*ctx);
T_int32 = Type::getInt32Ty(*ctx);
T_int64 = Type::getInt64Ty(*ctx);
T_size = sizeof(void*) == 8 ? T_int64 : T_int32;
T_pint8 = PointerType::get(T_int8, 0);

if (!(pool_alloc = M.getFunction("jl_gc_pool_alloc"))) {
std::vector<Type*> alloc_pool_args(0);
alloc_pool_args.push_back(T_pint8);
alloc_pool_args.push_back(T_int32);
alloc_pool_args.push_back(T_int32);
pool_alloc = Function::Create(FunctionType::get(T_prjlvalue, alloc_pool_args, false),
Function::ExternalLinkage, "jl_gc_pool_alloc", &M);
addRetNoAlias(pool_alloc);
}
if (!(big_alloc = M.getFunction("jl_gc_big_alloc"))) {
std::vector<Type*> alloc_big_args(0);
alloc_big_args.push_back(T_pint8);
alloc_big_args.push_back(T_size);
big_alloc = Function::Create(FunctionType::get(T_prjlvalue, alloc_big_args, false),
Function::ExternalLinkage, "jl_gc_big_alloc", &M);
addRetNoAlias(big_alloc);
}

#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 });
Expand Down Expand Up @@ -583,33 +545,6 @@ void AllocOpt::replaceUsesWith(Instruction *orig_inst, Instruction *new_inst,
}
}

void AllocOpt::lowerAlloc(CallInst *I, size_t sz)
{
int osize;
int offset = jl_gc_classify_pools(sz, &osize);
IRBuilder<> builder(I);
builder.SetCurrentDebugLocation(I->getDebugLoc());
auto ptls = I->getArgOperand(0);
CallInst *newI;
if (offset < 0) {
newI = builder.CreateCall(big_alloc, {ptls, ConstantInt::get(T_size, sz + sizeof(void*))});
}
else {
auto pool_offs = ConstantInt::get(T_int32, offset);
auto pool_osize = ConstantInt::get(T_int32, osize);
newI = builder.CreateCall(pool_alloc, {ptls, pool_offs, pool_osize});
}
newI->setAttributes(I->getAttributes());
newI->takeName(I);
copyMetadata(newI, I);
auto derived = builder.CreateAddrSpaceCast(newI, T_pjlvalue_der);
auto cast = builder.CreateBitCast(derived, T_ppjlvalue_der);
auto tagaddr = builder.CreateGEP(T_prjlvalue, cast, {ConstantInt::get(T_size, -1)});
auto store = builder.CreateStore(I->getArgOperand(2), tagaddr);
store->setMetadata(LLVMContext::MD_tbaa, tbaa_tag);
I->replaceAllUsesWith(newI);
}

bool AllocOpt::isSafepoint(Instruction *inst)
{
auto call = dyn_cast<CallInst>(inst);
Expand Down Expand Up @@ -647,7 +582,9 @@ bool AllocOpt::runOnFunction(Function &F)
else {
continue;
}
allocs[call] = sz;
if (sz < IntegerType::MAX_INT_BITS / 8) {
allocs[call] = sz;
}
}
}

Expand All @@ -660,8 +597,7 @@ bool AllocOpt::runOnFunction(Function &F)
bool ignore_tag = true;
auto orig = it.first;
size_t sz = it.second;
if (optimize && sz < IntegerType::MAX_INT_BITS / 8 &&
checkInst(orig, check_stack, alloc_uses, ignore_tag)) {
if (checkInst(orig, check_stack, alloc_uses, ignore_tag)) {
// The allocation does not escape or get used in a phi node so none of the derived
// SSA from it are live when we run the allocation again.
// It is now safe to promote the allocation to an entry block alloca.
Expand Down Expand Up @@ -707,9 +643,6 @@ bool AllocOpt::runOnFunction(Function &F)
casti->takeName(orig);
replaceUsesWith(orig, cast<Instruction>(casti), replace_stack);
}
else {
lowerAlloc(orig, sz);
}
}
for (auto it: allocs)
it.first->eraseFromParent();
Expand All @@ -723,7 +656,7 @@ static RegisterPass<AllocOpt> X("AllocOpt", "Promote heap allocation to stack",

}

Pass *createAllocOptPass(bool opt)
Pass *createAllocOptPass()
{
return new AllocOpt(opt);
return new AllocOpt();
}

0 comments on commit 7ad6a9c

Please sign in to comment.