Skip to content

Commit

Permalink
New feature for vcov
Browse files Browse the repository at this point in the history
1.Enable slicing criteria as "-c filename:linenum:varname"
e.g. -c cxxfilt.c:1000:work
e.g. -c cxxfilt.c:1000:NULL slicer will use the detected variable in that line.
2.dump BBName(file:line:col) to "./sliced_cfg" directory.
3.Temporarily fix infinite recursion bug(issue mchalupa#335) in LLVMReadWriteGraphBuild$
  in lib/llvm/ReadWriteGraph/LLVMReadWriteGraphBuilder.cpp.
  • Loading branch information
yangke committed Feb 1, 2021
1 parent 860f124 commit 4f89c42
Show file tree
Hide file tree
Showing 10 changed files with 436 additions and 24 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# DG
# modified-DG

add new feature

# how to use

`llvm-slicer -c filename.c:10:varname code.bc`

[![Build Status](https://travis-ci.org/mchalupa/dg.svg?branch=master)](https://travis-ci.org/mchalupa/dg)

Expand Down
46 changes: 44 additions & 2 deletions include/dg/Slicing.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
#include "dg/BBlock.h"
#endif

#include <llvm/IR/Constants.h>
#include <llvm/IR/Value.h>
#include <llvm/IR/Instruction.h>
#include <llvm/IR/GlobalVariable.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/InstIterator.h>
#include <llvm/Support/raw_ostream.h>

namespace dg {

// this class will go through the nodes
Expand Down Expand Up @@ -104,7 +112,19 @@ class WalkAndMark : public legacy::NodesWalk<NodeT, dg::ADT::QueueFIFO<NodeT *>>
}
}
};

struct DependencyItem{
int line;
int col;
std::string filename;
friend bool operator==(const DependencyItem & d1,const DependencyItem & d2){
return (d1.line == d2.line && d1.filename == d2.filename);
}
friend bool operator<(const DependencyItem & d1,const DependencyItem & d2){
if(d1.filename == d2.filename)
return d1.line<d2.line;
return (d1.filename < d2.filename);
}
};
struct SlicerStatistics
{
SlicerStatistics()
Expand All @@ -117,6 +137,7 @@ struct SlicerStatistics
uint64_t nodesRemoved;
// number of whole blocks removed
uint32_t blocksRemoved;
std::set<DependencyItem> dependency;
};

template <typename NodeT>
Expand Down Expand Up @@ -228,7 +249,6 @@ class Slicer : legacy::Analysis<NodeT>

return sl_id;
}

// remove node from the graph
// This virtual method allows to taky an action
// when node is being removed from the graph. It can also
Expand Down Expand Up @@ -290,9 +310,13 @@ class Slicer : legacy::Analysis<NodeT>
// FIXME: we don't need two loops, just go carefully
// through the constructed blocks (keep temporary always-valid iterator)
std::set<BBlock<NodeT> *> blocks;
std::set<BBlock<NodeT> *> saved_blocks;
for (auto& it : CB) {
if (it.second->getSlice() != sl_id)
blocks.insert(it.second);
else{
saved_blocks.insert(it.second);
}
}

for (BBlock<NodeT> *blk : blocks) {
Expand All @@ -307,6 +331,24 @@ class Slicer : legacy::Analysis<NodeT>
blk->remove();
}
}
//saved blocks .
/*
for (BBlock<NodeT> *block : saved_blocks) {
llvm::errs() << "block slice "<<block->getSlice()<<" \n";
llvm::Value *val = block->getKey();
if(val == nullptr)
continue;
llvm::BasicBlock *blk = llvm::cast<llvm::BasicBlock>(val);
for (llvm::Instruction& Inst : *blk){
auto& Loc = Inst.getDebugLoc();
llvm::errs() << "Inst is "<<" \n";
if(!Loc){
continue;
}
llvm::errs() << "dependency line is "<<Loc.getLine()<<" \n";
}
}*/

assert(CB.size() + blocks.size() == blocksNum &&
"Inconsistency in sliced blocks");
Expand Down
61 changes: 58 additions & 3 deletions include/dg/llvm/LLVMSlicer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
#include <llvm/IR/Instruction.h>
#include <llvm/IR/GlobalVariable.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/InstIterator.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/DebugInfoMetadata.h>

#if (__clang__)
#pragma clang diagnostic pop // ignore -Wunused-parameter
Expand Down Expand Up @@ -137,7 +140,34 @@ class LLVMSlicer : public Slicer<LLVMNode>
assert(0 && "Do not use this method with LLVM dg");
return 0;
}

