Skip to content

Omp lassa #3

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 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
242 changes: 242 additions & 0 deletions llvm/include/llvm/Analysis/OmpDiagnosticsAnalysis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
//===- OmpDiagnosticsAnalysis.h - Analyze omp target clauses and infer data
// mapping -----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// OpenMp target data mapping Analysis,
// A Diagnostics Pass to help understand usage of data mapping clauses.
// Looks at all the omp target RTL calls, and interprets their semantics,
// to conclude which variable is residing on Device or Host memory,
// outside and inside target regions.
// RTL is an acronym for "Run Time Library"
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_OmpDiagnosticsANALYSIS_H
#define LLVM_ANALYSIS_OmpDiagnosticsANALYSIS_H

#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/AbstractCallSite.h"
#include "llvm/Pass.h"
#include <map>
#include <queue>
#include <set>

namespace llvm {

using namespace llvm;

class IntResult {
int R;

public:
IntResult() : R(0) {}
int get() { return R; }
};
// using UseInstr2DefInstrMapTy = std::map<Instruction*,Instruction*>;
using ArgumentDefsTy = std::map<unsigned, const Instruction *>;
using CallToFuncArgsAliasMapTy =
std::map<const CallInst *, std::map<unsigned, unsigned>>;
using ArgumentUsesTy = std::map<unsigned, const Instruction *>;
using FuncToGenDefsTy = std::map<const Function *, ArgumentDefsTy>;
using FuncToGenUsesTy = std::map<const Function *, ArgumentUsesTy>;
using CallToGenDefsTy = std::map<const CallInst *, ArgumentDefsTy>;
using CallToGenUsesTy = std::map<const CallInst *, ArgumentUsesTy>;
using CallToUpwardExposedArgsTy =
std::map<const CallInst *, std::set<unsigned>>;
/// Iterate over every Omp RTL call instruction, and parse its arguments, to
/// deduce the data mapping pragma used by the programmer. Then record all the
/// variables mapped and its mapping properties for every Omp RTL call.
class OmpDiagnosticsLocalAnalysis {
const Function &ThisFunc;
const MemorySSA &MSSA;
AAResults &AA;
/// The following 3 maps are the result, they are updated after this analysis,
FuncToGenDefsTy &FuncToGenDefs;
FuncToGenUsesTy &FuncToGenUses;
// Map of which call instruction argument refers to which parent function argument.
CallToFuncArgsAliasMapTy &CallToFuncArgsAliasMap;
///

void analyzeBB(const BasicBlock &BB);
// This function records if the instruction uses one of the function arguments.
void recordFuncGenUses(const MemoryUse &MemUse);
void recordFuncGenDefs(const MemoryDef &MemDef);
Value *getAliasingCallArg(CallInst &CIDef, Value &PointerOp);
void adjustFuncArgNum(const Instruction &MemUse, unsigned &FuncArgNum, const FuncToGenDefsTy &Temp ) {
// If recording global uses, then keep appending.
auto FIter = Temp.find(MemUse.getFunction()) ;
if ( FIter != Temp.end() &&
FuncArgNum >= MemUse.getFunction()->arg_size() && /*Make sure this is for a global var, and not func argument*/
FIter->second.find(FuncArgNum) != FIter->second.end()){
// Find a func arg num that does not already exist, append logic.
while (FIter->second.find(FuncArgNum) != FIter->second.end()){
//TODO: add an alias check to overwrite same defs.
FuncArgNum++;
}
}
}

void addFuncToGenDef(const Instruction &MemDef, unsigned FuncArgNum) {
// Here we make sure, it is never overwritten
adjustFuncArgNum(MemDef, FuncArgNum, FuncToGenDefs);
FuncToGenDefs[MemDef.getFunction()][FuncArgNum] = &MemDef;
}
void addFuncToGenUse(const Instruction &MemUse, unsigned FuncArgNum) {
// Here we make sure, it is never overwritten
adjustFuncArgNum(MemUse, FuncArgNum, FuncToGenUses);
FuncToGenUses[MemUse.getFunction()][FuncArgNum] = &MemUse;
}
bool isGlobalVariable(const Value &Ptr, std::set<const Value*> &Visited);

// Iterate over all function arguments, and check which argument aliases with
// Mem
llvm::Optional<unsigned> getAliasingArg(const Value &Mem, const Function &F);

public:
/// Updates the \p OInfo, with the mapping informa
OmpDiagnosticsLocalAnalysis(const Function &F, const MemorySSA &MSSA,
AAResults &AA, FuncToGenDefsTy &FuncToGenDefs,
FuncToGenUsesTy &FuncToGenUses,
CallToFuncArgsAliasMapTy &CallToFuncArgsAliasMap)
: ThisFunc(F), MSSA(MSSA), AA(AA), FuncToGenDefs(FuncToGenDefs),
FuncToGenUses(FuncToGenUses),
CallToFuncArgsAliasMap(CallToFuncArgsAliasMap) {}
// TODO : make sure the order of traversal of Basicblocks is correct, preorder
// traversal only
// This analysis records the following 3 items,
// 1. Which instruction uses one of the function arguments.
// 2. Which instruction defines one of the function arguments.
// 3. Which call instruction passes one of the function arguments.
void run();
void recordFuncGens();
void print();
};

using ArgToDefMapTy = std::map<unsigned, const Instruction *>;
using ArgToUseMapTy = std::map<unsigned, const Instruction *>;
class InterproceduralAnalysis {
Module &ThisModule;
FuncToGenDefsTy &FuncToGenDefs;
FuncToGenUsesTy &FuncToGenUses;
CallToFuncArgsAliasMapTy &CallToFuncArgsAliasMap;

std::map<CallBase*, AbstractCallSite *> CallInstToACSmap;

bool Converged;
Function *getCalledFunc(CallInst &CI);
Function *getCalledFuncDefs(CallInst &CI, ArgToDefMapTy &ArgToDefMap);
Function *getCalledFuncUses(CallInst &CI, ArgToUseMapTy &ArgToDefMap);
void insertDef(Function &F, unsigned FuncArg, const Instruction *);
void insertUse(Function &F, unsigned FuncArg, const Instruction *);
void analyzeFunc(Function &F);
void run();

public:
InterproceduralAnalysis(Module &ThisModule, FuncToGenDefsTy &FuncToGenDefs,
FuncToGenUsesTy &FuncToGenUses,
CallToFuncArgsAliasMapTy &CallToFuncArgsAliasMap)
: ThisModule(ThisModule), FuncToGenDefs(FuncToGenDefs),
FuncToGenUses(FuncToGenUses),
CallToFuncArgsAliasMap(CallToFuncArgsAliasMap), Converged(false) {
run();
}
void getCallGens(CallToGenDefsTy &CallToGenDefs, CallToGenUsesTy &CallToGenUses);
void print();
};

using FuncToAAResultsMapTy = std::map<const Function *, AAResults *>;
using FuncToMSSAMapTy = std::map<const Function *, const MemorySSA *>;
using SetOfInstructionsTy = std::vector<const Instruction*> ;
using SetOfMemoryAccessesTy = std::set<const MemoryUseOrDef*>;
class InterproceduralMSSAWalker {
const Module &ThisModule;
FuncToAAResultsMapTy &FuncToAAResultsMap;
FuncToMSSAMapTy &FuncToMSSAMap;
CallToGenDefsTy &CallToGenDefs;
CallToGenUsesTy &CallToGenUses;
std::map<const MemoryPhi *, std::vector<bool>> MemPhiToDeviceDefMap;
std::map<const CallInst*, const CallInst*> TargetCIMap;
enum DefLocation{NoDef, DeviceDef, HostDef} ;

// llvm::optional<const Instruction*>
void recordReachingDefsAtPhi();
void printCopy(const SetOfInstructionsTy &Src, const Instruction &Dst, const Instruction &CopyAt, const std::string &copyStr, bool UseOnDevice);
const Instruction *getFuncArgDef(const CallInst &CI,unsigned ArgNum);
bool checkIfAlias(const Instruction *Def, const Value *UseMem, AAResults &AR);
// Iterate over all the arguments to the call instruction \p DefInstr, and check if any argument aliases with Usemem, return the argument which aliases.
void checkCallArgAlias(const CallInst &DefInstr,
const Value *UseMem,
AAResults &AR, std::set<unsigned> &AliasingArgs);
DefLocation getDefAccesses(const MemoryAccess &MA, const Value *UseMem,
const MemorySSA &MSSA, AAResults &AR, std::set<const MemoryAccess *> &VisitedSet, SetOfInstructionsTy &DefInstrs, SetOfMemoryAccessesTy &SetOfMemoryAccesses, const MemoryUseOrDef &MemUse);

bool getDefAccesses(const MemoryUseOrDef &UseMA, const MemoryAccess &DefMA, const Value *UseMem,const MemorySSA &MSSA, AAResults &AR);
void handleMemUse(const MemoryUse &MemUse, const MemorySSA &MSSA,
AAResults &AR);
void handleMemDef(const MemoryDef &MemDef, const MemorySSA &MSSA,
AAResults &AR);
void analyzeFunc(const MemorySSA &MSSA, AAResults &AR, const Function &F, std::vector<const Function*> &CalledFunctionsList);
void run();
bool isInstrOnDevice(const Instruction &I);
void handleDefOnDevice(const MemoryUseOrDef &MemUse, const MemoryUseOrDef &MemDef);

public:
/// Updates the \p OInfo, with the mapping informa
InterproceduralMSSAWalker(const Module &ThisModule,
FuncToAAResultsMapTy &FuncToAAResultsMap,
FuncToMSSAMapTy &FuncToMSSAMap,
CallToGenDefsTy &CallToGenDefs,
CallToGenUsesTy &CallToGenUses)
: ThisModule(ThisModule), FuncToAAResultsMap(FuncToAAResultsMap),
FuncToMSSAMap(FuncToMSSAMap), CallToGenDefs(CallToGenDefs),
CallToGenUses(CallToGenUses) {run();}
};

/// This pass performs the global (interprocedural) Omp Data Mapping Analysis.
/// (New pass manager).
class OmpDiagnosticsGlobalAnalysis
: public AnalysisInfoMixin<OmpDiagnosticsGlobalAnalysis> {
friend AnalysisInfoMixin<OmpDiagnosticsGlobalAnalysis>;
static AnalysisKey Key;
Module *ThisModule;
ModuleAnalysisManager *AnalysisManager;
std::function<AAResults &(Function &)> GetAAForFunc;
std::function<MemorySSA &(Function &F)> GetMemSSAForFunc;
FuncToAAResultsMapTy FuncToAAResultsMap;
FuncToMSSAMapTy FuncToMSSAMap;
FuncToGenDefsTy FuncToGenDefs;
FuncToGenUsesTy FuncToGenUses;
CallToFuncArgsAliasMapTy CallToFuncArgsAliasMap;

void analyzeModule();
void recordFuncGens();
void interProcRecordFuncGens();
void interProcMSSA();

public:
using Result = IntResult;
Result run(Module &M, ModuleAnalysisManager &AM);
/// Dummy function, does nothing right now.
void handleIndirectCalls(Function &F);
};

/// Printer pass for the \c OmpDiagnosticsGlobalAnalysis results.
class OmpDiagnosticsGlobalPrinterPass
: public PassInfoMixin<OmpDiagnosticsGlobalPrinterPass> {
raw_ostream &OS;

public:
explicit OmpDiagnosticsGlobalPrinterPass(raw_ostream &OS) : OS(OS) {}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
};

} // end namespace llvm

