Skip to content

Commit

Permalink
Synchronizing with internal repository
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiaokang Fan committed Mar 22, 2017
1 parent fee3803 commit 5355fc2
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 20 deletions.
4 changes: 3 additions & 1 deletion include/MSSA/SVFGBuilder.h
Expand Up @@ -60,7 +60,7 @@ class SVFGBuilder {
typedef SVFG::SVFGEdgeSetTy SVFGEdgeSet;

/// Constructor
SVFGBuilder(): svfg(NULL) {}
SVFGBuilder(bool _SVFGWithIndCall = false): svfg(NULL), SVFGWithIndCall(_SVFGWithIndCall) {}

/// Destructor
virtual ~SVFGBuilder() {}
Expand Down Expand Up @@ -104,6 +104,8 @@ class SVFGBuilder {
/// SVFG Edges connected at indirect call/ret sites
SVFGEdgeSet vfEdgesAtIndCallSite;
SVFG* svfg;
/// SVFG with precomputed indirect call edges
bool SVFGWithIndCall;
};

#endif /* ANDERSENMEMSSA_H_ */
9 changes: 6 additions & 3 deletions include/MSSA/SVFGNode.h
Expand Up @@ -538,9 +538,12 @@ class PHISVFGNode : public SVFGNode {
bb = inst->getParent();
}
else {
assert(llvm::isa<llvm::Argument>(val)&& "Phi svf node is not an instruction or an formal parameter??");
const llvm::Argument* arg = llvm::cast<llvm::Argument>(val);
bb = &arg->getParent()->getEntryBlock();
assert((llvm::isa<llvm::Argument>(val) || analysisUtil::isSelectConstantExpr(val))
&& "Phi svf node is not an instruction, a select constantExpr or an formal parameter??");
if(const llvm::Argument* arg = llvm::dyn_cast<llvm::Argument>(val))
bb = &arg->getParent()->getEntryBlock();
else
bb = NULL; /// bb is null when we have a select constant expression
}
}

Expand Down
8 changes: 8 additions & 0 deletions include/Util/AnalysisUtil.h
Expand Up @@ -431,6 +431,14 @@ inline const llvm::ConstantExpr *isCastConstantExpr(const llvm::Value *val) {
}
return NULL;
}

inline const llvm::ConstantExpr *isSelectConstantExpr(const llvm::Value *val) {
if(const llvm::ConstantExpr* constExpr = llvm::dyn_cast<llvm::ConstantExpr>(val)) {
if(constExpr->getOpcode() == llvm::Instruction::Select)
return constExpr;
}
return NULL;
}
//@}

