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
;
126 struct /* compare */ {
127 pseudo_t _src1
, _src2
; // alias .src[12]
128 struct symbol
*itype
; // input operands' type
134 struct /* setval */ {
135 struct expression
*val
;
137 struct /* setfval */ {
142 struct pseudo_list
*arguments
;
143 struct symbol_list
*fntypes
;
145 struct /* context */ {
148 struct expression
*context_expr
;
152 struct asm_rules
*asm_rules
;
157 struct basic_block_list
;
158 struct instruction_list
;
162 unsigned long generation
;
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 unsigned int nr
; /* unique id for label's names */
169 int dom_level
; /* level in the dominance tree */
170 struct basic_block_list
*doms
; /* list of BB idominated by this one */
171 struct pseudo_list
*needs
, *defines
;
173 struct phi_map
*phi_map
;/* needed during SSA conversion */
174 int postorder_nr
; /* postorder number */
175 int context
; /* needed during context checking */
182 // return the opcode of the instruction defining ``SRC`` if existing
183 // and OP_BADOP if not. It also assigns the defining instruction
185 #define DEF_OPCODE(DEF, SRC) \
186 (((SRC)->type == PSEUDO_REG && (DEF = (SRC)->def)) ? DEF->opcode : OP_BADOP)
189 static inline void add_bb(struct basic_block_list
**list
, struct basic_block
*bb
)
191 add_ptr_list(list
, bb
);
194 static inline void add_instruction(struct instruction_list
**list
, struct instruction
*insn
)
196 add_ptr_list(list
, insn
);
199 static inline void add_multijmp(struct multijmp_list
**list
, struct multijmp
*multijmp
)
201 add_ptr_list(list
, multijmp
);
204 static inline pseudo_t
*add_pseudo(struct pseudo_list
**list
, pseudo_t pseudo
)
206 return add_ptr_list(list
, pseudo
);
209 static inline int remove_pseudo(struct pseudo_list
**list
, pseudo_t pseudo
)
211 return delete_ptr_list_entry((struct ptr_list
**)list
, pseudo
, 0) != 0;
214 static inline int pseudo_in_list(struct pseudo_list
*list
, pseudo_t pseudo
)
216 return lookup_ptr_list_entry((struct ptr_list
*)list
, pseudo
);
219 static inline int bb_terminated(struct basic_block
*bb
)
221 struct instruction
*insn
;
224 insn
= last_instruction(bb
->insns
);
225 return insn
&& insn
->opcode
>= OP_TERMINATOR
226 && insn
->opcode
<= OP_TERMINATOR_END
;
229 static inline int bb_reachable(struct basic_block
*bb
)
234 static inline int lookup_bb(struct basic_block_list
*list
, struct basic_block
*bb
)
236 return lookup_ptr_list_entry((struct ptr_list
*)list
, bb
);
240 static inline void add_pseudo_user_ptr(struct pseudo_user
*user
, struct pseudo_user_list
**list
)
242 add_ptr_list(list
, user
);
245 static inline int has_use_list(pseudo_t p
)
247 return (p
&& p
->type
!= PSEUDO_VOID
&& p
->type
!= PSEUDO_UNDEF
&& p
->type
!= PSEUDO_VAL
);
250 static inline bool has_definition(pseudo_t p
)
252 return p
->type
== PSEUDO_REG
|| p
->type
== PSEUDO_PHI
;
255 static inline int pseudo_user_list_size(struct pseudo_user_list
*list
)
257 return ptr_list_size((struct ptr_list
*)list
);
260 static inline bool pseudo_user_list_empty(struct pseudo_user_list
*list
)
262 return ptr_list_empty((struct ptr_list
*)list
);
265 static inline int has_users(pseudo_t p
)
267 return !pseudo_user_list_empty(p
->users
);
270 static inline bool one_use(pseudo_t p
)
272 return !ptr_list_multiple((struct ptr_list
*)(p
->users
));
275 static inline int nbr_users(pseudo_t p
)
277 return pseudo_user_list_size(p
->users
);
280 static inline struct pseudo_user
*alloc_pseudo_user(struct instruction
*insn
, pseudo_t
*pp
)
282 struct pseudo_user
*user
= __alloc_pseudo_user(0);
288 static inline void use_pseudo(struct instruction
*insn
, pseudo_t p
, pseudo_t
*pp
)
292 add_pseudo_user_ptr(alloc_pseudo_user(insn
, pp
), &p
->users
);
295 static inline void remove_bb_from_list(struct basic_block_list
**list
, struct basic_block
*entry
, int count
)
297 delete_ptr_list_entry((struct ptr_list
**)list
, entry
, count
);
300 static inline void replace_bb_in_list(struct basic_block_list
**list
,
301 struct basic_block
*old
, struct basic_block
*new, int count
)
303 replace_ptr_list_entry((struct ptr_list
**)list
, old
, new, count
);
308 struct symbol_list
*syms
;
309 struct pseudo_list
*accesses
;
310 struct basic_block_list
*bbs
;
311 struct basic_block
*active
;
312 struct instruction
*entry
;
313 unsigned int dom_levels
; /* max levels in the dom tree */
316 extern void insert_select(struct basic_block
*bb
, struct instruction
*br
, struct instruction
*phi
, pseudo_t if_true
, pseudo_t if_false
);
317 extern void insert_branch(struct basic_block
*bb
, struct instruction
*br
, struct basic_block
*target
);
319 struct instruction
*alloc_phisrc(pseudo_t pseudo
, struct symbol
*type
);
320 struct instruction
*alloc_phi_node(struct basic_block
*bb
, struct symbol
*type
, struct ident
*ident
);
321 struct instruction
*insert_phi_node(struct basic_block
*bb
, struct symbol
*var
);
322 void add_phi_node(struct basic_block
*bb
, struct instruction
*phi_node
);
324 pseudo_t
alloc_phi(struct basic_block
*source
, pseudo_t pseudo
, struct symbol
*type
);
325 pseudo_t
alloc_pseudo(struct instruction
*def
);
326 pseudo_t
value_pseudo(long long val
);
327 pseudo_t
undef_pseudo(void);
329 struct entrypoint
*linearize_symbol(struct symbol
*sym
);
330 int unssa(struct entrypoint
*ep
);
331 void show_entry(struct entrypoint
*ep
);
332 void show_insn_entry(struct instruction
*insn
);
333 const char *show_pseudo(pseudo_t pseudo
);
334 void show_bb(struct basic_block
*bb
);
335 void show_insn_bb(struct instruction
*insn
);
336 const char *show_instruction(struct instruction
*insn
);
337 const char *show_label(struct basic_block
*bb
);
339 #endif /* LINEARIZE_H */