GP-3429 Intersect tests for stack affecting ops

This commit is contained in:
caheckman 2023-07-07 21:39:36 +00:00
parent d932173a25
commit 67b22166af
12 changed files with 432 additions and 15 deletions

View file

@ -26,6 +26,44 @@ class PcodeOp;
class FlowBlock;
class Varnode;
/// \brief A set of PcodeOps that can be tested for Cover intersections
///
/// This is a set of PcodeOp objects, designed for quick intersection tests with a Cover. The set is
/// lazily constructed via its populate() method at the time the first intersection test is needed.
/// Once an intersection has been established between a PcodeOp in \b this set and a Varnode Cover,
/// affectsTest() can do secondary testing to determine if the intersection should prevent merging.
class PcodeOpSet {
friend class Cover;
vector<PcodeOp *> opList; // Ops in this set, sorted on block index, then SeqNum::order
vector<int4> blockStart; // Index of first op in each non-empty block
bool is_pop; // Has the populate() method been called
protected:
void addOp(PcodeOp *op) { opList.push_back(op); } ///< Add a PcodeOp into the set
void finalize(void); // Sort ops in the set into blocks
public:
PcodeOpSet(void) { is_pop = false; }
bool isPopulated(void) const { return is_pop; } /// Return \b true if \b this set is populated
virtual ~PcodeOpSet(void) {}
/// \brief Populate the PcodeOp object in \b this set
///
/// Call-back to the owner to lazily add PcodeOps to \b this set. The override method calls addOp() for
/// each PcodeOp it wants to add, then calls finalize() to make \b this set ready for intersection tests.
virtual void populate(void)=0;
/// \brief (Secondary) test that the given PcodeOp affects the Varnode
///
/// This method is called after an intersection of a PcodeOp in \b this set with a Varnode Cover has been
/// determined. This allows the owner to make a final determination if merging should be prevented.
/// \param op is the PcodeOp that intersects with the Varnode Cover
/// \param vn is the Varnode whose Cover is intersected
/// \return \b true if merging should be prevented
virtual bool affectsTest(PcodeOp *op,Varnode *vn) const=0;
void clear(void) { is_pop = false; opList.clear(); blockStart.clear(); } ///< Clear all PcodeOps in \b this
static bool compareByBlock(const PcodeOp *a,const PcodeOp *b); ///< Compare PcodeOps for \b this set
};
/// \brief The topological scope of a variable within a basic block
///
/// Within a basic block, the topological scope of a variable can be considered
@ -78,6 +116,7 @@ public:
int4 intersect(const Cover &op2) const; ///< Characterize the intersection between \b this and another Cover.
int4 intersectByBlock(int4 blk,const Cover &op2) const; ///< Characterize the intersection on a specific block
void intersectList(vector<int4> &listout,const Cover &op2,int4 level) const;
bool intersect(const PcodeOpSet &opSet,Varnode *rep) const; ///< Does \b this cover any PcodeOp in the given PcodeOpSet
bool contain(const PcodeOp *op,int4 max) const;
int4 containVarnodeDef(const Varnode *vn) const;
void merge(const Cover &op2); ///< Merge \b this with another Cover block by block