Making a variable addressable in GIMPLE
Hi all, I'm trying to inject code that uses variable addresses into the first mudflap pass. These variables are not natively addressable in the program itself. The problem is that the first mudflap pass takes place at the GIMPLE level, at which point all variables have their addressable/non-addressable attributes set, which forbids me to build an ADDR_EXPR node for a non-addressable pointer variable ("invalid operand to unary & operator" error). Is there a way to change this attribute at the GIMPLE level, or do I need to move my pass back a few notches, before gimplification? Thanks, Yoav Etsion
Re: Making a variable addressable in GIMPLE
Hi Diego, Diego Novillo wrote: > Yoav Etsion wrote: > > >>The problem is that the first mudflap pass takes place at the GIMPLE >>level, at which point all variables have their >>addressable/non-addressable attributes set, which forbids me to build an >>ADDR_EXPR node for a non-addressable pointer variable ("invalid operand >>to unary & operator" error). >> > > Call build_addr() to create the ADDR_EXPR. It will set the > TREE_ADDRESSABLE bit on the variable and set some attributes on the > ADDR_EXPR itself. > The code is nicer, but still no go... :) > > That message suggest that you may be trying to build the address of a > non-decl, though. Show me the code and an example of your transformation? > The transformation is simple: mudflap already injects a call to __mf_register when an addressable variable is declared. I want to do the same for all pointer variables, so I've added the predicate POINTER_TYPE_P( TREE_TYPE(decl) ) to the eligibility test (performed on each VAR_DECL node). gcc is compiled with --enable-checking. The test code: >>> /* avoid including the entire header. */ extern int printf (const char * __format, ...); int main() { int data = 15; int *data_p = &data; printf("%d, %d\n", (int)data_p, data); return 0; } <<< The code dump after the first mudflap pass is: >>> { intD.0 data.0D.781; intD.0 data_p.1D.782; intD.0 D.783; intD.0 dataD.779; intD.0 * data_pD.780; try { __mf_register (&dataD.779, 4, 3, "simple-stack-pointer.c:6 (main) data"); __mf_register (&data_pD.780, 4, 3, "simple-stack-pointer.c:7 (main) data_p"); dataD.779 = 15; data_pD.780 = &dataD.779; data.0D.781 = dataD.779; data_p.1D.782 = (intD.0) data_pD.780; printf (&"%d, %d\n"[0], data_p.1D.782, data.0D.781); D.783 = 0; return D.783; } finally { __mf_unregister (&dataD.779, 4, 3); __mf_unregister (&data_pD.780, 4, 3); } } <<< The exact error message is: >>> simple-stack-pointer.c: In function 'main': simple-stack-pointer.c:5: error: Invalid operand to unary operator data_pD.780 simple-stack-pointer.c:5: internal compiler error: verify_stmts failed. please submit... <<< The error message directs me to the addressability of 'data_p'. Any ideas? Thanks, Yoav Etsion
Re: Making a variable addressable in GIMPLE
The pointer variable's address is used as the pointer's unique ID in a database, collecting information about each pointer variable - mostly its legal bounds. That way I can test when a pointer crosses its object's bounds. Terrible overhead, I know. Just need it to collect statistics about program (or programmer) behavior. Yoav Frank Ch. Eigler wrote: Yoav Etsion <[EMAIL PROTECTED]> writes: The transformation is simple: mudflap already injects a call to __mf_register when an addressable variable is declared. I want to do the same for all pointer variables [...] Why? If those pointers are not themselves taken address of, what kind access to the pointer value is worth checking? - FChE
Re: Making a variable addressable in GIMPLE
Frank Ch. Eigler wrote: Yoav Etsion <[EMAIL PROTECTED]> writes: The pointer variable's address is used as the pointer's unique ID in a database, collecting information about each pointer variable - mostly its legal bounds. That way I can test when a pointer crosses its object's bounds. ... But I may misunderstand the nature of checking you intend. Could you summarize your intended overall algorithm? (I'll answer this first, hoping it will also answer the previous two comments) My approach is simple: during dereference we have to check whether the pointer points within its legal boundaries, which should be those of the object assigned to it before any pointer arithmetic. Question is how do we know what the legal boundaries are, as pointer arithmeric might have caused our pointer to jump into an adjacent object? Now, think of the boundaries as attributes that can only change in pointer assignments (not arithmetic). We need to keep a database mapping pointers to boundaries, that is updated with each pointer assignment. So the three operations I need to intercept are pointer dereferences (code which already exists in mudflap2), pointer assignments, and pointer declarations to get the variable's address as the unique database ID (my current predicament). Since I assume automatically generated variables do not induce bugs (hopefully) I don't have to track them (come to think of it, maybe I can do with only assignments and dereferences). Using such database I can both check bounds, and more important to my current research to better understand programming habits and pointer flow. Hope this clears things up, and obviously any comments and suggestions are more than welcome. Yoav - FChE
tracking pointers in hardware
Hi all, I'm designing a new hardware that needs to know which GPR contains a simple integer, and which contained pointer. The hardware simply needs different load operations for both (we're talking load/store machines, with no indirect addressing to make life easier). From the compiler's perspective, all it needs is to annotate load operations to tell the hardware if this is a pointer or an integer (say LD for integers and PLD for pointers). As far as I can see, this data is not available in the final RTL stage: the RTL contains some pointer data about virtual registers at first, but it seems this data gets lost during optimizations, and mainly during the reload phase. Do any of you guys have suggestions how to implement it as part of gcc? My only idea for now is to add an RTL pass just before the final pass tracking dataflow to find which registers are used as addresses in loads/stores (but this can probably be done by dataflow tracking asm-to-asm filter). Thanks, Yoav Etsion