|
From: Julian S. <js...@ac...> - 2012-11-05 15:33:49
|
I've been working on an implementation of this on and off (mostly off)
for a a while, using the ARM front end as a driver since it is a convenient
source of conditional loads/stores. It works well enough now to run
Firefox on ARM (--tool=none). Mostly this involved iterating the
representation to something usable and then fixing up the IR pipeline
(including ir_opt) to handle it. The resulting definitions are below.
Next step is to fix up all the tools to handle the changes. Might not
be too easy, since many tools look at loads and stores but assume they
are unconditional.
There are two new IRStmt_ kinds now, IRStmt_StoreG and IRStmt_LoadG.
("store guarded", "load guarded"). Since both require quite a few fields
these are just pointers to auxiliary structures as shown below, in the
style of the existing IRDirty, etc.
J
/* --------------- Guarded loads and stores --------------- */
/* Conditional stores are straightforward. They are the same as
normal stores, with an extra 'guard' field :: Ity_I1 that
determines whether or not the store actually happens. If not,
memory is unmodified.
The semantics of this is that 'addr' and 'data' are fully evaluated
even in the case where 'guard' evaluates to zero (false).
*/
typedef
struct {
IREndness end; /* Endianness of the store */
IRExpr* addr; /* store address */
IRExpr* data; /* value to write */
IRExpr* guard; /* Guarding value */
}
IRStoreG;
/* Conditional loads are a little more complex. 'addr' is the
address, 'guard' is the guarding condition. If the load takes
place, the loaded value is placed in 'dst'. If it does not take
place, 'alt' is copied to 'dst'. However, the loaded value is not
placed directly in 'dst' -- it is first subjected to the conversion
specified by 'cvt'.
For example, imagine doing a conditional 8-bit load, in which the
loaded value is zero extended to 32 bits. Hence:
* 'dst' and 'alt' must have type I32
* 'cvt' must be a unary op which converts I8 to I32. In this
example, it would be ILGop_8Uto32.
There is no explicit indication of the type at which the load is
done, since that is inferrable from the arg type of 'cvt'. Note
that the types of 'alt' and 'dst' and the result type of 'cvt' must
all be the same.
Semantically, 'addr' is evaluated even in the case where 'guard'
evaluates to zero (false), and 'alt' is evaluated even when 'guard'
evaluates to one (true). That is, 'addr' and 'alt' are always
evaluated.
*/
typedef
enum {
ILGop_INVALID=0x1D00,
ILGop_Ident32, /* 32 bit, no conversion */
ILGop_16Uto32, /* 16 bit load, Z-widen to 32 */
ILGop_16Sto32, /* 16 bit load, S-widen to 32 */
ILGop_8Uto32, /* 8 bit load, Z-widen to 32 */
ILGop_8Sto32 /* 8 bit load, S-widen to 32 */
}
IRLoadGOp;
typedef
struct {
IREndness end; /* Endianness of the load */
IRLoadGOp cvt; /* Conversion to apply to the loaded value */
IRTemp dst; /* Destination (LHS) of assignment */
IRExpr* addr; /* Address being loaded from */
IRExpr* alt; /* Value if load is not done. */
IRExpr* guard; /* Guarding value */
}
IRLoadG;
extern void ppIRStoreG ( IRStoreG* sg );
extern void ppIRLoadGOp ( IRLoadGOp cvt );
extern void ppIRLoadG ( IRLoadG* lg );
extern IRStoreG* mkIRStoreG ( IREndness end,
IRExpr* addr, IRExpr* data,
IRExpr* guard );
extern IRLoadG* mkIRLoadG ( IREndness end, IRLoadGOp cvt,
IRTemp dst, IRExpr* addr, IRExpr* alt,
IRExpr* guard );
On Friday, October 12, 2012, Florian Krohm wrote:
> On 10/12/2012 04:36 AM, Julian Seward wrote:
> > On Friday, October 12, 2012, Florian Krohm wrote:
> >> While we're at it... Can I have a Ist_PutC -- a conditional Put ?
> >>
> >> PutC ( guard_expr, offset, data_temp)
> >>
> >> If guard_expr is true, then data_temp will be stored at offset in guest
> >> state. That would help s390.
> >
> > Hmm, I'd prefer not, unless you absolutely need it. What do you need
> > it for?
>
> I should have been more clear.. I could need it to implement a
> conditional assignment to a register with these semantics:
>
> r4 = guard_expr ? new_value : r4;
>
> Sure, I can (and do) implement that with today's machinery but with a
> PutC I can have a more efficient implementation.
>
> Florian
>
> ---------------------------------------------------------------------------
> --- Don't let slow site performance ruin your business. Deploy New Relic
> APM Deploy New Relic app performance management and know exactly
> what is happening inside your Ruby, Python, PHP, Java, and .NET app
> Try New Relic at no cost today and get our sweet Data Nerd shirt too!
> http://p.sf.net/sfu/newrelic-dev2dev
> _______________________________________________
> Valgrind-developers mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-developers
|