diff --git a/include/tsar/Transform/IR/Passes.h b/include/tsar/Transform/IR/Passes.h index d4b4e8e4..178470a0 100644 --- a/include/tsar/Transform/IR/Passes.h +++ b/include/tsar/Transform/IR/Passes.h @@ -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 diff --git a/lib/Analysis/Clang/ExpressionMatcher.cpp b/lib/Analysis/Clang/ExpressionMatcher.cpp index b283bea4..466a7646 100644 --- a/lib/Analysis/Clang/ExpressionMatcher.cpp +++ b/lib/Analysis/Clang/ExpressionMatcher.cpp @@ -108,14 +108,14 @@ class MatchExprVisitor : << "\n"); if (auto CE = dyn_cast(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; } @@ -128,7 +128,7 @@ class MatchExprVisitor : if (auto *T{ dyn_cast(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; } @@ -138,7 +138,7 @@ class MatchExprVisitor : if (auto *SE{dyn_cast(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; } @@ -158,7 +158,7 @@ class MatchExprVisitor : // For `++ ` we match `++` with store and `` 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(S)}) { @@ -185,7 +185,7 @@ class MatchExprVisitor : } else if (auto *ME = dyn_cast(S)) { VisitItem(DynTypedNode::create(*S), ME->getMemberLoc()); } - StashParent [[maybe_unused]] Stash{S, mParents}; + [[maybe_unused]] StashParent Stash{S, mParents}; return RecursiveASTVisitor::TraverseStmt(S); } diff --git a/lib/Core/Query.cpp b/lib/Core/Query.cpp index 819ecd14..34115476 100644 --- a/lib/Core/Query.cpp +++ b/lib/Core/Query.cpp @@ -153,6 +153,8 @@ void addBeforeTfmAnalysis(legacy::PassManager &Passes, StringRef AnalysisUse) { Passes.add(createDIDependencyAnalysisPass(true)); Passes.add(createProcessDIMemoryTraitPass(mark)); Passes.add(createAnalysisReader()); + + Passes.add(createMallocWrapperPass()); } void addAfterSROAAnalysis(const GlobalOptions &GO, const DataLayout &DL, diff --git a/lib/Transform/Clang/DVMHSMAutoPar.cpp b/lib/Transform/Clang/DVMHSMAutoPar.cpp index fb54b6d8..1fe764cd 100644 --- a/lib/Transform/Clang/DVMHSMAutoPar.cpp +++ b/lib/Transform/Clang/DVMHSMAutoPar.cpp @@ -475,7 +475,11 @@ static void sanitizeAcrossLoops(ItrT I, ItrT EI, continue; SmallVector UntiedVars; auto &Clauses{Parallel->getClauses()}; - for (auto &&[V, Distances] : Clauses.template get()) { + // for (auto &&[V, Distances] : Clauses.template get()) { + for (auto &&elem : Clauses.template get()) { + auto &&V = elem.first; + auto &&Distances = elem.second; + auto Range{Clauses.template get().equal_range(V)}; auto TieItr{find_if(Range.first, Range.second, [&V](const auto &Tie) { return Tie.first.template get() == V.template get(); diff --git a/lib/Transform/Clang/DVMHWriter.cpp b/lib/Transform/Clang/DVMHWriter.cpp index 0dda7bd7..46600b82 100644 --- a/lib/Transform/Clang/DVMHWriter.cpp +++ b/lib/Transform/Clang/DVMHWriter.cpp @@ -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(Position.TfmCtx)->getContext()}; auto &ParentCtx{ASTCtx.getParentMapContext()}; diff --git a/lib/Transform/IR/CMakeLists.txt b/lib/Transform/IR/CMakeLists.txt index 10e97a45..e4461ad3 100644 --- a/lib/Transform/IR/CMakeLists.txt +++ b/lib/Transform/IR/CMakeLists.txt @@ -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} diff --git a/lib/Transform/IR/CallExtractor.cpp b/lib/Transform/IR/CallExtractor.cpp index 57cf4e15..4a759321 100644 --- a/lib/Transform/IR/CallExtractor.cpp +++ b/lib/Transform/IR/CallExtractor.cpp @@ -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(); diff --git a/lib/Transform/IR/MallocWrapper.cpp b/lib/Transform/IR/MallocWrapper.cpp new file mode 100644 index 00000000..6810d1df --- /dev/null +++ b/lib/Transform/IR/MallocWrapper.cpp @@ -0,0 +1,137 @@ +#include "tsar/Transform/IR/Passes.h" +#include "tsar/Analysis/KnownFunctionTraits.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace llvm; +using namespace tsar; + +namespace +{ +class MallocWrapperPass: public ModulePass, private bcl::Uncopyable { + std::map 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 (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> malloc_call_list; + + for (auto &F: M) { + for (auto &BB: F) { + for (auto &I: BB) { + if (I.getOpcode() == Instruction::Call) { + CallInst *callI = cast(&I); + auto func_name = callI->getCalledFunction()->getName(); + if (func_name != "malloc") { + break; + } + + + Type *t = nullptr; + for (auto &use: callI->uses()) { + Instruction *inst = cast(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(inst_call_new); + ReplaceInstWithInst(cast(use.getUser()), BitCastInst::CreatePointerCast(res_new, res_new->getType())); + } + } + + for (auto &F : M) { + if (!F.empty()) { + errs() << F << "\n"; + } + } + + return true; +} \ No newline at end of file diff --git a/lib/Transform/IR/Passes.cpp b/lib/Transform/IR/Passes.cpp index 60080348..5bdefcbe 100644 --- a/lib/Transform/IR/Passes.cpp +++ b/lib/Transform/IR/Passes.cpp @@ -37,4 +37,5 @@ void llvm::initializeIRTransform(PassRegistry &Registry) { initializeDependenceInlinerPassPass(Registry); initializeDependenceInlinerAttributerPass(Registry); initializeNoCaptureAnalysisPass(Registry); + initializeMallocWrapperPassPass(Registry); }