8 #ifndef MTARESULTVALIDATOR_H_ 9 #define MTARESULTVALIDATOR_H_ 29 tcg =
mhp->getThreadCallGraph();
47 std::vector<std::string> &
split(
const std::string &s,
char delim, std::vector<std::string> &elems);
48 std::vector<std::string>
split(
const std::string &s,
char delim);
70 inline std::string
getOutput(
const char *scenario,
bool analysisRes);
172 const RC_FLAG flags) :
173 I1(I1), I2(I2), flags(flags)
209 selectedValidationScenarios = RC_MHP | RC_ALIASES | RC_PROTECTED | RC_RACE;
210 collectValidationTargets();
227 return !accessPairs.empty();
237 selectedValidationScenarios &= ~RC_ALIASES;
243 selectedValidationScenarios &= ~RC_MHP;
249 selectedValidationScenarios &= ~RC_PROTECTED;
255 selectedValidationScenarios &= ~RC_RACE;
268 std::vector<const CallInst*> csInsts;
269 const Function *F = M.getFunction(RC_ACCESS);
272 for (Value::const_use_iterator it = F->use_begin(), ie =
273 F->use_end(); it != ie; ++it)
276 const Value *user = u->getUser();
279 csInsts.push_back(csInst);
281 assert(csInsts.size() % 2 == 0 &&
"We should have RC_ACCESS called in pairs.");
284 std::sort(csInsts.begin(), csInsts.end(), compare);
287 for (
int i = 0, e = csInsts.size(); i != e;)
295 assert(I1 && I2 &&
"RC_ACCESS should be placed immediately after the target memory access.");
296 RC_FLAG flags = C->getZExtValue();
297 accessPairs.push_back(
AccessPair(I1, I2, flags));
307 for (
int i = 0, e = accessPairs.size(); i != e; ++i)
313 bool mhp = mayHappenInParallel(I1, I2);
314 bool alias = mayAccessAliases(I1, I2);
315 bool protect = protectedByCommonLocks(I1, I2);
316 bool racy = mayHaveDataRace(I1, I2);
321 if (selectedValidationScenarios & RC_ALIASES)
327 if (selectedValidationScenarios & RC_MHP)
332 if (selectedValidationScenarios & RC_PROTECTED)
338 if (selectedValidationScenarios & RC_RACE)
351 bool analysisRes,
bool expectedRes)
353 std::string ret(scenario);
359 if (analysisRes == expectedRes)
377 const Value *V1 = CI1->getOperand(0);
378 const Value *V2 = CI2->getOperand(0);
381 assert(0 != C1 && 0 != C2);
382 return C1->getZExtValue() < C2->getZExtValue();
393 I = I->getPrevNode();
396 if (SVFUtil::isa<LoadInst>(I) || SVFUtil::isa<StoreInst>(I))
400 if (ExtAPI::EFT_L_A0__A0R_A1R == ExtAPI::getExtAPI()->get_type(callee)
401 || callee->getName().find(
"llvm.memset") != StringRef::npos)
404 I = I->getPrevNode();
411 static const RC_FLAG RC_MHP = 0x01;
412 static const RC_FLAG RC_ALIASES = 0x02;
413 static const RC_FLAG RC_PROTECTED = 0x04;
414 static const RC_FLAG RC_RACE = 0x10;
419 static constexpr
char const *RC_ACCESS =
"RC_ACCESS";
virtual bool protectedByCommonLocks(const Instruction *I1, const Instruction *I2)
std::string getOutputforInterlevAnalysis(const char *scenario, INTERLEV_FLAG analysisRes)
AccessPair(const Instruction *I1, const Instruction *I2, const RC_FLAG flags)
Constructor.
static constexpr char const * INTERLEV_ACCESS
static const INTERLEV_FLAG INTERLEV_UNSOUND
std::string pasMsg(std::string msg)
Print each pass/phase message by converting a string into blue string output.
static bool compare(const CallInst *CI1, const CallInst *CI2)
void release()
Release resource.
MHP::InstToThreadStmtSetMap instToTSMap
static constexpr char const * CXT_THREAD
Map a statement to its thread interleavings.
virtual bool mayAccessAliases(const Instruction *I1, const Instruction *I2)
bool collectCallsiteTargets()
std::string getSourceLoc(const Value *val)
Return source code including line number and file name from debug information.
Map< NodeID, Set< NodeID > > rthdToChildren
const Instruction * getPreviousMemoryAccessInst(const Instruction *I)
llvm::ConstantInt ConstantInt
std::string sucMsg(std::string msg)
Returns successful message by converting a string into green string output.
const Instruction * getInstruction1() const
MHP::ThreadStmtToThreadInterleav threadStmtToInterLeaving
std::string getOutput(const char *scenario, bool analysisRes, bool expectedRes)
Get the validation result string of a single validation scenario.
INTERLEV_FLAG validateInterleaving()
Validate the result of concurrent analysis.
RC_FLAG selectedValidationScenarios
virtual ~RaceResultValidator()
Destructor.
void collectValidationTargets()
Map< NodeID, NodeID > vthdTorthd
std::string getOutput(const char *scenario, bool analysisRes)
Map< NodeID, NodeID > rthdTovthd
NodeID getIntArg(const Instruction *inst, unsigned int arg_num)
llvm::Instruction Instruction
const Instruction * getInstruction2() const
virtual bool mayHaveDataRace(const Instruction *I1, const Instruction *I2)
Map< NodeID, CallStrCxt > vthdToCxt
std::vector< std::string > getStringArg(const Instruction *inst, unsigned int arg_num)
const SVFFunction * getCallee(const CallSite cs)
Return callee of a callsite. Return null if this is an indirect call.
bool hasValidationTarget() const
Check if the input program has validation target.
void validateAll()
Perform validation for all targets.
raw_ostream & outs()
Overwrite llvm::outs()
const Instruction * getPreviousMemoryAccessInst(const Instruction *I)
bool collectCxtThreadTargets()
MTAResultValidator(MHP *mh)
virtual bool mayHappenInParallel(const Instruction *I1, const Instruction *I2)
llvm::SparseBitVector NodeBS
static const INTERLEV_FLAG INTERLEV_IMPRECISE
bool collectInterleavingTargets()
static const INTERLEV_FLAG INTERLEV_TRUE
Constant INTERLEV_FLAG values.
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
bool isFlaged(const RC_FLAG flag) const
Class member access.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
CallStrCxt getCxtArg(const Instruction *inst, unsigned int arg_num)
void dumpCxt(const CallStrCxt &cxt) const
void dumpInterlev(NodeBS &lev)
std::vector< AccessPair > accessPairs
bool matchCxt(const CallStrCxt cxt1, const CallStrCxt cxt2) const
std::string errMsg(std::string msg)
Print error message by converting a string into red string output.
static constexpr char const * TCT_ACCESS
Map< NodeID, const CallInst * > csnumToInstMap
void init(SVFModule *M)
Initialization.