Skip to content

Commit

Permalink
Instrument AllocOpt
Browse files Browse the repository at this point in the history
  • Loading branch information
pchintalapudi committed Mar 12, 2022
1 parent b49a1b4 commit e7b8476
Showing 1 changed file with 27 additions and 1 deletion.
28 changes: 27 additions & 1 deletion src/llvm-alloc-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <llvm/ADT/SmallSet.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/ADT/SetVector.h>
#include <llvm/ADT/Statistic.h>
#include <llvm/IR/Value.h>
#include <llvm/IR/CFG.h>
#include <llvm/IR/LegacyPassManager.h>
Expand All @@ -20,6 +21,7 @@
#include <llvm/IR/Module.h>
#include <llvm/IR/Operator.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Pass.h>
#include <llvm/Support/Debug.h>
#include <llvm/Transforms/Utils/PromoteMemToReg.h>
Expand All @@ -41,10 +43,19 @@
using namespace llvm;
using namespace jl_alloc;

STATISTIC(RemovedAllocs, "Total number of heap allocations elided");
STATISTIC(DeletedAllocs, "Total number of heap allocations fully deleted");
STATISTIC(SplitAllocs, "Total number of allocations split into registers");
STATISTIC(StackAllocs, "Total number of allocations moved to the stack");
STATISTIC(RemovedTypeofs, "Total number of typeofs removed");
STATISTIC(RemovedWriteBarriers, "Total number of write barriers removed");
STATISTIC(RemovedGCPreserve, "Total number of GC preserve instructions removed");

namespace {

static void removeGCPreserve(CallInst *call, Instruction *val)
{
++RemovedGCPreserve;
auto replace = Constant::getNullValue(val->getType());
call->replaceUsesOfWith(val, replace);
for (auto &arg: call->args()) {
Expand Down Expand Up @@ -538,6 +549,8 @@ void Optimizer::replaceIntrinsicUseWith(IntrinsicInst *call, Intrinsic::ID ID,
// all the original safepoints.
void Optimizer::moveToStack(CallInst *orig_inst, size_t sz, bool has_ref)
{
++RemovedAllocs;
++StackAllocs;
auto tag = orig_inst->getArgOperand(2);
removed.push_back(orig_inst);
// The allocation does not escape or get used in a phi node so none of the derived
Expand Down Expand Up @@ -626,6 +639,7 @@ void Optimizer::moveToStack(CallInst *orig_inst, size_t sz, bool has_ref)
return;
}
if (pass.typeof_func == callee) {
++RemovedTypeofs;
call->replaceAllUsesWith(tag);
call->eraseFromParent();
return;
Expand All @@ -641,6 +655,7 @@ void Optimizer::moveToStack(CallInst *orig_inst, size_t sz, bool has_ref)
return;
}
if (pass.write_barrier_func == callee) {
++RemovedWriteBarriers;
call->eraseFromParent();
return;
}
Expand Down Expand Up @@ -696,6 +711,8 @@ void Optimizer::moveToStack(CallInst *orig_inst, size_t sz, bool has_ref)
// all the original safepoints.
void Optimizer::removeAlloc(CallInst *orig_inst)
{
++RemovedAllocs;
++DeletedAllocs;
auto tag = orig_inst->getArgOperand(2);
removed.push_back(orig_inst);
auto simple_remove = [&] (Instruction *orig_i) {
Expand Down Expand Up @@ -740,11 +757,13 @@ void Optimizer::removeAlloc(CallInst *orig_inst)
return;
}
if (pass.typeof_func == callee) {
++RemovedTypeofs;
call->replaceAllUsesWith(tag);
call->eraseFromParent();
return;
}
if (pass.write_barrier_func == callee) {
++RemovedWriteBarriers;
call->eraseFromParent();
return;
}
Expand Down Expand Up @@ -790,6 +809,7 @@ void Optimizer::optimizeTag(CallInst *orig_inst)
if (auto call = dyn_cast<CallInst>(user)) {
auto callee = call->getCalledOperand();
if (pass.typeof_func == callee) {
++RemovedTypeofs;
call->replaceAllUsesWith(tag);
// Push to the removed instructions to trigger `finalize` to
// return the correct result.
Expand All @@ -805,6 +825,8 @@ void Optimizer::optimizeTag(CallInst *orig_inst)
void Optimizer::splitOnStack(CallInst *orig_inst)
{
auto tag = orig_inst->getArgOperand(2);
++RemovedAllocs;
++SplitAllocs;
removed.push_back(orig_inst);
IRBuilder<> prolog_builder(&F.getEntryBlock().front());
struct SplitSlot {
Expand Down Expand Up @@ -1032,11 +1054,13 @@ void Optimizer::splitOnStack(CallInst *orig_inst)
}
}
if (pass.typeof_func == callee) {
++RemovedTypeofs;
call->replaceAllUsesWith(tag);
call->eraseFromParent();
return;
}
if (pass.write_barrier_func == callee) {
++RemovedWriteBarriers;
call->eraseFromParent();
return;
}
Expand Down Expand Up @@ -1148,7 +1172,9 @@ bool AllocOpt::runOnFunction(Function &F, function_ref<DominatorTree&()> GetDT)
Optimizer optimizer(F, *this, std::move(GetDT));
optimizer.initialize();
optimizer.optimizeAll();
return optimizer.finalize();
bool modified = optimizer.finalize();
assert(!verifyFunction(F));
return modified;
}

struct AllocOptLegacy : public FunctionPass {
Expand Down

0 comments on commit e7b8476

Please sign in to comment.