Skip to content
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

feat(explorer)[clauses]: improved detection of data sharing clauses #642

Merged
Merged
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
8 changes: 4 additions & 4 deletions DiscoPoP/DiscoPoP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@
#define DP_DEBUG false

#define ClCheckLoopPar true
#define DumpToDot true
#define DumpToDot false
#define DP_BRANCH_TRACKING \
true // toggles the creation of instrumentation calls for tracking taken
// branches. Required by the graph pruning step of the DiscoPoP
// optimizer.
#define DP_DEBUG false
#define DP_VERBOSE false // prints warning messages
#define DP_hybrid_DEBUG true
#define DP_hybrid_DEBUG false

using namespace llvm;
using namespace std;
Expand Down Expand Up @@ -137,10 +137,10 @@ class DiscoPoP : public ModulePass {

Type *pointsToStruct(PointerType *PTy);

Value *determineVariableName_dynamic(Instruction *const I);
Value *determineVariableName_dynamic(Instruction *const I, string prefix);

string determineVariableName_static(Instruction *I, bool &isGlobalVariable /*=defaultIsGlobalVariableValue*/,
bool disable_MetadataMap);
bool disable_MetadataMap, string prefix);

void getTrueVarNamesFromMetadata(Region *TopRegion, Node *root,
std::map<string, string> *trueVarNamesFromMetadataMap);
Expand Down
2 changes: 1 addition & 1 deletion DiscoPoP/instrumentation/low_level/instrumentAlloca.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void DiscoPoP::instrumentAlloca(AllocaInst *toInstrument) {

vector<Value *> args;
args.push_back(ConstantInt::get(Int32, lid));
args.push_back(determineVariableName_dynamic(toInstrument));
args.push_back(determineVariableName_dynamic(toInstrument, ""));

bool isGlobal;
// Value *startAddr = PtrToIntInst::CreatePointerCast(toInstrument, Int64, "",
Expand Down
2 changes: 1 addition & 1 deletion DiscoPoP/instrumentation/low_level/instrumentLoad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void DiscoPoP::instrumentLoad(LoadInst *toInstrument) {
Value *memAddr = PtrToIntInst::CreatePointerCast(toInstrument->getPointerOperand(), Int64, "", toInstrument);
args.push_back(memAddr);

args.push_back(determineVariableName_dynamic(toInstrument));
args.push_back(determineVariableName_dynamic(toInstrument, ""));

#ifdef SKIP_DUP_INSTR
Twine name = Twine("L").concat(Twine(uniqueNum));
Expand Down
2 changes: 1 addition & 1 deletion DiscoPoP/instrumentation/low_level/instrumentStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void DiscoPoP::instrumentStore(StoreInst *toInstrument) {
Value *memAddr = PtrToIntInst::CreatePointerCast(toInstrument->getPointerOperand(), Int64, "", toInstrument);
args.push_back(memAddr);

args.push_back(determineVariableName_dynamic(toInstrument));
args.push_back(determineVariableName_dynamic(toInstrument, ""));

#ifdef SKIP_DUP_INSTR
Twine name = Twine("S").concat(Twine(uniqueNum));
Expand Down
30 changes: 0 additions & 30 deletions DiscoPoP/llvm_hooks/runOnFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,6 @@ bool DiscoPoP::runOnFunction(Function &F) {
if(DG.edgeIsINIT(edge)){
string initLine = DG.getInitEdgeInstructionLine(edge);
string varIdentifier = DG.getValueNameAndMemRegIDFromEdge(edge, staticValueNameToMemRegIDMap);
std::cout << "Found init: " << DG.edgeToDPDep(edge, staticValueNameToMemRegIDMap) << "\n";
std::cout << "\t@ " << initLine << "\n";
std::cout << "\tvar: " << varIdentifier << "\n";

if(lineToInitializedVarsMap.find(initLine) == lineToInitializedVarsMap.end()){
set<string> tmp;
Expand All @@ -310,52 +307,26 @@ bool DiscoPoP::runOnFunction(Function &F) {
if (!conditionalBBDepMap.count(Src->getParent())) {
set<string> tmp;
conditionalBBDepMap[Src->getParent()] = tmp;

std::cout<< "Registered set1: \n";
for(auto s : tmp){
std::cout << "--> " << s << "\n";
}
}
conditionalBBDepMap[Src->getParent()].insert(DG.edgeToDPDep(edge, staticValueNameToMemRegIDMap));
std::cout << "Inserted1: " << DG.edgeToDPDep(edge, staticValueNameToMemRegIDMap) << "\n";
} else {
if (!conditionalBBPairDepMap.count(Dst->getParent())) {
map<BasicBlock *, set<string>> tmp;
conditionalBBPairDepMap[Dst->getParent()] = tmp;
std::cout<< "Registered set2: \n";
for(auto pair : tmp){
for(auto s : pair.second){
std::cout << "--> " << s << "\n";
}
}
}
if (!conditionalBBPairDepMap[Dst->getParent()].count(Src->getParent())) {
set<string> tmp;
conditionalBBPairDepMap[Dst->getParent()][Src->getParent()] = tmp;
std::cout<< "Registered set3: \n";
for(auto s : tmp){
std::cout << "--> " << s << "\n";
}
}
std::cout << "First: " << Dst << "\n";
Dst->print(outs());
std::cout << "\n";
std::cout << "Second: " << Src << "\n";
Src->print(outs());
std::cout << "\n";
// Prevent reporting of false-positive WAW Dependencies due to alloca movement from e.g. loops to function entry
bool insertDep = true;
if(Dst == Src){ // check if instruciton are the same
std::cout << "==> Potential for false-positive WAW\n";
std::cout << "--> same inst\n";
// check if initialization exists in the instruction line
if(lineToInitializedVarsMap.find(DG.getInstructionLine(Dst)) != lineToInitializedVarsMap.end()){
std::cout << "--> same init exists\n";
// check if the accessed variable is initialed here
string varIdentifier = DG.getValueNameAndMemRegIDFromEdge(edge, staticValueNameToMemRegIDMap);
if(lineToInitializedVarsMap[DG.getInstructionLine(Dst)].find(varIdentifier) != lineToInitializedVarsMap[DG.getInstructionLine(Dst)].end()){
// ignore this access as the initialized variable is accessed
std::cout << "==> initialized var accessed\n";
insertDep = false;
}
}
Expand All @@ -364,7 +335,6 @@ bool DiscoPoP::runOnFunction(Function &F) {
if(insertDep){
conditionalBBPairDepMap[Dst->getParent()][Src->getParent()].insert(
DG.edgeToDPDep(edge, staticValueNameToMemRegIDMap));
std::cout << "Inserted: " << DG.edgeToDPDep(edge, staticValueNameToMemRegIDMap) << "\n";
}
}
omittableInstructions.insert(Src);
Expand Down
4 changes: 2 additions & 2 deletions DiscoPoP/static_analysis/createCUs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ void DiscoPoP::createCUs(Region *TopRegion, set<string> &globalVariablesSet, vec
Type *Ty = operand->getType();
unsigned u = DL->getTypeSizeInBits(Ty);
cu->writeDataSize += u;
varName = determineVariableName_static(&*instruction, isGlobalVar, false);
varName = determineVariableName_static(&*instruction, isGlobalVar, false, "");
varType = determineVariableType(&*instruction);
suspiciousVariables.insert(varName);
if (lid > 0)
Expand All @@ -162,7 +162,7 @@ void DiscoPoP::createCUs(Region *TopRegion, set<string> &globalVariablesSet, vec
Type *Ty = instruction->getType();
unsigned u = DL->getTypeSizeInBits(Ty);
cu->readDataSize += u;
varName = determineVariableName_static(&*instruction, isGlobalVar, false);
varName = determineVariableName_static(&*instruction, isGlobalVar, false, "");
if (suspiciousVariables.count(varName)) {
// VIOLATION OF CAUTIOUS PROPERTY
// it is a load instruction which read the value of a global
Expand Down
2 changes: 1 addition & 1 deletion DiscoPoP/static_analysis/fillCUVariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void DiscoPoP::fillCUVariables(Region *TopRegion, set<string> &globalVariablesSe
if (lid == 0)
continue;
// NOTE: changed 'instruction' to '&*instruction', next 2 lines
varName = determineVariableName_static(&*instruction, isGlobalVar, false);
varName = determineVariableName_static(&*instruction, isGlobalVar, false, "");
varType = determineVariableType(&*instruction);

int index = isa<StoreInst>(&*instruction) ? 1 : 0;
Expand Down
2 changes: 1 addition & 1 deletion DiscoPoP/static_analysis/populateGlobalVariablesSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ void DiscoPoP::populateGlobalVariablesSet(Region *TopRegion, set<string> &global
if (isa<LoadInst>(instruction) || isa<StoreInst>(instruction) || isa<CallInst>(instruction)) {

// NOTE: changed 'instruction' to '&*instruction'
string varName = determineVariableName_static(&*instruction, isGlobalVariable, false);
string varName = determineVariableName_static(&*instruction, isGlobalVariable, false, "");

if (isGlobalVariable) // add it if it is a global variable in the
// program
Expand Down
6 changes: 3 additions & 3 deletions DiscoPoP/utils/variables/defLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ string DiscoPoP::determineVariableDefLine(Instruction *I) {
string varDefLine{"LineNotFound"};

bool isGlobal = false;
string varName = determineVariableName_static(&*I, isGlobal, true);
string varName = determineVariableName_static(&*I, isGlobal, true, "");
// varName = refineVarName(varName);
varName = (varName.find(".addr") == varName.npos) ? varName : varName.erase(varName.find(".addr"), 5);
// varName.erase(varName.find(".addr"), 5);
Expand Down Expand Up @@ -63,10 +63,10 @@ string DiscoPoP::determineVariableDefLine(Instruction *I) {
if (AI) {
for (User *U : AI->users()) {
if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
vn = determineVariableName_static(&*SI, isGlobal, true);
vn = determineVariableName_static(&*SI, isGlobal, true, "");
break;
} else if (LoadInst *LI = dyn_cast<LoadInst>(U)) {
vn = determineVariableName_static(&*LI, isGlobal, true);
vn = determineVariableName_static(&*LI, isGlobal, true, "");
break;
}
}
Expand Down
34 changes: 22 additions & 12 deletions DiscoPoP/utils/variables/names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@

string DiscoPoP::getOrInsertVarName_static(string varName, IRBuilder<> &builder) {
Value *valName = NULL;
// remove .addr if added. Replaced by the GEPRESULT_ tag
if (varName.find(".addr") != std::string::npos){
varName.erase(varName.find(".addr"), 5);
}

std::string vName = varName;
map<string, Value *>::iterator pair = VarNames.find(varName);
if (pair == VarNames.end()) {
Expand All @@ -28,6 +33,11 @@ string DiscoPoP::getOrInsertVarName_static(string varName, IRBuilder<> &builder)
}

Value *DiscoPoP::getOrInsertVarName_dynamic(string varName, IRBuilder<> &builder) {
// remove .addr if added. Replaced by the GEPRESULT_ tag
if (varName.find(".addr") != std::string::npos){
varName.erase(varName.find(".addr"), 5);
}

// 26.08.2022 Lukas
// update varName with original varName from Metadata
if (trueVarNamesFromMetadataMap.find(varName) == trueVarNamesFromMetadataMap.end()) {
Expand All @@ -49,7 +59,7 @@ Value *DiscoPoP::getOrInsertVarName_dynamic(string varName, IRBuilder<> &builder
}

string DiscoPoP::determineVariableName_static(Instruction *I, bool &isGlobalVariable /*=defaultIsGlobalVariableValue*/,
bool disable_MetadataMap) {
bool disable_MetadataMap, string prefix) {

assert(I && "Instruction cannot be NULL \n");
int index = isa<StoreInst>(I) ? 1 : 0;
Expand Down Expand Up @@ -120,9 +130,9 @@ string DiscoPoP::determineVariableName_static(Instruction *I, bool &isGlobalVari

// we've found an array
if (PTy->getPointerElementType()->getTypeID() == Type::ArrayTyID && isa<GetElementPtrInst>(*ptrOperand)) {
return determineVariableName_static((Instruction *)ptrOperand, isGlobalVariable, false);
return determineVariableName_static((Instruction *)ptrOperand, isGlobalVariable, false, prefix);
}
return determineVariableName_static((Instruction *)gep, isGlobalVariable, false);
return determineVariableName_static((Instruction *)gep, isGlobalVariable, false, "GEPRESULT_" + prefix);
}
string retVal = string(operand->getName().data());
if (trueVarNamesFromMetadataMap.find(retVal) == trueVarNamesFromMetadataMap.end() || disable_MetadataMap) {
Expand All @@ -134,13 +144,13 @@ string DiscoPoP::determineVariableName_static(Instruction *I, bool &isGlobalVari
}

if (isa<LoadInst>(*operand) || isa<StoreInst>(*operand)) {
return determineVariableName_static((Instruction *)(operand), isGlobalVariable, false);
return determineVariableName_static((Instruction *)(operand), isGlobalVariable, false, prefix);
}
// if we cannot determine the name, then return *
return ""; // getOrInsertVarName("*", builder);
}

Value *DiscoPoP::determineVariableName_dynamic(Instruction *const I) {
Value *DiscoPoP::determineVariableName_dynamic(Instruction *const I, string prefix) {
assert(I && "Instruction cannot be NULL \n");
int index = isa<StoreInst>(I) ? 1 : 0;
Value *operand = I->getOperand(index);
Expand All @@ -156,7 +166,7 @@ Value *DiscoPoP::determineVariableName_dynamic(Instruction *const I) {
if (isa<GlobalVariable>(*operand)) {
DIGlobalVariable *gv = findDbgGlobalDeclare(cast<GlobalVariable>(operand));
if (gv != NULL) {
return getOrInsertVarName_dynamic(string(gv->getDisplayName().data()), builder);
return getOrInsertVarName_dynamic(prefix + string(gv->getDisplayName().data()), builder);
}
}
if (isa<GetElementPtrInst>(*operand)) {
Expand Down Expand Up @@ -187,21 +197,21 @@ Value *DiscoPoP::determineVariableName_dynamic(Instruction *const I) {

// we've found an array
if (PTy->getPointerElementType()->getTypeID() == Type::ArrayTyID && isa<GetElementPtrInst>(*ptrOperand)) {
return determineVariableName_dynamic((Instruction *)ptrOperand);
return determineVariableName_dynamic((Instruction *)ptrOperand, prefix);
}
return determineVariableName_dynamic((Instruction *)gep);
return determineVariableName_dynamic((Instruction *)gep, "GEPRESULT_"+prefix);
}
return getOrInsertVarName_dynamic(string(operand->getName().data()), builder);
return getOrInsertVarName_dynamic(prefix + string(operand->getName().data()), builder);
}

if (isa<LoadInst>(*operand) || isa<StoreInst>(*operand)) {
return determineVariableName_dynamic((Instruction *)(operand));
return determineVariableName_dynamic((Instruction *)(operand), prefix);
}
if (isa<AllocaInst>(I)) {
return getOrInsertVarName_dynamic(I->getName().str(), builder);
return getOrInsertVarName_dynamic(prefix + I->getName().str(), builder);
}
// if we cannot determine the name, then return *
return getOrInsertVarName_dynamic("*", builder);
return getOrInsertVarName_dynamic(prefix + "*", builder);
}

void DiscoPoP::getTrueVarNamesFromMetadata(Region *TopRegion, Node *root,
Expand Down
2 changes: 2 additions & 0 deletions discopop_explorer/PEGraphX.py
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,8 @@ def map_static_and_dynamic_dependencies(self) -> None:
if d1.memory_region != d2.memory_region:
if d1.memory_region is None or d2.memory_region is None:
continue
if d1.memory_region.startswith("GEPRESULT_") or d2.memory_region.startswith("GEPRESULT_"):
continue
if d1.memory_region not in mem_reg_mappings:
mem_reg_mappings[d1.memory_region] = set()
if d2.memory_region not in mem_reg_mappings:
Expand Down
16 changes: 14 additions & 2 deletions discopop_explorer/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class DependenceItem(object):
type: Any
var_name: Any
memory_region: Any
is_gep_result_dependency: bool
metadata: Any
# TODO improve typing

Expand Down Expand Up @@ -198,13 +199,24 @@ def __parse_dep_file(dep_fd: TextIOWrapper, output_path: str) -> Tuple[List[Depe
key_tuple = sink, source_fields[0], type, var_name, aa_var_name
if key_tuple in dependency_metadata:
metadata = dependency_metadata[key_tuple]

# check if the dependency originates from the result of a GEP instruction
is_gep_result_dependency = False
if var_name.startswith("GEPRESULT_"):
var_name = var_name.replace("GEPRESULT_", "")
is_gep_result_dependency = True

# register dependencies
if len(metadata) == 0:
dependencies_list.append(DependenceItem(sink, source_fields[0], type, var_name, aa_var_name, ""))
dependencies_list.append(
DependenceItem(sink, source_fields[0], type, var_name, aa_var_name, is_gep_result_dependency, "")
)
else:
for md_set in metadata:
dependencies_list.append(
DependenceItem(sink, source_fields[0], type, var_name, aa_var_name, md_set)
DependenceItem(
sink, source_fields[0], type, var_name, aa_var_name, is_gep_result_dependency, md_set
)
)

return dependencies_list, loop_data_list
Expand Down
1 change: 1 addition & 0 deletions discopop_explorer/pattern_detectors/reduction_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ def __detect_reduction(pet: PEGraphX, root: LoopNode) -> bool:
# and "**" not in v.type --> replaced by check for array reduction
]
reduction_var_names = cast(List[str], [v.name for v in reduction_vars])

fp, p, lp, s, r = classify_loop_variables(pet, root)

# get parents of loop
Expand Down
Loading
Loading