15 struct instruction
*insn
;
19 DECLARE_ALLOCATOR(pseudo_user
);
20 DECLARE_PTR_LIST(pseudo_user_list
, struct pseudo_user
);
21 DECLARE_PTRMAP(phi_map
, struct symbol
*, pseudo_t
);
36 enum pseudo_type type
;
37 struct pseudo_user_list
*users
;
41 struct instruction
*def
;
47 extern struct pseudo void_pseudo
;
49 #define VOID (&void_pseudo)
51 static inline bool is_zero(pseudo_t pseudo
)
53 return pseudo
->type
== PSEUDO_VAL
&& pseudo
->value
== 0;
56 static inline bool is_nonzero(pseudo_t pseudo
)
58 return pseudo
->type
== PSEUDO_VAL
&& pseudo
->value
!= 0;
63 struct basic_block
*target
;
67 struct asm_constraint
{
69 const char *constraint
;
70 const struct ident
*ident
;
73 DECLARE_ALLOCATOR(asm_constraint
);
74 DECLARE_PTR_LIST(asm_constraint_list
, struct asm_constraint
);
77 struct asm_constraint_list
*inputs
;
78 struct asm_constraint_list
*outputs
;
79 struct asm_constraint_list
*clobbers
;
82 DECLARE_ALLOCATOR(asm_rules
);
88 struct basic_block
*bb
;
93 struct /* entrypoint */ {
94 struct pseudo_list
*arg_list
;
98 struct basic_block
*bb_true
, *bb_false
;
100 struct /* switch */ {
102 struct multijmp_list
*multijmp_list
;
104 struct /* phi_node */ {
105 pseudo_t phi_var
; // used for SSA conversion
106 struct pseudo_list
*phi_list
;
109 struct /* phi source */ {
111 struct instruction_list
*phi_users
;
115 struct symbol
*orig_type
; /* casts */
117 struct /* memops */ {
118 pseudo_t addr
; /* alias .src */
120 unsigned int is_volatile
:1;
122 struct /* binops and sel */ {
123 pseudo_t src1
, src2
, src3
;
129 struct /* setval */ {
130 struct expression
*val
;
132 struct /* setfval */ {
137 struct pseudo_list
*arguments
;
138 struct symbol_list
*fntypes
;
140 struct /* context */ {
143 struct expression
*context_expr
;
147 struct asm_rules
*asm_rules
;
152 struct basic_block_list
;
153 struct instruction_list
;
157 unsigned long generation
;
160 int postorder_nr
; /* postorder number */
161 int dom_level
; /* level in the dominance tree */
163 struct entrypoint
*ep
;
164 struct basic_block_list
*parents
; /* sources */
165 struct basic_block_list
*children
; /* destinations */
166 struct instruction_list
*insns
; /* Linear list of instructions */
167 struct basic_block
*idom
; /* link to the immediate dominator */
168 struct basic_block_list
*doms
; /* list of BB idominated by this one */
169 struct phi_map
*phi_map
;
170 struct pseudo_list
*needs
, *defines
;
172 unsigned int nr
; /* unique id for label's names */
179 // return the opcode of the instruction defining ``SRC`` if existing
180 // and OP_BADOP if not. It also assigns the defining instruction
182 #define DEF_OPCODE(DEF, SRC) \
183 (((SRC)->type == PSEUDO_REG && (DEF = (SRC)->def)) ? DEF->opcode : OP_BADOP)
186 static inline void add_bb(struct basic_block_list
**list
, struct basic_block
*bb
)
188 add_ptr_list(list
, bb
);
191 static inline void add_instruction(struct instruction_list
**list
, struct instruction
*insn
)
193 add_ptr_list(list
, insn
);
196 static inline void add_multijmp(struct multijmp_list
**list
, struct multijmp
*multijmp
)
198 add_ptr_list(list
, multijmp
);
201 static inline pseudo_t
*add_pseudo(struct pseudo_list
**list
, pseudo_t pseudo
)
203 return add_ptr_list(list
, pseudo
);
206 static inline int remove_pseudo(struct pseudo_list
**list
, pseudo_t pseudo
)
208 return delete_ptr_list_entry((struct ptr_list
**)list
, pseudo
, 0) != 0;
211 static inline int pseudo_in_list(struct pseudo_list
*list
, pseudo_t pseudo
)
213 return lookup_ptr_list_entry((struct ptr_list
*)list
, pseudo
);
216 static inline int bb_terminated(struct basic_block
*bb
)
218 struct instruction
*insn
;
221 insn
= last_instruction(bb
->insns
);
222 return insn
&& insn
->opcode
>= OP_TERMINATOR
223 && insn
->opcode
<= OP_TERMINATOR_END
;
226 static inline int bb_reachable(struct basic_block
*bb
)
231 static inline int lookup_bb(struct basic_block_list
*list
, struct basic_block
*bb
)
233 return lookup_ptr_list_entry((struct ptr_list
*)list
, bb
);
237 static inline void add_pseudo_user_ptr(struct pseudo_user
*user
, struct pseudo_user_list
**list
)
239 add_ptr_list(list
, user
);
242 static inline int has_use_list(pseudo_t p
)
244 return (p
&& p
->type
!= PSEUDO_VOID
&& p
->type
!= PSEUDO_UNDEF
&& p
->type
!= PSEUDO_VAL
);
247 static inline int pseudo_user_list_size(struct pseudo_user_list
*list
)
249 return ptr_list_size((struct ptr_list
*)list
);
252 static inline bool pseudo_user_list_empty(struct pseudo_user_list
*list
)
254 return ptr_list_empty((struct ptr_list
*)list
);
257 static inline int has_users(pseudo_t p
)
259 return !pseudo_user_list_empty(p
->users
);
262 static inline bool multi_users(pseudo_t p
)
264 return ptr_list_multiple((struct ptr_list
*)(p
->users
));
267 static inline int nbr_users(pseudo_t p
)
269 return pseudo_user_list_size(p
->users
);
272 static inline struct pseudo_user
*alloc_pseudo_user(struct instruction
*insn
, pseudo_t
*pp
)
274 struct pseudo_user
*user
= __alloc_pseudo_user(0);
280 static inline void use_pseudo(struct instruction
*insn
, pseudo_t p
, pseudo_t
*pp
)
284 add_pseudo_user_ptr(alloc_pseudo_user(insn
, pp
), &p
->users
);
287 static inline void remove_bb_from_list(struct basic_block_list
**list
, struct basic_block
*entry
, int count
)
289 delete_ptr_list_entry((struct ptr_list
**)list
, entry
, count
);
292 static inline void replace_bb_in_list(struct basic_block_list
**list
,
293 struct basic_block
*old
, struct basic_block
*new, int count
)
295 replace_ptr_list_entry((struct ptr_list
**)list
, old
, new, count
);
300 struct symbol_list
*syms
;
301 struct pseudo_list
*accesses
;
302 struct basic_block_list
*bbs
;
303 struct basic_block
*active
;
304 struct instruction
*entry
;
305 unsigned int dom_levels
; /* max levels in the dom tree */
308 extern void insert_select(struct basic_block
*bb
, struct instruction
*br
, struct instruction
*phi
, pseudo_t if_true
, pseudo_t if_false
);
309 extern void insert_branch(struct basic_block
*bb
, struct instruction
*br
, struct basic_block
*target
);
311 struct instruction
*alloc_phisrc(pseudo_t pseudo
, struct symbol
*type
);
312 struct instruction
*alloc_phi_node(struct basic_block
*bb
, struct symbol
*type
, struct ident
*ident
);
313 struct instruction
*insert_phi_node(struct basic_block
*bb
, struct symbol
*var
);
314 void add_phi_node(struct basic_block
*bb
, struct instruction
*phi_node
);
316 pseudo_t
alloc_phi(struct basic_block
*source
, pseudo_t pseudo
, struct symbol
*type
);
317 pseudo_t
alloc_pseudo(struct instruction
*def
);
318 pseudo_t
value_pseudo(long long val
);
319 pseudo_t
undef_pseudo(void);
321 struct entrypoint
*linearize_symbol(struct symbol
*sym
);
322 int unssa(struct entrypoint
*ep
);
323 void show_entry(struct entrypoint
*ep
);
324 const char *show_pseudo(pseudo_t pseudo
);
325 void show_bb(struct basic_block
*bb
);
326 const char *show_instruction(struct instruction
*insn
);
327 const char *show_label(struct basic_block
*bb
);
329 #endif /* LINEARIZE_H */