Sparse API¶
Utilities¶
Pointer list manipulation¶
-
int
ptr_list_size
(struct ptr_list *head)¶ Get the size of a ptrlist.
- Parameters
head – the head of the list
- Returns
the size of the list given by head.
-
bool
ptr_list_empty
(const struct ptr_list *head)¶ Test if a list is empty.
- Parameters
head – the head of the list
- Returns
true
if the list is empty,false
otherwise.
-
bool
ptr_list_multiple
(const struct ptr_list *head)¶ Test is a list contains more than one element.
- Parameters
head – the head of the list
- Returns
true
if the list has more than 1 element,false
otherwise.
-
void *
first_ptr_list
(struct ptr_list *head)¶ Get the first element of a ptrlist.
- Parameters
head – the head of the list
- Returns
the first element of the list or
NULL
if the list is empty
-
void *
last_ptr_list
(struct ptr_list *head)¶ Get the last element of a ptrlist.
- Parameters
head – the head of the list
- Returns
the last element of the list or
NULL
if the list is empty
-
void *
ptr_list_nth_entry
(struct ptr_list *list, unsigned int idx)¶ Get the nth element of a ptrlist.
- Parameters
head – the head of the list
- Returns
the nth element of the list or
NULL
if the list is too short.
-
int
linearize_ptr_list
(struct ptr_list *head, void **arr, int max)¶ Linearize the entries of a list.
- Parameters
head – the list to be linearized
arr – a
void*
array to fill with head’s entriesmax – the maximum number of entries to store into arr
- Returns
the number of entries linearized.
Linearize the entries of a list up to a total of max, and return the nr of entries linearized.
The array to linearize into (arr) should really be
void *x[]
, but we want to let people fill in any kind of pointer array, so let’s just call itvoid **
.
-
void
pack_ptr_list
(struct ptr_list **listp)¶ Pack a ptrlist.
- Parameters
listp – a pointer to the list to be packed.
When we’ve walked the list and deleted entries, we may need to re-pack it so that we don’t have any empty blocks left (empty blocks upset the walking code).
-
void
split_ptr_list_head
(struct ptr_list *head)¶ Split a ptrlist block.
- Parameters
head – the ptrlist block to be split
A new block is inserted just after head and the entries at the half end of head are moved to this new block. The goal being to create space inside head for a new entry.
-
void **
__add_ptr_list
(struct ptr_list **listp, void *ptr)¶ Add an entry to a ptrlist.
- Parameters
listp – a pointer to the list
ptr – the entry to add to the list
- Returns
the address where the new entry is stored.
- Note
code must not use this function and should use
add_ptr_list()
instead.
-
void **
__add_ptr_list_tag
(struct ptr_list **listp, void *ptr, unsigned long tag)¶ Add a tagged entry to a ptrlist.
- Parameters
listp – a pointer to the list
ptr – the entry to add to the list
tag – the tag to add to ptr
- Returns
the address where the new entry is stored.
- Note
code must not use this function and should use
add_ptr_list_tag()
instead.
-
bool
lookup_ptr_list_entry
(const struct ptr_list *head, const void *entry)¶ Test if some entry is already present in a ptrlist.
- Parameters
list – the head of the list
entry – the entry to test
- Returns
true
if the entry is already present,false
otherwise.
-
int
delete_ptr_list_entry
(struct ptr_list **list, void *entry, int count)¶ Delete an entry from a ptrlist.
- Parameters
list – a pointer to the list
entry – the item to be deleted
count – the minimum number of times entry should be deleted or 0.
-
int
replace_ptr_list_entry
(struct ptr_list **list, void *old_ptr, void *new_ptr, int count)¶ Replace an entry in a ptrlist.
- Parameters
list – a pointer to the list
old_ptr – the entry to be replaced
new_ptr – the new entry
count – the minimum number of times entry should be deleted or 0.
-
void *
undo_ptr_list_last
(struct ptr_list **head)¶ Remove the last entry of a ptrlist.
- Parameters
head – a pointer to the list
- Returns
the last element of the list or NULL if the list is empty.
- Note
this doesn’t repack the list
-
void *
delete_ptr_list_last
(struct ptr_list **head)¶ Remove the last entry and repack the list.
- Parameters
head – a pointer to the list
- Returns
the last element of the list or NULL if the list is empty.
-
void
concat_ptr_list
(struct ptr_list *a, struct ptr_list **b)¶ Concat two ptrlists.
- Parameters
a – the source list
b – a pointer to the destination list.
The element of a are added at the end of b.
-
void
copy_ptr_list
(struct ptr_list **listp, struct ptr_list *src)¶ Copy the elements of a list at the end of another list.
- Parameters
listp – a pointer to the destination list.
src – the head of the source list.
-
void
__free_ptr_list
(struct ptr_list **listp)¶ Free a ptrlist.
- Parameters
listp – a pointer to the list
Each blocks of the list are freed (but the entries themselves are not freed).
- Note
code must not use this function and should use the macro
free_ptr_list()
instead.
Miscellaneous utilities¶
-
unsigned int
hexval
(unsigned int c)¶ Return the value coresponding to an hexadecimal digit.
-
void *
xmemdup
(const void *src, size_t len)¶ Duplicate a memory buffer in a newly allocated buffer.
- Parameters
src – a pointer to the memory buffer to be duplicated
len – the size of the memory buffer to be duplicated
- Returns
a pointer to a copy of src allocated via
__alloc_bytes()
.
-
char *
xstrdup
(const char *src)¶ Duplicate a null-terminated string in a newly allocated buffer.
- Parameters
src – a pointer to string to be duplicated
- Returns
a pointer to a copy of str allocated via
__alloc_bytes()
.
-
char *
xasprintf
(const char *fmt, ...)¶ Printf to allocated string.
- Parameters
fmt – the format followed by its arguments.
- Returns
the allocated & formatted string.
This function is similar to asprintf() but the resulting string is allocated with __alloc_bytes().
-
char *
xvasprintf
(const char *fmt, va_list ap)¶ Vprintf to allocated string.
- Parameters
fmt – the format
ap – the variadic arguments
- Returns
the allocated & formatted string.
This function is similar to asprintf() but the resulting string is allocated with __alloc_bytes().
Parsing¶
Constant expression values¶
-
int
is_zero_constant
(struct expression *expr)¶ Test if an expression evaluates to the constant
0
.- Returns
1
if expr evaluate to0
,0
otherwise.
-
int
expr_truth_value
(struct expression *expr)¶ Test the compile time truth value of an expression.
- Returns
-1
if expr is not constant,0
or1
depending on the truth value of expr.
Typing¶
-
struct symbol *
evaluate_expression
(struct expression *expr)¶ Evaluate the type of an expression.
- Parameters
expr – the expression to be evaluated
- Returns
the type of the expression or
NULL
if the expression can’t be evaluated
-
struct symbol *
evaluate_statement
(struct statement *stmt)¶ Evaluate the type of a statement.
- Parameters
stmt – the statement to be evaluated
- Returns
the type of the statement or
NULL
if it can’t be evaluated
-
void
evaluate_symbol_list
(struct symbol_list *list)¶ Evaluate the type of a set of symbols.
- Parameters
list – the list of the symbol to be evaluated
-
int
evaluate_arguments
(struct symbol_list *argtypes, struct expression_list *args)¶ Evaluate the arguments of a function.
- Parameters
argtypes – the list of the types in the prototype
args – the list of the effective arguments
Optimization¶
Instruction simplification¶
Notation¶
The following conventions are used to describe the simplications:
Uppercase letters are reserved for constants:
M for a constant mask,
S for a constant shift,
N for a constant number of bits (usually other than a shift),
C or ‘K’ for others constants.
Lowercase letters a, b, x, y, … are used for non-constants or when it doesn’t matter if the pseudo is a constant or not.
Primes are used if needed to distinguish symbols (M, M’, …).
Expressions or sub-expressions involving only constants are understood to be evaluated.
$mask(N) is used for ((1 << N) -1)
$trunc(x, N) is used for (x & $mask(N))
Expressions like (-1 << S), (-1 >> S) and others formulae are understood to be truncated to the size of the current instruction (needed, since in general this size is not the same as the one used by sparse for the evaluation of arithmetic operations).
TRUNC(x, N) is used for a truncation to a size of N bits
ZEXT(x, N) is used for a zero-extension from a size of N bits
OP(x, C) is used to represent some generic operation using a constant, including when the constant is implicit (e.g. TRUNC(x, N)).
MASK(x, M) is used to respresent a ‘masking’ instruction:
AND(x, M)
LSR(x, S), with M = (-1 << S)
SHL(x, S), with M = (-1 >> S)
TRUNC(x, N), with M = $mask(N)
ZEXT(x, N), with M = $mask(N)
SHIFT(x, S) is used for LSR(x, S) or SHL(x, S).
Utilities¶
-
static struct basic_block *
phi_parent
(struct basic_block *source, pseudo_t pseudo)¶ Find the trivial parent for a phi-source.
-
static int
get_phisources
(struct instruction *sources[], int nbr, struct instruction *insn)¶ Copy the phi-node’s phisrcs into to given array.
- Returns
0 if the the list contained the expected number of element, a positive number if there was more than expected and a negative one if less.
- Note
we can’t reuse a function like linearize_ptr_list() because any VOIDs in the phi-list must be ignored here as in this context they mean ‘entry has been removed’.
-
static pseudo_t
trivial_phi
(pseudo_t pseudo, struct instruction *insn, struct pseudo_list **list)¶ Detect trivial phi-nodes.
- Parameters
insn – the phi-node
pseudo – the candidate resulting pseudo (NULL when starting)
- Returns
the unique result if the phi-node is trivial, NULL otherwise
- A phi-node is trivial if it has a single possible result:
all operands are the same
- the operands are themselves defined by a chain or cycle of phi-nodes
and the set of all operands involved contains a single value not defined by these phi-nodes
Since the result is unique, these phi-nodes can be removed.
-
int
kill_insn
(struct instruction *insn, int force)¶ Kill an instruction.
- Parameters
insn – the instruction to be killed
force – if unset, the normal case, the instruction is not killed if not free of possible side-effect; if set the instruction is unconditionally killed.
The killed instruction is removed from its BB and the usage of all its operands are removed. The instruction is also marked as killed by setting its ->bb to NULL.
-
static int
dead_insn
(struct instruction *insn, pseudo_t *src1, pseudo_t *src2, pseudo_t *src3)¶ Kill trivially dead instructions.
-
static inline int
replace_pseudo
(struct instruction *insn, pseudo_t *pp, pseudo_t new)¶ Replace the operand of an instruction.
- Parameters
insn – the instruction
pp – the address of the instruction’s operand
new – the new value for the operand
- Returns
REPEAT_CSE.
-
static unsigned int
operand_size
(struct instruction *insn, pseudo_t pseudo)¶ Try to determine the maximum size of bits in a pseudo.
Right now this only follow casts and constant values, but we could look at things like AND instructions, etc.
Simplifications¶
-
static int
simplify_mask_or_and
(struct instruction *insn, unsigned long long mask, pseudo_t ora, pseudo_t orb)¶ Try to simplify MASK(OR(AND(x, M’), b), M).
- Parameters
insn – the masking instruction
mask – the associated mask (M)
ora – one of the OR’s operands, guaranteed to be PSEUDO_REG
orb – the other OR’s operand
- Returns
0 if no changes have been made, one or more REPEAT_* flags otherwise.
-
static int
simplify_mask_or
(struct instruction *insn, unsigned long long mask, struct instruction *or)¶ Try to simplify MASK(OR(a, b), M).
- Parameters
insn – the masking instruction
mask – the associated mask (M)
or – the OR instruction
- Returns
0 if no changes have been made, one or more REPEAT_* flags otherwise.
-
static int
simplify_mask_shift_or
(struct instruction *sh, struct instruction *or, unsigned long long mask)¶ Try to simplify MASK(SHIFT(OR(a, b), S), M).
- Parameters
sh – the shift instruction
or – the OR instruction
mask – the mask associated to MASK (M):
- Returns
0 if no changes have been made, one or more REPEAT_* flags otherwise.
-
static int
simplify_memop
(struct instruction *insn)¶ Simplify memops instructions.
- Note
We walk the whole chain of adds/subs backwards. That’s not only more efficient, but it allows us to find loops.
-
static int
simplify_cond_branch
(struct instruction *br, struct instruction *def, pseudo_t newcond)¶ Simplify SET_NE/EQ $0 + BR.