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
;
71 unsigned int is_memory
:1;
74 DECLARE_ALLOCATOR(asm_constraint
);
75 DECLARE_PTR_LIST(asm_constraint_list
, struct asm_constraint
);
78 struct asm_constraint_list
*inputs
;
79 struct asm_constraint_list
*outputs
;
80 struct asm_constraint_list
*clobbers
;
83 DECLARE_ALLOCATOR(asm_rules
);
89 struct basic_block
*bb
;
94 struct /* entrypoint */ {
95 struct pseudo_list
*arg_list
;
99 struct basic_block
*bb_true
, *bb_false
;
101 struct /* switch */ {
103 struct multijmp_list
*multijmp_list
;
105 struct /* phi_node */ {
106 pseudo_t phi_var
; // used for SSA conversion
107 struct pseudo_list
*phi_list
;
110 struct /* phi source */ {
112 struct instruction_list
*phi_users
;
116 struct symbol
*orig_type
; /* casts */
118 struct /* memops */ {
119 pseudo_t addr
; /* alias .src */
121 unsigned int is_volatile
:1;
123 struct /* binops and sel */ {
124 pseudo_t src1
, src2
, src3
;
130 struct /* setval */ {
131 struct expression
*val
;
133 struct /* setfval */ {
138 struct pseudo_list
*arguments
;
139 struct symbol_list
*fntypes
;
141 struct /* context */ {
144 struct expression
*context_expr
;
148 struct asm_rules
*asm_rules
;
153 struct basic_block_list
;
154 struct instruction_list
;
158 unsigned long generation
;
161 int postorder_nr
; /* postorder number */
162 int dom_level
; /* level in the dominance tree */
164 struct entrypoint
*ep
;
165 struct basic_block_list
*parents
; /* sources */
166 struct basic_block_list
*children
; /* destinations */
167 struct instruction_list
*insns
; /* Linear list of instructions */
168 struct basic_block
*idom
; /* link to the immediate dominator */
169 struct basic_block_list
*doms
; /* list of BB idominated by this one */
170 struct phi_map
*phi_map
;
171 struct pseudo_list
*needs
, *defines
;
173 unsigned int nr
; /* unique id for label's names */
180 // return the opcode of the instruction defining ``SRC`` if existing
181 // and OP_BADOP if not. It also assigns the defining instruction
183 #define DEF_OPCODE(DEF, SRC) \
184 (((SRC)->type == PSEUDO_REG && (DEF = (SRC)->def)) ? DEF->opcode : OP_BADOP)
187 static inline void add_bb(struct basic_block_list
**list
, struct basic_block
*bb
)
189 add_ptr_list(list
, bb
);
192 static inline void add_instruction(struct instruction_list
**list
, struct instruction
*insn
)
194 add_ptr_list(list
, insn
);
197 static inline void add_multijmp(struct multijmp_list
**list
, struct multijmp
*multijmp
)
199 add_ptr_list(list
, multijmp
);
202 static inline pseudo_t
*add_pseudo(struct pseudo_list
**list
, pseudo_t pseudo
)
204 return add_ptr_list(list
, pseudo
);
207 static inline int remove_pseudo(struct pseudo_list
**list
, pseudo_t pseudo
)
209 return delete_ptr_list_entry((struct ptr_list
**)list
, pseudo
, 0) != 0;
212 static inline int pseudo_in_list(struct pseudo_list
*list
, pseudo_t pseudo
)
214 return lookup_ptr_list_entry((struct ptr_list
*)list
, pseudo
);
217 static inline int bb_terminated(struct basic_block
*bb
)
219 struct instruction
*insn
;
222 insn
= last_instruction(bb
->insns
);
223 return insn
&& insn
->opcode
>= OP_TERMINATOR
224 && insn
->opcode
<= OP_TERMINATOR_END
;
227 static inline int bb_reachable(struct basic_block
*bb
)
232 static inline int lookup_bb(struct basic_block_list
*list
, struct basic_block
*bb
)
234 return lookup_ptr_list_entry((struct ptr_list
*)list
, bb
);
238 static inline void add_pseudo_user_ptr(struct pseudo_user
*user
, struct pseudo_user_list
**list
)
240 add_ptr_list(list
, user
);
243 static inline int has_use_list(pseudo_t p
)
245 return (p
&& p
->type
!= PSEUDO_VOID
&& p
->type
!= PSEUDO_UNDEF
&& p
->type
!= PSEUDO_VAL
);
248 static inline int pseudo_user_list_size(struct pseudo_user_list
*list
)
250 return ptr_list_size((struct ptr_list
*)list
);
253 static inline bool pseudo_user_list_empty(struct pseudo_user_list
*list
)
255 return ptr_list_empty((struct ptr_list
*)list
);
258 static inline int has_users(pseudo_t p
)
260 return !pseudo_user_list_empty(p
->users
);
263 static inline bool multi_users(pseudo_t p
)
265 return ptr_list_multiple((struct ptr_list
*)(p
->users
));
268 static inline int nbr_users(pseudo_t p
)
270 return pseudo_user_list_size(p
->users
);
273 static inline struct pseudo_user
*alloc_pseudo_user(struct instruction
*insn
, pseudo_t
*pp
)
275 struct pseudo_user
*user
= __alloc_pseudo_user(0);
281 static inline void use_pseudo(struct instruction
*insn
, pseudo_t p
, pseudo_t
*pp
)
285 add_pseudo_user_ptr(alloc_pseudo_user(insn
, pp
), &p
->users
);
288 static inline void remove_bb_from_list(struct basic_block_list
**list
, struct basic_block
*entry
, int count
)
290 delete_ptr_list_entry((struct ptr_list
**)list
, entry
, count
);
293 static inline void replace_bb_in_list(struct basic_block_list
**list
,
294 struct basic_block
*old
, struct basic_block
*new, int count
)
296 replace_ptr_list_entry((struct ptr_list
**)list
, old
, new, count
);
301 struct symbol_list
*syms
;
302 struct pseudo_list
*accesses
;
303 struct basic_block_list
*bbs
;
304 struct basic_block
*active
;
305 struct instruction
*entry
;
306 unsigned int dom_levels
; /* max levels in the dom tree */
309 extern void insert_select(struct basic_block
*bb
, struct instruction
*br
, struct instruction
*phi
, pseudo_t if_true
, pseudo_t if_false
);
310 extern void insert_branch(struct basic_block
*bb
, struct instruction
*br
, struct basic_block
*target
);
312 struct instruction
*alloc_phisrc(pseudo_t pseudo
, struct symbol
*type
);
313 struct instruction
*alloc_phi_node(struct basic_block
*bb
, struct symbol
*type
, struct ident
*ident
);
314 struct instruction
*insert_phi_node(struct basic_block
*bb
, struct symbol
*var
);
315 void add_phi_node(struct basic_block
*bb
, struct instruction
*phi_node
);
317 pseudo_t
alloc_phi(struct basic_block
*source
, pseudo_t pseudo
, struct symbol
*type
);
318 pseudo_t
alloc_pseudo(struct instruction
*def
);
319 pseudo_t
value_pseudo(long long val
);
320 pseudo_t
undef_pseudo(void);
322 struct entrypoint
*linearize_symbol(struct symbol
*sym
);
323 int unssa(struct entrypoint
*ep
);
324 void show_entry(struct entrypoint
*ep
);
325 const char *show_pseudo(pseudo_t pseudo
);
326 void show_bb(struct basic_block
*bb
);
327 const char *show_instruction(struct instruction
*insn
);
328 const char *show_label(struct basic_block
*bb
);
330 #endif /* LINEARIZE_H */