Skip to content

Added MallocWrapperPass #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/tsar/Transform/IR/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,8 @@ void initializeNoCaptureAnalysisPass(PassRegistry &Registry);

/// Create a pass calculating preserved parameters.
Pass * createNoCaptureAnalysisPass();

void initializeMallocWrapperPassPass(PassRegistry& Registry);
ModulePass* createMallocWrapperPass();
}
#endif//TSAR_IR_TRANSFORM_PASSES_H
12 changes: 6 additions & 6 deletions lib/Analysis/Clang/ExpressionMatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,14 @@ class MatchExprVisitor :
<< "\n");
if (auto CE = dyn_cast<CallExpr>(S)) {
if (!CE->getDirectCallee()) {
StashParent [[maybe_unused]] Stash{CE->getCallee(), mParents};
[[maybe_unused]] StashParent Stash{CE->getCallee(), mParents};
// We match expression which computes callee before this call.
if (!TraverseStmt(CE->getCallee()))
return false;
}
VisitItem(DynTypedNode::create(*S), S->getBeginLoc());
for (auto Arg : CE->arguments()) {
StashParent [[maybe_unused]] Stash{Arg, mParents};
[[maybe_unused]] StashParent Stash{Arg, mParents};
if (!TraverseStmt(Arg))
return false;
}
Expand All @@ -128,7 +128,7 @@ class MatchExprVisitor :
if (auto *T{
dyn_cast<VariableArrayType>(U->getArgumentType().getTypePtr())}) {
for (auto *C : U->children()) {
StashParent [[maybe_unused]] Stash{C, mParents};
[[maybe_unused]] StashParent Stash{C, mParents};
if (!TraverseStmt(C))
return false;
}
Expand All @@ -138,7 +138,7 @@ class MatchExprVisitor :
if (auto *SE{dyn_cast<ArraySubscriptExpr>(S)}) {
{
// We use scope to reload stash on exit.
StashParent [[maybe_unused]] Stash{S, mParents};
[[maybe_unused]] StashParent Stash{S, mParents};
if (!RecursiveASTVisitor::TraverseStmt(S))
return false;
}
Expand All @@ -158,7 +158,7 @@ class MatchExprVisitor :
// For `++ <expr>` we match `++` with store and `<expr>` with load.
VisitItem(DynTypedNode::create(*UO->getSubExpr()), UO->getOperatorLoc());
VisitItem(DynTypedNode::create(*S), UO->getOperatorLoc());
StashParent [[maybe_unused]] Stash{UO->getSubExpr(), mParents};
[[maybe_unused]] StashParent Stash{UO->getSubExpr(), mParents};
return TraverseStmt(UO->getSubExpr());
}
if (auto DRE{dyn_cast<DeclRefExpr>(S)}) {
Expand All @@ -185,7 +185,7 @@ class MatchExprVisitor :
} else if (auto *ME = dyn_cast<MemberExpr>(S)) {
VisitItem(DynTypedNode::create(*S), ME->getMemberLoc());
}
StashParent [[maybe_unused]] Stash{S, mParents};
[[maybe_unused]] StashParent Stash{S, mParents};
return RecursiveASTVisitor::TraverseStmt(S);
}

Expand Down
2 changes: 2 additions & 0 deletions lib/Core/Query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ void addBeforeTfmAnalysis(legacy::PassManager &Passes, StringRef AnalysisUse) {
Passes.add(createDIDependencyAnalysisPass(true));
Passes.add(createProcessDIMemoryTraitPass(mark<trait::DirectAccess>));
Passes.add(createAnalysisReader());

Passes.add(createMallocWrapperPass());
}

void addAfterSROAAnalysis(const GlobalOptions &GO, const DataLayout &DL,
Expand Down
6 changes: 5 additions & 1 deletion lib/Transform/Clang/DVMHSMAutoPar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,11 @@ static void sanitizeAcrossLoops(ItrT I, ItrT EI,
continue;
SmallVector<const Decl *, 4> UntiedVars;
auto &Clauses{Parallel->getClauses()};
for (auto &&[V, Distances] : Clauses.template get<trait::Dependence>()) {
// for (auto &&[V, Distances] : Clauses.template get<trait::Dependence>()) {
for (auto &&elem : Clauses.template get<trait::Dependence>()) {
auto &&V = elem.first;
auto &&Distances = elem.second;

auto Range{Clauses.template get<trait::DirectAccess>().equal_range(V)};
auto TieItr{find_if(Range.first, Range.second, [&V](const auto &Tie) {
return Tie.first.template get<MD>() == V.template get<MD>();
Expand Down
6 changes: 5 additions & 1 deletion lib/Transform/Clang/DVMHWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1060,7 +1060,11 @@ static void insertPragmaData(PragmaToLocations &PragmaLocations,
}
return true;
};
for (auto &&[S, Position] : PragmasToInsert) {
// for (auto &&[S, Position] : PragmasToInsert) {
for (auto &&elem : PragmasToInsert) {
auto &&S = elem.first;
auto &&Position = elem.second;

auto &ASTCtx{
cast<ClangTransformationContext>(Position.TfmCtx)->getContext()};
auto &ParentCtx{ASTCtx.getParentMapContext()};
Expand Down
2 changes: 1 addition & 1 deletion lib/Transform/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
set(TRANSFORM_SOURCES Passes.cpp DeadCodeElimination.cpp InterprocAttr.cpp
MetadataUtils.cpp Utils.cpp CallExtractor.cpp DependenceInliner.cpp
NoCaptureAnalysis.cpp)
NoCaptureAnalysis.cpp MallocWrapper.cpp)

if(MSVC_IDE)
file(GLOB_RECURSE TRANSFORM_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
Expand Down
2 changes: 1 addition & 1 deletion lib/Transform/IR/CallExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ bool CallExtractorPass::runOnFunction(Function& F) {
if (!F.empty()) {
for (auto CurrBB = F.begin(), LastBB = F.end();
CurrBB != LastBB; ++CurrBB) {
auto *TermInst = CurrBB->getTerminator();
auto *TermInst = CurrBB->getTerminator();
if (TermInst == nullptr || CurrBB->size() < 2)
continue;
auto CurrInstr = CurrBB->begin();
Expand Down
137 changes: 137 additions & 0 deletions lib/Transform/IR/MallocWrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include "tsar/Transform/IR/Passes.h"
#include "tsar/Analysis/KnownFunctionTraits.h"
#include <bcl/utility.h>
#include <llvm/IR/BasicBlock.h>
#include <llvm/Pass.h>
#include <llvm/Support/Debug.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/Transforms/Utils/BasicBlockUtils.h>
#include <string>
#include <map>
#include <sstream>

using namespace llvm;
using namespace tsar;

namespace
{
class MallocWrapperPass: public ModulePass, private bcl::Uncopyable {
std::map<std::string, FunctionCallee> wrappers_map;

FunctionCallee createMallocWrapper(Module &M, Type *type);
std::string getWrapperName(Type *type);
public:
static char ID;
MallocWrapperPass() : ModulePass(ID) {
initializeMallocWrapperPassPass(*PassRegistry::getPassRegistry());
}
bool runOnModule(Module &M) override;
};
}

#undef DEBUG_TYPE
#define DEBUG_TYPE "wrap-malloc"

char MallocWrapperPass::ID = 0;
INITIALIZE_PASS(MallocWrapperPass, "wrap-malloc",
"Wraps malloc", false, false)

ModulePass * llvm::createMallocWrapperPass() {
return new MallocWrapperPass();
}

std::string MallocWrapperPass::getWrapperName(Type *type) {
std::string s;
raw_string_ostream ostream(s);
type->print(ostream);

return std::string("malloc_wrapper_") + ostream.str();
}

FunctionCallee MallocWrapperPass::createMallocWrapper(Module &M, Type *type) {
std::string name = getWrapperName(type);
if (wrappers_map.count(name) != 0) {
return wrappers_map[name];
}

auto& context = M.getContext();

wrappers_map[name] = M.getOrInsertFunction(name, type, Type::getInt64Ty(context));
Function *f = cast<Function> (wrappers_map[name].getCallee());
f->setCallingConv(CallingConv::C);
f->addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
Function::arg_iterator args = f->arg_begin();

Value *size = args++;
size->setName("size");

BasicBlock *block = BasicBlock::Create(context, "entry", f);
IRBuilder<> builder(block);

auto malloc_func = M.getOrInsertFunction("malloc", Type::getInt8PtrTy(context), Type::getInt64Ty(context));

CallInst *mem = builder.CreateCall(malloc_func, size);
mem->addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
Value *result = builder.CreatePointerCast(mem, type, "result");
builder.CreateRet(result);

return wrappers_map[name];
}

bool MallocWrapperPass::runOnModule(Module &M) {
std::vector<std::pair<CallInst*, Type*>> malloc_call_list;

for (auto &F: M) {
for (auto &BB: F) {
for (auto &I: BB) {
if (I.getOpcode() == Instruction::Call) {
CallInst *callI = cast<CallInst>(&I);
auto func_name = callI->getCalledFunction()->getName();
if (func_name != "malloc") {
break;
}


Type *t = nullptr;
for (auto &use: callI->uses()) {
Instruction *inst = cast<Instruction>(use.getUser());
if (!inst || inst->getOpcode() != Instruction::BitCast) { break; }
if (!t) {
t = inst->getType();
} else if (t != use->getType()) {
t = nullptr;
break;
}
}

if (t) {
malloc_call_list.push_back({callI, t});
}
}
}
}
}

for (auto &el: malloc_call_list) {
auto callI = el.first;
auto t = el.second;

auto fc = createMallocWrapper(M, t);
CallInst* inst_call_new = CallInst::Create(fc, callI->getOperand(0));
inst_call_new->addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
ReplaceInstWithInst(callI, inst_call_new);

for (auto &use: callI->uses()) {
Value * res_new = cast<Value>(inst_call_new);
ReplaceInstWithInst(cast<Instruction>(use.getUser()), BitCastInst::CreatePointerCast(res_new, res_new->getType()));
}
}

for (auto &F : M) {
if (!F.empty()) {
errs() << F << "\n";
}
}

return true;
}
1 change: 1 addition & 0 deletions lib/Transform/IR/Passes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ void llvm::initializeIRTransform(PassRegistry &Registry) {
initializeDependenceInlinerPassPass(Registry);
initializeDependenceInlinerAttributerPass(Registry);
initializeNoCaptureAnalysisPass(Registry);
initializeMallocWrapperPassPass(Registry);
}