-
Notifications
You must be signed in to change notification settings - Fork 131
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
Hybrid memory representation #400
base: dev10
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments mainly for my understanding...
lib/seahorn/BvOpSem2MemRepr.cc
Outdated
/** | ||
* rewriter for store expr: | ||
* e = store A idx val -> { return ite( (idx == ptr), val, rewrite(A) )} | ||
* e is not store (const array or terminal register) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC changing store
to ite
will allow us to hit the SAT
solver rather than the SMT
solver which knows about arrays.
lib/seahorn/BvOpSem2MemRepr.cc
Outdated
Expr doPtrEq(Expr p1, Expr p2) { return m_alu.doEq(p1, p2, m_ptrSz); } | ||
|
||
Expr operator()(Expr e) { | ||
if (isOp<STORE>(e)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will adding an assert
that we expect a struct with three fields help with debugging?
lib/seahorn/BvOpSem2MemRepr.cc
Outdated
LOG("opsem-hybrid", INFO << "From ptr " << *mem.toExpr() << "\n"); | ||
|
||
/** rewrite store into ITE **/ | ||
ArrayStoreRewriter rw(ptr.toExpr(), m_ctx.alu(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC when we load
we lazily rewrite the store
instructions in the memory array rather than rewriting everytime we store... is this correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. optimizing while doing so. next layer is to optimize store instructions to simplify load optimizations later on
6a0fddc
to
61e489f
Compare
d726b99
to
716e1ac
Compare
6d8770b
to
2d51832
Compare
2d51832
to
9344400
Compare
include/seahorn/Expr/ExprRewriter.hh
Outdated
Expr rewriteITEComp(Expr exp); | ||
|
||
struct RewriteFrame { | ||
Expr m_exp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment the role of the fields
include/seahorn/Expr/ExprRewriter.hh
Outdated
/* apply rewrite rules */ | ||
protected: | ||
ExprFactory &m_efac; // for making expr | ||
EZ3 &m_zctx; // for z3 simplifier if needed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why generic rewriter should depend on Z3. Its specialization can, but the generic rewriter should not
include/seahorn/Expr/ExprRewriter.hh
Outdated
protected: | ||
Config m_config; | ||
ExprFactory &m_efac; // for making expr | ||
EZ3 &m_zctx; // for z3 simplifier if needed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should not be part of generic rewriter
include/seahorn/Expr/ExprRewriter.hh
Outdated
in any of the above case, push e to top of result stack | ||
otherwise return false and push e into top of rewriteStack | ||
*/ | ||
bool visited(Expr e, size_t depth) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the function has too many side-effects. The name does not reflect them all, neither does the comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps renaming the function into visit
would go long way to address the comment above
include/seahorn/Expr/ExprRewriter.hh
Outdated
rewrite_result rwRes = m_config.applyRewriteRules(new_exp); | ||
if (rwRes.status == rewrite_status::RW_DONE) { | ||
m_resultStack.push_back(rwRes.rewritten); | ||
if (exp->use_count() > 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replace exp->use_count() > 1
with shouldCache
function for readability. Here and elsewhere
include/seahorn/Expr/ExprRewriter.hh
Outdated
m_resultStack.resize(begin); | ||
// apply rewrite rules to expression with new kids | ||
rewrite_result rwRes = m_config.applyRewriteRules(new_exp); | ||
if (rwRes.status == rewrite_status::RW_DONE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there has to be a way for a rule to indicate that no rewrite has happened. In this case, the result should not be cached.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps add a new status RW_SKIPPED
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RW_SKIP
include/seahorn/Expr/ExprVisitor.hh
Outdated
/* Pair <mem, ptr> */ | ||
using DagVisitMemCache = std::unordered_map<ENode *, ExprPair>; | ||
|
||
inline Expr findInDagVisitCache(DagVisitCache &cache, Expr expr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this for? Document
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if this is needed anymore
2a23a0d
to
ac0b752
Compare
853ce4e
to
7eea7fc
Compare
} | ||
} | ||
// ite(true, a, b) => a | ||
if (isOpX<TRUE>(i)) { | ||
return {t, rewrite_status::RW_1}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why RW_1
? a
is already rewritten
} | ||
// ite(false, a, b) => b | ||
if (isOpX<FALSE>(i)) { | ||
return {e, rewrite_status::RW_1}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RW_DONE
@@ -151,7 +152,45 @@ struct BoolOpRewriteRule : public ExprRewriteRule { | |||
if (isOpX<NEG>(exp)) { | |||
Expr neg = exp->arg(0); | |||
if (isOpX<NEG>(neg)) { | |||
return {neg->arg(0), rewrite_status::RW_2}; | |||
return {neg->arg(0), rewrite_status::RW_1}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RW_DONE
Expr e = arr->arg(2); | ||
Expr new_t = op::array::select(t, idx); | ||
Expr new_e = op::array::select(e, idx); | ||
return {mk<ITE>(i, new_t, new_e), rewrite_status::RW_2}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall, this is potentially very expensive in our application. It will create a lot of intermediate expressions while select
is being pushed down. It would be more effective to implement push_select_over_ite
method that pushes select to the bottom of the ite
tree in one operation.
/** Read-over-write: select(store(arr_w, idx_w, val), idx_r) | ||
==> ite(idx_w == idx_x, val, select(arr_w, idx_r)) | ||
**/ | ||
if (isOpX<STORE>(arr)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as above. Need a single operation that pushes select down a chain of stores, and maybe a combination that pushes select through the chain of ite and store
8d1d06e
to
4dc0a6c
Compare
4dc0a6c
to
55d832c
Compare
} | ||
|
||
AddrRange zeroBitsRange(AddrRange &r, size_t bits) { | ||
unsigned new_low = r.low >> bits; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should check or assume r.isTop == false
at first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch so that we can skip some operations
lib/seahorn/Smt/ExprRewriter.cc
Outdated
} | ||
} // namespace utils | ||
|
||
Expr rewriteHybridLoadMemExpr(Expr loadMem, Expr ptr, AddrRangeMap &arm) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am confused about parameters you passed for this method. Why you add ptr
but not use it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
include/seahorn/Expr/ExprRewriter.hh
Outdated
ITECompRewriteConfig(ExprFactory &efac, DagVisitCache &cache, | ||
AddrRangeMap &arm) | ||
: m_iteRule(efac, cache), m_compRule(efac, cache), | ||
m_boolRule(efac, cache), m_arrayRule(efac, cache, arm), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you only use ARM for select
only. Maybe I did not fully get the usage of the ARM. Can Arm be used for other pointer expressions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can perhaps use it during the initial rewrite from store
s to ITE
s
54af027
to
41be486
Compare
(to sqaush): use rewriter to apply pattern recursively feat(ExprVisitor): set selected kids to visit instead of always visit all (tsquash): use more restrained vistor to only visit first arg of store (tsquash): rename, cleanup use simple custom rewriter for array store; revert m_selectedKids
in house version is gud feat(mem-repr): iterative rewriter for ITE expr
(intrim): cached visit; stateless rules (intrim): OOP design
draft(nmr): present stack ptr expr with based obj type draft(nmr): low precision but sound addr filtering draft(hybrid): push down bvadd; better addrs range draft(hybrid): AddrRange data struc to keep track of isTop
966c04f
to
af1b26b
Compare
af1b26b
to
a3b486f
Compare
@danblitzhou can we close this PR? |
Yes, the new PR should replace this one.
Arie Gurfinkel ***@***.***>于2022年12月9日 周五下午3:15写道:
… @danblitzhou <https://github.com/danblitzhou> can we close this PR?
—
Reply to this email directly, view it on GitHub
<#400 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEHINGS3NR7HTQ6AZNP2KZ3WMOHM5ANCNFSM434L376A>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
OpSemMemHybridRepr
: store: array theory, load: ITEstore
Expr duringloadAlignedWordFromMem
for hybrid repr