/// Get basic block successor position
Expand Down
2 changes: 1 addition & 1 deletion lib/MSSA/SVFGBuilder.cpp
Expand Up @@ -112,7 +112,7 @@ bool SVFGBuilder::build(SVFG* graph,BVDataPTAImpl* pta) {

createSVFG(&mssa, graph);

if(SVFGWithIndirectCall)
if(SVFGWithIndirectCall || SVFGWithIndCall)
updateCallGraph(mssa.getPTA());

releaseMemory(graph);
Expand Down
22 changes: 20 additions & 2 deletions lib/MemoryModel/MemModel.cpp
Expand Up @@ -632,6 +632,7 @@ void SymbolTableInfo::buildMemModel(llvm::Module& module) {
for (Module::alias_iterator I = module.alias_begin(), E =
module.alias_end(); I != E; I++) {
collectSym(&*I);
collectSym((*I).getAliasee());
}

// Add symbols for all of the functions and the instructions in them.
Expand Down Expand Up @@ -856,15 +857,32 @@ bool SymbolTableInfo::isConstantObjSym(const Value *val) {
*/
void SymbolTableInfo::handleCE(const Value *val) {
if (const Constant* ref = dyn_cast<Constant>(val)) {
const ConstantExpr* ce = isGepConstantExpr(ref) == NULL ? isCastConstantExpr(ref) : isGepConstantExpr(ref);
if (ce != NULL) {
if (const ConstantExpr* ce = isGepConstantExpr(ref)) {
DBOUT(DMemModelCE,
outs() << "handle constant expression " << *ref << "\n");
collectVal(ce);
collectVal(ce->getOperand(0));
// handle the recursive constant express case
// like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
handleCE(ce->getOperand(0));
} else if (const ConstantExpr* ce = isCastConstantExpr(ref)) {
DBOUT(DMemModelCE,
outs() << "handle constant expression " << *ref << "\n");
collectVal(ce);
collectVal(ce->getOperand(0));
// handle the recursive constant express case
// like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
handleCE(ce->getOperand(0));
} else if (const ConstantExpr* ce = isSelectConstantExpr(ref)) {
DBOUT(DMemModelCE,
outs() << "handle constant expression " << *ref << "\n");
collectVal(ce);
collectVal(ce->getOperand(0));
collectVal(ce->getOperand(1));
// handle the recursive constant express case
// like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
handleCE(ce->getOperand(0));
handleCE(ce->getOperand(1));
}
// remember to handle the constant bit cast opnd after stripping casts off
else {
Expand Down
6 changes: 4 additions & 2 deletions lib/MemoryModel/PAG.cpp
Expand Up @@ -354,7 +354,8 @@ bool PAG::hasInterEdge(PAGNode* src, PAGNode* dst, PAGEdge::PEDGEK kind, const l
* Argument CopyEdge (PAG::addFormalParamBlackHoleAddrEdge)
* ConstantExpr CopyEdge (Int2PtrConstantExpr CastConstantExpr PAGBuilder::processCE)
* GepEdge (GepConstantExpr PAGBuilder::processCE)
* ConstantPointerNull CopyEdge (3-->2 PAG::addNullPtrNode)
* ConstantPointerNull CopyEdge (3-->2 NullPtr-->BlkPtr PAG::addNullPtrNode)
* AddrEdge (0-->2 BlkObj-->BlkPtr PAG::addNullPtrNode)
* GlobalVariable AddrEdge (PAGBuilder::visitGlobal)
* GepEdge (PAGBuilder::getGlobalVarField)
* Function AddrEdge (PAGBuilder::visitGlobal)
Expand All @@ -374,7 +375,8 @@ void PAG::setCurrentBBAndValueForPAGEdge(PAGEdge* edge) {
if (!curBB)
globPAGEdgesSet.insert(edge);
} else if (isa<ConstantPointerNull>(curVal)) {
assert(edge->getSrcID() == 3 && edge->getDstID() == 2);
assert((edge->getSrcID() == NullPtr && edge->getDstID() == BlkPtr) ||
(edge->getSrcID() == BlackHole && edge->getDstID() == BlkPtr));
globPAGEdgesSet.insert(edge);
} else if (isa<GlobalVariable>(curVal) ||
isa<Function>(curVal) ||
Expand Down
38 changes: 32 additions & 6 deletions lib/MemoryModel/PAGBuilder.cpp
Expand Up @@ -166,9 +166,11 @@ bool PAGBuilder::computeGepOffset(const User *V, LocationSet& ls) {
*/
void PAGBuilder::processCE(const Value *val) {
if (const Constant* ref = dyn_cast<Constant>(val)) {
if (!isa<PointerType>(ref->getType()))
return;
if (const ConstantExpr* gepce = isGepConstantExpr(ref)) {
DBOUT(DPAGBuild,
outs() << "handle constant expression " << *ref << "\n");
outs() << "handle gep constant expression " << *ref << "\n");
const Constant* opnd = gepce->getOperand(0);
LocationSet ls;
bool constGep = computeGepOffset(gepce, ls);
Expand All @@ -187,7 +189,7 @@ void PAGBuilder::processCE(const Value *val) {
}
else if (const ConstantExpr* castce = isCastConstantExpr(ref)) {
DBOUT(DPAGBuild,
outs() << "handle constant expression " << *ref << "\n");
outs() << "handle cast constant expression " << *ref << "\n");
const Constant* opnd = castce->getOperand(0);
const llvm::Value* cval = pag->getCurrentValue();
const llvm::BasicBlock* cbb = pag->getCurrentBB();
Expand All @@ -196,6 +198,25 @@ void PAGBuilder::processCE(const Value *val) {
pag->setCurrentLocation(cval, cbb);
processCE(opnd);
}
else if (const ConstantExpr* selectce = isSelectConstantExpr(ref)) {
DBOUT(DPAGBuild,
outs() << "handle select constant expression " << *ref << "\n");
const Constant* src1 = selectce->getOperand(1);
const Constant* src2 = selectce->getOperand(2);
const llvm::Value* cval = pag->getCurrentValue();
const llvm::BasicBlock* cbb = pag->getCurrentBB();
pag->setCurrentLocation(selectce, NULL);
NodeID nsrc1 = pag->getValueNode(src1);
NodeID nsrc2 = pag->getValueNode(src2);
NodeID nres = pag->getValueNode(selectce);
pag->addCopyEdge(nsrc1, nres);
pag->addCopyEdge(nsrc2, nres);
pag->addPhiNode(pag->getPAGNode(nres),pag->getPAGNode(nsrc1),NULL);
pag->addPhiNode(pag->getPAGNode(nres),pag->getPAGNode(nsrc2),NULL);
pag->setCurrentLocation(cval, cbb);
processCE(src1);
processCE(src2);
}
// if we meet a int2ptr, then it points-to black hole
else if (const ConstantExpr* int2Ptrce = isInt2PtrConstantExpr(ref)) {
pag->addGlobalBlackHoleAddrEdge(pag->getValueNode(int2Ptrce), int2Ptrce);
Expand Down Expand Up @@ -310,8 +331,14 @@ void PAGBuilder::visitGlobal(llvm::Module& module) {
pag->addAddrEdge(obj, idx);
}

/// initial global aliases
/// for now we do not implement this
// Handle global aliases (due to linkage of multiple bc files), e.g., @x = internal alias @y. We need to add a copy from y to x.
for (Module::alias_iterator I = module.alias_begin(), E = module.alias_end(); I != E; I++) {
NodeID dst = pag->getValueNode(&*I);
NodeID src = pag->getValueNode((*I).getAliasee());
processCE((*I).getAliasee());
pag->setCurrentLocation(&*I, NULL);
pag->addCopyEdge(src,dst);
}
}

/*!
Expand Down Expand Up @@ -855,9 +882,8 @@ void PAGBuilder::handleExtCall(CallSite cs, const Function *callee) {
Size_t offset = pag->getLocationSetFromBaseNode(vnArg).getOffset();

// We get all fields
const Type *type = vArg->getType();
vector<LocationSet> fields;
SymbolTableInfo::Symbolnfo()->getFields(fields, type, 0);
const Type *type = getBaseTypeAndFlattenedFields(vArg,fields);
assert(fields.size() >= 4 && "_Rb_tree_node_base should have at least 4 fields.\n");

// We summarize the side effects: ret = arg->parent, ret = arg->left, ret = arg->right
Expand Down
7 changes: 4 additions & 3 deletions lib/Util/ExtAPI.cpp
Expand Up @@ -762,13 +762,14 @@ static const ei_pair ei_pairs[]= {
{"XQueryTree", ExtAPI::EFT_A4R_NEW},
{"XGetWindowProperty", ExtAPI::EFT_A11R_NEW},

// C++ STL function
// C++ STL functions
// std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)
{"_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_", ExtAPI::EFT_STD_RB_TREE_INSERT_AND_REBALANCE},

// std::_Rb_tree_increment and std::_Rb_tree_decrement
{"_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base", ExtAPI::EFT_STD_RB_TREE_INCREMENT},
{"_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base", ExtAPI::EFT_STD_RB_TREE_INCREMENT},
// TODO: the following side effects seem not to be necessary
// {"_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base", ExtAPI::EFT_STD_RB_TREE_INCREMENT},
// {"_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base", ExtAPI::EFT_STD_RB_TREE_INCREMENT},

//This must be the last entry.
{0, ExtAPI::EFT_NOOP}
Expand Down
14 changes: 12 additions & 2 deletions lib/WPA/WPAPass.cpp
Expand Up @@ -66,10 +66,13 @@ static cl::bits<WPAPass::AliasCheckRule> AliasRule(cl::desc("Select alias check
clEnumValEnd));

cl::opt<bool> StoreAnder("store-ander", cl::init(false),
cl::desc("Store Andersen's analysis result to a file"));
cl::desc("Store Andersen's analysis result to a file"));

cl::opt<bool> LoadAnder("load-ander", cl::init(false),
cl::desc("Load Andersen's analysis result from a file"));
cl::desc("Load Andersen's analysis result from a file"));

cl::opt<bool> anderSVFG("svfg", cl::init(false),
cl::desc("Generate SVFG after Andersen's Analysis"));

/*!
* Destructor
Expand Down Expand Up @@ -117,8 +120,15 @@ void WPAPass::runPointerAnalysis(llvm::Module& module, u32_t kind)
_pta = new AndersenWave();
break;
case PointerAnalysis::AndersenWaveDiff_WPA:
{
_pta = new AndersenWaveDiff();
if (anderSVFG) {
SVFGBuilder memSSA(true);
SVFG *svfg = memSSA.buildSVFG((BVDataPTAImpl*)_pta);
svfg->dump("ander_svfg");
}
break;
}
case PointerAnalysis::FSSPARSE_WPA:
_pta = new FlowSensitive();
break;
Expand Down

0 comments on commit 5355fc2

Please sign in to comment.