diff options
author | 2007-01-16 18:36:16 -0800 | |
---|---|---|
committer | 2007-01-16 20:47:04 -0800 | |
commit | e7fb6e092055425e404052bfc9ffefd38365c009 (patch) | |
tree | 7c1cd6c88d690be4332440898bd9865fbb5f5abc /linearize.h | |
parent | Change the symbol access list to a pseudo list (diff) | |
download | sparse-e7fb6e092055425e404052bfc9ffefd38365c009.tar.gz sparse-e7fb6e092055425e404052bfc9ffefd38365c009.tar.bz2 sparse-e7fb6e092055425e404052bfc9ffefd38365c009.zip |
Add instruction to pseudo user tracking.
The current way of tracking pseudo register user is by
keeping a list of the address of the pseudo_t member.
This address can be in part of the instruction member, the
worse case is in the argument list of the call instruction.
As the comment for address_taken() said, using the container
to get instruction pointer is wrong. It use to work with instruction
that relate to symbol address. But that is not true any more. Even
worse, it is very hard to track the pseudo usage other than symbol
address. The only reason symbol address used to works for call instruction
is because call instruction did not directly use the symbol address.
I bit the bullet and just add the instruction pointer to pair with
the pseudo user pointer. So it will work with the case that the
user instruction is call as well.
Testing:
I compare the linearize result with/without the patch on a few
sparse source file it self. The linearize generate exactly
the same result except the symbol address changes. Which is
predictable different because the pseudo user structure allocate
memory.
Singed-Off-By: Christopher Li <sparse@chrisli.org>
Diffstat (limited to 'linearize.h')
-rw-r--r-- | linearize.h | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/linearize.h b/linearize.h index ace0434..e5ed1f8 100644 --- a/linearize.h +++ b/linearize.h @@ -9,6 +9,15 @@ struct instruction; DECLARE_PTR_LIST(pseudo_ptr_list, pseudo_t); +struct pseudo_user { + struct instruction *insn; + pseudo_t *userp; +}; + +DECLARE_ALLOCATOR(pseudo_user); +DECLARE_PTR_LIST(pseudo_user_list, struct pseudo_user); + + enum pseudo_type { PSEUDO_VOID, PSEUDO_REG, @@ -21,7 +30,7 @@ enum pseudo_type { struct pseudo { int nr; enum pseudo_type type; - struct pseudo_ptr_list *users; + struct pseudo_user_list *users; struct ident *ident; union { struct symbol *sym; @@ -268,16 +277,29 @@ static inline void add_pseudo_ptr(pseudo_t *ptr, struct pseudo_ptr_list **list) add_ptr_list(list, ptr); } +static inline void add_pseudo_user_ptr(struct pseudo_user *user, struct pseudo_user_list **list) +{ + add_ptr_list(list, user); +} + static inline int has_use_list(pseudo_t p) { return (p && p->type != PSEUDO_VOID && p->type != PSEUDO_VAL); } -static inline void use_pseudo(pseudo_t p, pseudo_t *pp) +static inline struct pseudo_user* alloc_pseudo_user(struct instruction *insn, pseudo_t *pp) +{ + struct pseudo_user *user = __alloc_pseudo_user(0); + user->userp = pp; + user->insn = insn; + return user; +} + +static inline void use_pseudo(struct instruction *insn, pseudo_t p, pseudo_t *pp) { *pp = p; if (has_use_list(p)) - add_pseudo_ptr(pp, &p->users); + add_pseudo_user_ptr(alloc_pseudo_user(insn, pp), &p->users); } static inline void remove_bb_from_list(struct basic_block_list **list, struct basic_block *entry, int count) |