#endif // LLVM_ANALYSIS_OmpDiagnosticsANALYSIS_H
2 changes: 2 additions & 0 deletions llvm/include/llvm/InitializePasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ void initializeObjCARCAPElimPass(PassRegistry&);
void initializeObjCARCContractPass(PassRegistry&);
void initializeObjCARCExpandPass(PassRegistry&);
void initializeObjCARCOptPass(PassRegistry&);
void initializeOmpDiagnosticsGlobalInfoWrapperPassPass(PassRegistry &);
void initializeOmpDiagnosticsInfoWrapperPassPass(PassRegistry &);
void initializeOptimizationRemarkEmitterWrapperPassPass(PassRegistry&);
void initializeOptimizePHIsPass(PassRegistry&);
void initializePAEvalPass(PassRegistry&);
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Analysis/AliasAnalysisSummary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) {
if (isa<GlobalValue>(Val))
return AttrGlobal;

return AttrNone;
if (auto *Arg = dyn_cast<Argument>(&Val))
// Only pointer arguments should have the argument attribute,
// because things can't escape through scalars without us seeing a
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ add_llvm_component_library(LLVMAnalysis
PhiValues.cpp
PostDominators.cpp
ProfileSummaryInfo.cpp
OmpDiagnosticsAnalysis.cpp
PtrUseVisitor.cpp
RegionInfo.cpp
RegionPass.cpp
Expand All @@ -104,6 +105,7 @@ add_llvm_component_library(LLVMAnalysis

ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/Analysis
${LLVM_MAIN_INCLUDE_DIR}/openmp/libomptarget/include/

DEPENDS
intrinsics_gen
Expand Down
Loading