uint32_t show_dependency(){
int line;
std::string filename;
llvm::errs() << "Dependency List:\n";
for (auto& it : constructedFunctions) {
for (auto& I : llvm::instructions(*llvm::cast<llvm::Function>(it.first))) {
const llvm::DebugLoc& Loc = I.getDebugLoc();
if (!Loc) {
continue;
}
DependencyItem tmpItem;
tmpItem.line = Loc.getLine();
tmpItem.col = Loc.getCol();
const llvm::DILocation *dil = Loc.get();
std::string filename = dil->getFilename().str();
tmpItem.filename = filename;
//llvm::errs() << "dependency line is "<<Loc.getLine()<<" \n";
statistics.dependency.insert(tmpItem);
}
}
std::set<DependencyItem>::iterator it;
llvm::errs() << "<filename>:<line>:<column>\n";
for(it=statistics.dependency.begin();it!=statistics.dependency.end();it++)
{
llvm::errs() << (*it).filename << ":" << (*it).line << ":" << (*it).col << "\n";
}
return 0;
}
uint32_t slice(LLVMDependenceGraph *,
LLVMNode *start, uint32_t sl_id = 0)
{
Expand All @@ -158,7 +188,22 @@ class LLVMSlicer : public Slicer<LLVMNode>

return sl_id;
}
uint32_t showinstruct(LLVMDependenceGraph *)
{
// take every subgraph and prt instruction
// this includes the main graph
for (auto& it : constructedFunctions) {
LLVMDependenceGraph *subdg = it.second;
for(auto I = subdg->begin(), E = subdg->end(); I != E;){
LLVMNode *n = I->second;
++I;
showOneInstruct(n->getKey());
llvm::errs() << "this is inst"<<" \n";
}
}

return 0;
}
private:
/*
void sliceCallNode(LLVMNode *callNode,
Expand Down Expand Up @@ -231,7 +276,14 @@ class LLVMSlicer : public Slicer<LLVMNode>
return true;
}
}

static inline bool showOneInstruct(const llvm::Value *val)
{
using namespace llvm;
const Instruction *Inst = dyn_cast<Instruction>(val);
if (!Inst)
return true;
llvm::errs() << "show one inst"<<" \n";
}
static LLVMBBlock *
createNewExitBB(LLVMDependenceGraph *graph)
{
Expand Down Expand Up @@ -487,9 +539,12 @@ class LLVMSlicer : public Slicer<LLVMNode>

bool dontTouch(const llvm::StringRef& r)
{
for (const char *n : dont_touch)
for (const char *n : dont_touch){

if (r.equals(n))
return true;
}


return false;
}
Expand Down
8 changes: 3 additions & 5 deletions lib/llvm/PointerAnalysis/Instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,16 @@ Offset accumulateEVOffsets(const llvm::ExtractValueInst *EV,
#endif

for (unsigned idx : EV->getIndices()) {
assert(type->indexValid(idx) && "Invalid index");
if (llvm::StructType *STy = llvm::dyn_cast<llvm::StructType>(type)) {
assert(STy->indexValid(idx) && "Invalid index");
const llvm::StructLayout *SL = DL.getStructLayout(STy);
off += SL->getElementOffset(idx);
} else {
// array or vector, so just move in the array
if (auto *arrTy = llvm::dyn_cast<llvm::ArrayType>(type)) {
assert(idx < arrTy->getNumElements() && "Invalid index");
if (auto *arrTy = llvm::dyn_cast<llvm::ArrayType>(type))
off += idx + DL.getTypeAllocSize(arrTy->getElementType());
} else {
else {
auto *vecTy = llvm::cast<llvm::VectorType>(type);
assert(idx < vecTy->getNumElements() && "Invalid index");
off += idx + DL.getTypeAllocSize(vecTy->getElementType());
}
}
Expand Down
4 changes: 3 additions & 1 deletion lib/llvm/ReadWriteGraph/Calls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ RWNode *LLVMReadWriteGraphBuilder::createUnknownCall(const llvm::CallInst *CInst
continue;

RWNode *target = getOperand(ptr.value);
assert(target && "Don't have pointer target for call argument");
if(!target) continue;
//assert(target && "Don't have pointer target for call argument");

// this call may use and define this memory
if (_options.undefinedFunsWriteArgs() && !_options.undefinedFunsWriteAny())
Expand Down Expand Up @@ -310,6 +311,7 @@ RWNode *LLVMReadWriteGraphBuilder::funcFromModel(const FunctionModel *model,
continue;

RWNode *target = getOperand(ptr.value);
if(!target) continue;
assert(target && "Don't have pointer target for call argument");

Offset from, to;
Expand Down
7 changes: 4 additions & 3 deletions lib/llvm/ReadWriteGraph/LLVMReadWriteGraphBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,16 @@ LLVMReadWriteGraphBuilder::mapPointers(const llvm::Value *where,

return result;
}

static int created=0;
RWNode *LLVMReadWriteGraphBuilder::getOperand(const llvm::Value *val) {
auto *op = getNode(val);
auto *op = getNode(val);created++;
if (!op) {
// lazily create allocations as these are targets in defsites
// and may not have been created yet
if (llvm::isa<llvm::AllocaInst>(val) ||
// FIXME: check that it is allocation
llvm::isa<llvm::CallInst>(val)) {
if (created>3) return NULL;
op = buildNode(val).getRepresentant();
}

Expand All @@ -155,7 +156,7 @@ RWNode *LLVMReadWriteGraphBuilder::getOperand(const llvm::Value *val) {
abort();
}
}
assert(op && "Do not have an operand");
assert(op && "Do not have an operand");created--;
return op;
}

Expand Down
4 changes: 4 additions & 0 deletions tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
# these tools can access the private headers
include_directories(${CMAKE_SOURCE_DIR}/lib)

SET(CMAKE_BUILD_TYPE "Debug")
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
add_definitions("-Wall -g")
if (LLVM_DG)
# generate a git-version.h with a HEAD commit hash tag
# (if it changed)
Expand Down
Loading

0 comments on commit 4f89c42

Please sign in to comment.